Suppress underscore warning for cgo functions

This change suppresses the warning for functions which are:
1. exported to C via a cgo "//export" comment, and
2. not exported in the Go package.

That allows functions exported to C to use idiomatic C names, but
still requires that they not pollute the exported Go API.

Fixes #144
diff --git a/lint.go b/lint.go
index 22c60c4..a13129c 100644
--- a/lint.go
+++ b/lint.go
@@ -544,6 +544,7 @@
 		if id.Name == should {
 			return
 		}
+
 		if len(id.Name) > 2 && strings.Contains(id.Name[1:], "_") {
 			f.errorf(id, 0.9, link("http://golang.org/doc/effective_go.html#mixed-caps"), category("naming"), "don't use underscores in Go names; %s %s should be %s", thing, id.Name, should)
 			return
@@ -581,7 +582,12 @@
 				thing = "method"
 			}
 
-			check(v.Name, thing)
+			// Exclude naming warnings for functions that are exported to C but
+			// not exported in the Go API.
+			// See https://github.com/golang/lint/issues/144.
+			if ast.IsExported(v.Name.Name) || !isCgoExported(v) {
+				check(v.Name, thing)
+			}
 
 			checkList(v.Type.Params, thing+" parameter")
 			checkList(v.Type.Results, thing+" result")
@@ -1508,6 +1514,20 @@
 	return ok && lit.Kind == token.INT && lit.Value == "1"
 }
 
+func isCgoExported(f *ast.FuncDecl) bool {
+	if f.Recv != nil || f.Doc == nil {
+		return false
+	}
+
+	cgoExport := regexp.MustCompile(fmt.Sprintf("(?m)^//export %s$", regexp.QuoteMeta(f.Name.Name)))
+	for _, c := range f.Doc.List {
+		if cgoExport.MatchString(c.Text) {
+			return true
+		}
+	}
+	return false
+}
+
 var basicTypeKinds = map[types.BasicKind]string{
 	types.UntypedBool:    "bool",
 	types.UntypedInt:     "int",
diff --git a/testdata/names.go b/testdata/names.go
index f884fab..0ec1520 100644
--- a/testdata/names.go
+++ b/testdata/names.go
@@ -10,6 +10,8 @@
 	"net/url"
 )
 
+import "C"
+
 var var_name int // MATCH /underscore.*var.*var_name/
 
 type t_wow struct { // MATCH /underscore.*type.*t_wow/
@@ -89,3 +91,26 @@
 type t struct{}
 
 func (t) LastInsertId() (int64, error) { return 0, nil } // okay because it matches a known style violation
+
+//export exported_to_c
+func exported_to_c() {} // okay: https://github.com/golang/lint/issues/144
+
+//export exported_to_c_with_arg
+func exported_to_c_with_arg(but_use_go_param_names int) // MATCH /underscore.*func parameter.*but_use_go_param_names/
+
+// This is an exported C function with a leading doc comment.
+//
+//export exported_to_c_with_comment
+func exported_to_c_with_comment() {} // okay: https://github.com/golang/lint/issues/144
+
+//export maybe_exported_to_CPlusPlusWithCamelCase
+func maybe_exported_to_CPlusPlusWithCamelCase() {} // okay: https://github.com/golang/lint/issues/144
+
+// WhyAreYouUsingCapitalLetters_InACFunctionName is a Go-exported function that
+// is also exported to C as a name with underscores.
+//
+// Don't do that. If you want to use a C-style name for a C export, make it
+// lower-case and leave it out of the Go-exported API.
+//
+//export WhyAreYouUsingCapitalLetters_InACFunctionName
+func WhyAreYouUsingCapitalLetters_InACFunctionName() {} // MATCH /underscore.*func.*Why.*CFunctionName/