jiri-swift: Don't put static defines from CGO in exported preamble

This CL restricts what get's copied into the generated header from
CGO exported headers by making sure that static defines and functions
are not exported to Swift.

Regression unit test is added as well as fixes to the existing.

Change-Id: I9878781f327c42090dab8b3f016fdd1ca68e46ac
diff --git a/jiri-swift/build_cgo.go b/jiri-swift/build_cgo.go
index 38deec3..7056de0 100644
--- a/jiri-swift/build_cgo.go
+++ b/jiri-swift/build_cgo.go
@@ -77,11 +77,11 @@
 	var destLibPath string
 	switch flagBuildMode {
 	case buildModeArchive:
-		a := fmt.Sprintf("v23_%v.a", targetArch)
+		a := fmt.Sprintf("%v_%v.a", libraryBinaryName, targetArch)
 		destLibPath = path.Join(swiftTargetDir, a)
 		sh.Cmd("mv", "main.a", destLibPath).Run()
 	case buildModeShared:
-		dylib := fmt.Sprintf("v23_%v.dylib", targetArch)
+		dylib := fmt.Sprintf("%v_%v.dylib", libraryBinaryName, targetArch)
 		destLibPath = path.Join(swiftTargetDir, dylib)
 		sh.Cmd("mv", "main", dylib).Run()
 		sh.Cmd("install_name_tool", "-id", "@loader_path/"+dylib, dylib).Run()
diff --git a/jiri-swift/build_test.go b/jiri-swift/build_test.go
index af10657..6138219 100644
--- a/jiri-swift/build_test.go
+++ b/jiri-swift/build_test.go
@@ -250,7 +250,7 @@
 }
 
 func cgoBinaryPath(jirix *jiri.X, arch string, buildMode string) (string, error) {
-	binaryPath := path.Join(getSwiftTargetDir(jirix), fmt.Sprintf("%v_%v", frameworkBinaryName, arch))
+	binaryPath := path.Join(getSwiftTargetDir(jirix), fmt.Sprintf("%v_%v", libraryBinaryName, arch))
 	switch buildMode {
 	case buildModeArchive:
 		binaryPath = binaryPath + ".a"
@@ -327,6 +327,18 @@
 	if strings.Count(cgoExports, "_check_for_64_bit_pointer_matching_GoInt") != 1 {
 		return fmt.Errorf("64-bit check should only occur once %v", cgoExportsPath)
 	}
+	s, e := strings.Index(cgoExports, "/* Start of preamble"), strings.Index(cgoExports, "/* End of preamble")
+	if s == -1 || e == -1 {
+		return fmt.Errorf("Missing preamble section")
+	}
+	for _, line := range strings.Split(cgoExports[s:e], "\n") {
+		switch {
+		case strings.TrimSpace(line) == "":
+			continue
+		case strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t"):
+			return fmt.Errorf("Looks like indented code in preamble")
+		}
+	}
 	return nil
 }
 
diff --git a/jiri-swift/cgo_header.go b/jiri-swift/cgo_header.go
index ebfa7a1..185d492 100644
--- a/jiri-swift/cgo_header.go
+++ b/jiri-swift/cgo_header.go
@@ -27,6 +27,7 @@
 const (
 	stateBase                 = "base"
 	stateInPreamble           = "inPreamble"
+	stateInPreambleDef        = "inPreambleDef"
 	stateInPrologue           = "inPrologue"
 	stateInPrologueIntSection = "inPrologueIntSection"
 	stateInCppGuardStart      = "inCppGuardStart"
@@ -68,6 +69,7 @@
 	handlers := map[string]func(string, *cgoHeader) (string, error){
 		stateBase:                 parseBase,
 		stateInPreamble:           parseInPreamble,
+		stateInPreambleDef:        parseInPreambleDef,
 		stateInPrologue:           parseInPrologue,
 		stateInPrologueIntSection: parseInPrologueIntSection,
 		stateInCppGuardStart:      parseInCppGuardStart,
@@ -114,12 +116,22 @@
 	case strings.Contains(line, "End of preamble"):
 		//	/* End of preamble from import "C" comments.  */
 		nextState = stateBase
+	case strings.HasSuffix(line, "{"):
+		// static int objcBOOL2int(BOOL b) {
+		nextState = stateInPreambleDef
 	case strings.HasPrefix(line, "#line"):
 		// #line 19 "/Users/zinman/vanadium/release/go/src/v.io/x/swift/impl/google/rt/swift.go"
 		// ignore
-	case strings.HasPrefix(line, "#import"):
+	case strings.HasPrefix(line, "#import") && strings.Contains(line, "types.h"):
 		// #import "../../../types.h"
 		// ignore
+	case strings.HasPrefix(line, "#import"):
+		// #import <CoreBluetooth/CoreBluetooth.h>
+		// #import "CBDriver.h"
+		hdr.sysIncludes = append(hdr.sysIncludes, line)
+	case strings.HasPrefix(line, "static") && strings.HasSuffix(line, ";"):
+		// static const size_t sizeofSwiftByteArray = sizeof(SwiftByteArray);
+		// ignore
 	case strings.HasPrefix(line, "#include"):
 		// #include <string.h> // memcpy
 		hdr.sysIncludes = append(hdr.sysIncludes, line)
@@ -127,12 +139,22 @@
 		// // These sizes (including C struct memory alignment/padding) isn't available from Go, so we make that available via CGo.
 		// ignore
 	default:
-		// static const size_t sizeofSwiftByteArray = sizeof(SwiftByteArray);
+		// const size_t sizeofSwiftByteArray = sizeof(SwiftByteArray);
 		hdr.typedefs = append(hdr.typedefs, line)
 	}
 	return nextState, nil
 }
 
+func parseInPreambleDef(line string, hdr *cgoHeader) (nextState string, err error) {
+	nextState = stateInPreambleDef // Default is same state.
+	switch {
+	case line == "}":
+		// }
+		nextState = stateInPreamble
+	}
+	return nextState, nil
+}
+
 func parseInPrologue(line string, hdr *cgoHeader) (nextState string, err error) {
 	nextState = stateInPrologue // Default is same state.
 	switch {
@@ -173,7 +195,6 @@
 		nextState = stateInExports
 	}
 	return nextState, nil
-
 }
 
 func parseInExports(line string, hdr *cgoHeader) (nextState string, err error) {
@@ -185,7 +206,6 @@
 		hdr.exportedFunctions = append(hdr.exportedFunctions, line)
 	}
 	return nextState, nil
-
 }
 
 func parseInCppGuardEnd(line string, hdr *cgoHeader) (nextState string, err error) {
@@ -209,7 +229,6 @@
 	includes := hdrs.dedupedStrings(func(hdr *cgoHeader) []string {
 		return hdr.sysIncludes
 	})
-	sort.Strings(includes)
 	return includes
 }
 
diff --git a/jiri-swift/swift.go b/jiri-swift/swift.go
index 4f26e52..b063076 100644
--- a/jiri-swift/swift.go
+++ b/jiri-swift/swift.go
@@ -46,6 +46,7 @@
 
 	frameworkName       = "VanadiumCore.framework"
 	frameworkBinaryName = "VanadiumCore"
+	libraryBinaryName   = "v23"
 
 	stageBuildCgo       = "cgo"
 	stageBuildFramework = "framework"