// Parses the given line as a gcc line marker and returns the contained // filename. func parseLineMarker(line string) string { // A line marker contains the line number and filename and looks like: // # 123 /path/to/file.cpp // It can be followed by zero or more flag number that indicate the // preprocessor state and can be ignored. // For exact details on this format, see: // https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/gcc/c-family/c-ppoutput.c#L413-L415 split := strings.SplitN(line, " ", 3) if len(split) < 2 || split[0] != "#" { return "" } _, err := strconv.Atoi(split[1]) if err != nil { return "" } // If we get here, we found a # followed by a line number, so // assume this is a line marker and see if the rest of the line // starts with a string containing the filename str, rest, ok := utils.ParseCppString(split[2]) if ok && (rest == "" || rest[0] == ' ') { return str } return "" }
func TestParseCppString(t *testing.T) { str, rest, ok := utils.ParseCppString(`foo`) require.Equal(t, false, ok) str, rest, ok = utils.ParseCppString(`"foo`) require.Equal(t, false, ok) str, rest, ok = utils.ParseCppString(`"foo"`) require.Equal(t, true, ok) require.Equal(t, `foo`, str) require.Equal(t, ``, rest) str, rest, ok = utils.ParseCppString(`"foo\\bar"`) require.Equal(t, true, ok) require.Equal(t, `foo\bar`, str) require.Equal(t, ``, rest) str, rest, ok = utils.ParseCppString(`"foo \"is\" quoted and \\\\bar\"\" escaped\\" and "then" some`) require.Equal(t, true, ok) require.Equal(t, `foo "is" quoted and \\bar"" escaped\`, str) require.Equal(t, ` and "then" some`, rest) str, rest, ok = utils.ParseCppString(`" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"`) require.Equal(t, true, ok) require.Equal(t, ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`, str) require.Equal(t, ``, rest) str, rest, ok = utils.ParseCppString(`"/home/ççç/"`) require.Equal(t, true, ok) require.Equal(t, `/home/ççç/`, str) require.Equal(t, ``, rest) str, rest, ok = utils.ParseCppString(`"/home/ççç/ /$sdsdd\\"`) require.Equal(t, true, ok) require.Equal(t, `/home/ççç/ /$sdsdd\`, str) require.Equal(t, ``, rest) }