Created
January 26, 2018 23:47
-
-
Save josharian/54b2268af5792ff0e62f06437f28a8c9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"flag" | |
"fmt" | |
"os" | |
"strings" | |
"github.com/go-clang/v3.9/clang" | |
) | |
var fname = flag.String("fname", "", "the file to analyze") | |
func main() { | |
flag.Parse() | |
if *fname == "" { | |
flag.Usage() | |
fmt.Printf("please provide a file name to analyze\n") | |
os.Exit(1) | |
} | |
idx := clang.NewIndex(0, 1) | |
defer idx.Dispose() | |
tu := idx.ParseTranslationUnit(*fname, []string{"-DDOCURIUM=1"}, nil, 0) | |
defer tu.Dispose() | |
diagnostics := tu.Diagnostics() | |
for _, d := range diagnostics { | |
fmt.Println("PROBLEM:", d.Spelling()) | |
} | |
if len(diagnostics) > 0 { | |
os.Exit(1) | |
} | |
cursor := tu.TranslationUnitCursor() | |
var enums []string | |
var comments [][]string | |
cursor.Visit(func(cursor, parent clang.Cursor) clang.ChildVisitResult { | |
if cursor.IsNull() { | |
return clang.ChildVisit_Continue | |
} | |
file, _, _, _ := cursor.Location().FileLocation() | |
if file.Name() != *fname { | |
return clang.ChildVisit_Continue | |
} | |
switch cursor.Kind() { | |
case clang.Cursor_EnumDecl: | |
cursor.Visit(func(innercursor, innerparent clang.Cursor) clang.ChildVisitResult { | |
if innercursor.Kind() != clang.Cursor_EnumConstantDecl { | |
return clang.ChildVisit_Continue | |
} | |
enums = append(enums, innercursor.Spelling()) | |
pc := innercursor.ParsedComment() | |
var lines []string | |
for i := uint32(0); i < pc.NumChildren(); i++ { | |
c := pc.Child(i) | |
if c.Kind() != clang.Comment_Paragraph { | |
panic("unexpected comment kind") | |
} | |
for j := uint32(0); j < c.NumChildren(); j++ { | |
line := c.Child(j) | |
if line.Kind() != clang.Comment_Text { | |
panic(fmt.Sprintf("unexpected inner comment kind %v", line.Kind().Spelling())) | |
} | |
lines = append(lines, line.TextComment_getText()) | |
} | |
lines = append(lines, "\n") | |
} | |
if len(lines) > 0 && lines[len(lines)-1] == "\n" { | |
lines = lines[:len(lines)-1] | |
} | |
comments = append(comments, lines) | |
return clang.ChildVisit_Recurse | |
}) | |
case clang.Cursor_TypedefDecl: | |
if len(enums) > 0 { | |
ctyp := cursor.Spelling() | |
special, isspecial := ctype2go[ctyp] // handle exceptions | |
var typ string | |
if isspecial { | |
typ = special.gotype | |
} else { | |
typ = ctyp | |
typ = strings.TrimPrefix(typ, "git_") | |
typ = strings.TrimSuffix(typ, "_t") | |
typ = toCamel(typ) | |
} | |
fmt.Printf("type %s int\n\n", typ) | |
fmt.Printf("const (\n") | |
for i := range enums { | |
for _, line := range comments[i] { | |
fmt.Printf("\t//%s\n", line) | |
} | |
enum := toCamel(strings.TrimPrefix(enums[i], "GIT_")) | |
if isspecial { | |
enum = special.addPrefix + strings.TrimPrefix(enum, special.stripPrefix) | |
} | |
fmt.Printf("\t%s %s = C.%s\n", enum, typ, enums[i]) | |
if i != len(enums)-1 { | |
fmt.Println() | |
} | |
} | |
fmt.Printf(")\n\n\n") | |
} | |
enums = nil | |
comments = nil | |
} | |
return clang.ChildVisit_Continue | |
}) | |
if len(diagnostics) > 0 { | |
fmt.Println("NOTE: There were problems while analyzing the given file") | |
os.Exit(1) | |
} | |
} | |
var ctype2go = map[string]struct { | |
gotype string | |
stripPrefix string | |
addPrefix string | |
}{ | |
"git_merge_flag_t": {"MergeTreeFlag", "Merge", "MergeTree"}, | |
} | |
var caseCleanup = strings.NewReplacer("Fastforward", "FastForward") | |
func toCamel(s string) string { | |
words := strings.Split(s, "_") | |
var camel [][]byte | |
for _, word := range words { | |
if len(word) == 0 { | |
camel = append(camel, []byte("")) | |
} | |
w := []byte(word) | |
w = bytes.ToLower(w) | |
w[0] = bytes.ToUpper(w[:1])[0] | |
camel = append(camel, w) | |
} | |
s = string(bytes.Join(camel, nil)) | |
return caseCleanup.Replace(s) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ go run gen_git2go_enum.go -fname vendor/libgit2/include/git2/merge.h | |
type MergeTreeFlag int | |
const ( | |
// Detect renames that occur between the common ancestor and the "ours" | |
// side or the common ancestor and the "theirs" side. This will enable | |
// the ability to merge between a modified and renamed file. | |
MergeTreeFindRenames MergeTreeFlag = C.GIT_MERGE_FIND_RENAMES | |
// If a conflict occurs, exit immediately instead of attempting to | |
// continue resolving conflicts. The merge operation will fail with | |
// GIT_EMERGECONFLICT and no index will be returned. | |
MergeTreeFailOnConflict MergeTreeFlag = C.GIT_MERGE_FAIL_ON_CONFLICT | |
// Do not write the REUC extension on the generated index | |
MergeTreeSkipReuc MergeTreeFlag = C.GIT_MERGE_SKIP_REUC | |
// If the commits being merged have multiple merge bases, do not build | |
// a recursive merge base (by merging the multiple merge bases), | |
// instead simply use the first base. This flag provides a similar | |
// merge base to `git-merge-resolve`. | |
MergeTreeNoRecursive MergeTreeFlag = C.GIT_MERGE_NO_RECURSIVE | |
) | |
type MergeFileFavor int | |
const ( | |
// When a region of a file is changed in both branches, a conflict | |
// will be recorded in the index so that `git_checkout` can produce | |
// a merge file with conflict markers in the working directory. | |
// This is the default. | |
MergeFileFavorNormal MergeFileFavor = C.GIT_MERGE_FILE_FAVOR_NORMAL | |
// When a region of a file is changed in both branches, the file | |
// created in the index will contain the "ours" side of any conflicting | |
// region. The index will not record a conflict. | |
MergeFileFavorOurs MergeFileFavor = C.GIT_MERGE_FILE_FAVOR_OURS | |
// When a region of a file is changed in both branches, the file | |
// created in the index will contain the "theirs" side of any conflicting | |
// region. The index will not record a conflict. | |
MergeFileFavorTheirs MergeFileFavor = C.GIT_MERGE_FILE_FAVOR_THEIRS | |
// When a region of a file is changed in both branches, the file | |
// created in the index will contain each unique line from each side, | |
// which has the result of combining both files. The index will not | |
// record a conflict. | |
MergeFileFavorUnion MergeFileFavor = C.GIT_MERGE_FILE_FAVOR_UNION | |
) | |
type MergeFileFlag int | |
const ( | |
// Defaults | |
MergeFileDefault MergeFileFlag = C.GIT_MERGE_FILE_DEFAULT | |
// Create standard conflicted merge files | |
MergeFileStyleMerge MergeFileFlag = C.GIT_MERGE_FILE_STYLE_MERGE | |
// Create diff3-style files | |
MergeFileStyleDiff3 MergeFileFlag = C.GIT_MERGE_FILE_STYLE_DIFF3 | |
// Condense non-alphanumeric regions for simplified diff file | |
MergeFileSimplifyAlnum MergeFileFlag = C.GIT_MERGE_FILE_SIMPLIFY_ALNUM | |
// Ignore all whitespace | |
MergeFileIgnoreWhitespace MergeFileFlag = C.GIT_MERGE_FILE_IGNORE_WHITESPACE | |
// Ignore changes in amount of whitespace | |
MergeFileIgnoreWhitespaceChange MergeFileFlag = C.GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE | |
// Ignore whitespace at end of line | |
MergeFileIgnoreWhitespaceEol MergeFileFlag = C.GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL | |
// Use the "patience diff" algorithm | |
MergeFileDiffPatience MergeFileFlag = C.GIT_MERGE_FILE_DIFF_PATIENCE | |
// Take extra time to find minimal diff | |
MergeFileDiffMinimal MergeFileFlag = C.GIT_MERGE_FILE_DIFF_MINIMAL | |
) | |
type MergeAnalysis int | |
const ( | |
// No merge is possible. (Unused.) | |
MergeAnalysisNone MergeAnalysis = C.GIT_MERGE_ANALYSIS_NONE | |
// A "normal" merge; both HEAD and the given merge input have diverged | |
// from their common ancestor. The divergent commits must be merged. | |
MergeAnalysisNormal MergeAnalysis = C.GIT_MERGE_ANALYSIS_NORMAL | |
// All given merge inputs are reachable from HEAD, meaning the | |
// repository is up-to-date and no merge needs to be performed. | |
MergeAnalysisUpToDate MergeAnalysis = C.GIT_MERGE_ANALYSIS_UP_TO_DATE | |
// The given merge input is a fast-forward from HEAD and no merge | |
// needs to be performed. Instead, the client can check out the | |
// given merge input. | |
MergeAnalysisFastForward MergeAnalysis = C.GIT_MERGE_ANALYSIS_FASTFORWARD | |
// The HEAD of the current repository is "unborn" and does not point to | |
// a valid commit. No merge can be performed, but the caller may wish | |
// to simply set HEAD to the target commit(s). | |
MergeAnalysisUnborn MergeAnalysis = C.GIT_MERGE_ANALYSIS_UNBORN | |
) | |
type MergePreference int | |
const ( | |
// No configuration was found that suggests a preferred behavior for | |
// merge. | |
MergePreferenceNone MergePreference = C.GIT_MERGE_PREFERENCE_NONE | |
// There is a `merge.ff=false` configuration setting, suggesting that | |
// the user does not want to allow a fast-forward merge. | |
MergePreferenceNoFastForward MergePreference = C.GIT_MERGE_PREFERENCE_NO_FASTFORWARD | |
// There is a `merge.ff=only` configuration setting, suggesting that | |
// the user only wants fast-forward merges. | |
MergePreferenceFastForwardOnly MergePreference = C.GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment