diff --git a/src/arduino.cc/builder/ctags/ctags_parser.go b/src/arduino.cc/builder/ctags/ctags_parser.go index c630400d..f827ed79 100644 --- a/src/arduino.cc/builder/ctags/ctags_parser.go +++ b/src/arduino.cc/builder/ctags/ctags_parser.go @@ -53,13 +53,16 @@ var KNOWN_TAG_KINDS = map[string]bool{ } type CTagsParser struct { - tags []*types.CTag + tags []*types.CTag + mainFile string } -func (p *CTagsParser) Parse(ctagsOutput string) []*types.CTag { +func (p *CTagsParser) Parse(ctagsOutput string, mainFile string) []*types.CTag { rows := strings.Split(ctagsOutput, "\n") rows = removeEmpty(rows) + p.mainFile = mainFile + for _, row := range rows { p.tags = append(p.tags, parseTag(row)) } diff --git a/src/arduino.cc/builder/ctags/ctags_parser_test.go b/src/arduino.cc/builder/ctags/ctags_parser_test.go index d6390562..4bf9a510 100644 --- a/src/arduino.cc/builder/ctags/ctags_parser_test.go +++ b/src/arduino.cc/builder/ctags/ctags_parser_test.go @@ -44,7 +44,7 @@ func produceTags(t *testing.T, filename string) []*types.CTag { require.NoError(t, err) parser := CTagsParser{} - return parser.Parse(string(bytes)) + return parser.Parse(string(bytes), "") } func TestCTagsParserShouldListPrototypes(t *testing.T) { diff --git a/src/arduino.cc/builder/ctags/ctags_to_prototypes.go b/src/arduino.cc/builder/ctags/ctags_to_prototypes.go index 459174d8..556cab3f 100644 --- a/src/arduino.cc/builder/ctags/ctags_to_prototypes.go +++ b/src/arduino.cc/builder/ctags/ctags_to_prototypes.go @@ -48,10 +48,12 @@ func (p *CTagsParser) findLineWhereToInsertPrototypes() int { } else { return firstFunctionPointerAsArgument } - } else if firstFunctionLine == -1 { + } else if firstFunctionLine != -1 { + return firstFunctionLine + } else if firstFunctionPointerAsArgument != -1 { return firstFunctionPointerAsArgument } else { - return firstFunctionLine + return 0 } } @@ -86,7 +88,7 @@ func (p *CTagsParser) collectFunctionNames() []string { func (p *CTagsParser) firstFunctionAtLine() int { for _, tag := range p.tags { - if !tagIsUnknown(tag) && isHandled(tag) && tag.Kind == KIND_FUNCTION { + if !tagIsUnknown(tag) && isHandled(tag) && tag.Kind == KIND_FUNCTION && tag.Filename == p.mainFile { return tag.Line } } diff --git a/src/arduino.cc/builder/ctags/ctags_to_prototypes_test.go b/src/arduino.cc/builder/ctags/ctags_to_prototypes_test.go index 27db5820..5a80dd02 100644 --- a/src/arduino.cc/builder/ctags/ctags_to_prototypes_test.go +++ b/src/arduino.cc/builder/ctags/ctags_to_prototypes_test.go @@ -38,17 +38,17 @@ import ( "github.com/stretchr/testify/require" ) -func producePrototypes(t *testing.T, filename string) ([]*types.Prototype, int) { +func producePrototypes(t *testing.T, filename string, mainFile string) ([]*types.Prototype, int) { bytes, err := ioutil.ReadFile(filepath.Join("test_data", filename)) require.NoError(t, err) parser := &CTagsParser{} - parser.Parse(string(bytes)) + parser.Parse(string(bytes), mainFile) return parser.GeneratePrototypes() } func TestCTagsToPrototypesShouldListPrototypes(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldListPrototypes.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldListPrototypes.txt", "/tmp/sketch7210316334309249705.cpp") require.Equal(t, 5, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "/tmp/sketch7210316334309249705.cpp", prototypes[0].File) @@ -61,7 +61,7 @@ func TestCTagsToPrototypesShouldListPrototypes(t *testing.T) { } func TestCTagsToPrototypesShouldListTemplates(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldListTemplates.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldListTemplates.txt", "/tmp/sketch8398023134925534708.cpp") require.Equal(t, 3, len(prototypes)) require.Equal(t, "template T minimum (T a, T b);", prototypes[0].Prototype) @@ -73,7 +73,7 @@ func TestCTagsToPrototypesShouldListTemplates(t *testing.T) { } func TestCTagsToPrototypesShouldListTemplates2(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldListTemplates2.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldListTemplates2.txt", "/tmp/sketch463160524247569568.cpp") require.Equal(t, 4, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -86,7 +86,7 @@ func TestCTagsToPrototypesShouldListTemplates2(t *testing.T) { } func TestCTagsToPrototypesShouldDealWithClasses(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithClasses.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithClasses.txt", "/tmp/sketch9043227824785312266.cpp") require.Equal(t, 0, len(prototypes)) @@ -94,7 +94,7 @@ func TestCTagsToPrototypesShouldDealWithClasses(t *testing.T) { } func TestCTagsToPrototypesShouldDealWithStructs(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithStructs.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithStructs.txt", "/tmp/sketch8930345717354294915.cpp") require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -106,7 +106,7 @@ func TestCTagsToPrototypesShouldDealWithStructs(t *testing.T) { } func TestCTagsToPrototypesShouldDealWithMacros(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithMacros.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealWithMacros.txt", "/tmp/sketch5976699731718729500.cpp") require.Equal(t, 5, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -120,7 +120,7 @@ func TestCTagsToPrototypesShouldDealWithMacros(t *testing.T) { } func TestCTagsToPrototypesShouldDealFunctionWithDifferentSignatures(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserShouldDealFunctionWithDifferentSignatures.txt", "/tmp/test260613593/preproc/ctags_target.cpp") require.Equal(t, 1, len(prototypes)) require.Equal(t, "boolean getBytes( byte addr, int amount );", prototypes[0].Prototype) @@ -130,7 +130,7 @@ func TestCTagsToPrototypesShouldDealFunctionWithDifferentSignatures(t *testing.T } func TestCTagsToPrototypesClassMembersAreFilteredOut(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserClassMembersAreFilteredOut.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserClassMembersAreFilteredOut.txt", "/tmp/test834438754/preproc/ctags_target.cpp") require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -141,7 +141,7 @@ func TestCTagsToPrototypesClassMembersAreFilteredOut(t *testing.T) { } func TestCTagsToPrototypesStructWithFunctions(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserStructWithFunctions.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserStructWithFunctions.txt", "/tmp/build7315640391316178285.tmp/preproc/ctags_target.cpp") require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -152,7 +152,7 @@ func TestCTagsToPrototypesStructWithFunctions(t *testing.T) { } func TestCTagsToPrototypesDefaultArguments(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserDefaultArguments.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserDefaultArguments.txt", "/tmp/test179252494/preproc/ctags_target.cpp") require.Equal(t, 3, len(prototypes)) require.Equal(t, "void test(int x = 1);", prototypes[0].Prototype) @@ -164,7 +164,7 @@ func TestCTagsToPrototypesDefaultArguments(t *testing.T) { } func TestCTagsToPrototypesNamespace(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserNamespace.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserNamespace.txt", "/tmp/test030883150/preproc/ctags_target.cpp") require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -175,7 +175,7 @@ func TestCTagsToPrototypesNamespace(t *testing.T) { } func TestCTagsToPrototypesStatic(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserStatic.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserStatic.txt", "/tmp/test542833488/preproc/ctags_target.cpp") require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) @@ -188,7 +188,7 @@ func TestCTagsToPrototypesStatic(t *testing.T) { } func TestCTagsToPrototypesFunctionPointer(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserFunctionPointer.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserFunctionPointer.txt", "/tmp/test547238273/preproc/ctags_target.cpp") require.Equal(t, 3, len(prototypes)) require.Equal(t, "void t1Callback();", prototypes[0].Prototype) @@ -200,7 +200,7 @@ func TestCTagsToPrototypesFunctionPointer(t *testing.T) { } func TestCTagsToPrototypesFunctionPointers(t *testing.T) { - prototypes, line := producePrototypes(t, "TestCTagsParserFunctionPointers.txt") + prototypes, line := producePrototypes(t, "TestCTagsParserFunctionPointers.txt", "/tmp/test907446433/preproc/ctags_target.cpp") require.Equal(t, 2, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "/tmp/test907446433/preproc/ctags_target.cpp", prototypes[0].File) @@ -210,10 +210,19 @@ func TestCTagsToPrototypesFunctionPointers(t *testing.T) { } func TestCTagsRunnerSketchWithClassFunction(t *testing.T) { - prototypes, _ := producePrototypes(t, "TestCTagsRunnerSketchWithClassFunction.txt") + prototypes, _ := producePrototypes(t, "TestCTagsRunnerSketchWithClassFunction.txt", "/home/megabug/Workspace/arduino-builder/src/arduino.cc/builder/test/sketch_class_function/sketch_class_function.ino") require.Equal(t, 3, len(prototypes)) require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) require.Equal(t, "void asdf();", prototypes[2].Prototype) } + +func TestCTagsRunnerSketchWithMultiFile(t *testing.T) { + prototypes, line := producePrototypes(t, "TestCTagsRunnerSketchWithMultifile.txt", " /tmp/apUNI8a/apUNI8a.ino") + + require.Equal(t, 0, line) + require.Equal(t, "void A7105_Setup();", prototypes[0].Prototype) + require.Equal(t, "void A7105_Reset();", prototypes[1].Prototype) + require.Equal(t, "int A7105_calibrate_VCB(uint8_t channel);", prototypes[2].Prototype) +} diff --git a/src/arduino.cc/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt b/src/arduino.cc/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt new file mode 100644 index 00000000..626b8ef0 --- /dev/null +++ b/src/arduino.cc/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt @@ -0,0 +1,77 @@ +allowed_ch /tmp/apUNI8a/a7105.ino /^const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82};$/;" kind:variable line:21 +no_allowed_channels /tmp/apUNI8a/a7105.ino /^int no_allowed_channels = 12;$/;" kind:variable line:22 +A7105_Setup /tmp/apUNI8a/a7105.ino /^void A7105_Setup() {$/;" kind:function line:26 signature:() returntype:void +A7105_Reset /tmp/apUNI8a/a7105.ino /^void A7105_Reset()$/;" kind:function line:43 signature:() returntype:void +A7105_calibrate_IF /tmp/apUNI8a/a7105.ino /^int A7105_calibrate_IF() {$/;"kind:function line:52 signature:() returntype:int +A7105_calibrate_VCB /tmp/apUNI8a/a7105.ino /^int A7105_calibrate_VCB(uint8_t channel) {$/;" kind:function line:87 signature:(uint8_t channel) returntype:int +A7105_SetPower /tmp/apUNI8a/a7105.ino /^void A7105_SetPower(int power)$/;" kind:function line:120 signature:(int power) returntype:void +A7105_Strobe /tmp/apUNI8a/a7105.ino /^void A7105_Strobe(enum A7105_State state);$/;" kind:prototype line:176 signature:(enum A7105_State state) returntype:void +A7105_Strobe /tmp/apUNI8a/a7105.ino /^void A7105_Strobe(enum A7105_State state)$/;" kind:function line:179 signature:(enum A7105_State state) returntype:void +A7105_WriteReg /tmp/apUNI8a/a7105.ino /^void A7105_WriteReg(uint8_t address, uint8_t data)$/;" kind:function line:190 signature:(uint8_t address, uint8_t data) returntype:void +A7105_ReadReg /tmp/apUNI8a/a7105.ino /^uint8_t A7105_ReadReg(uint8_t address)$/;" kind:function line:197 signature:(uint8_t address) returntype:uint8_t +A7105_WriteData /tmp/apUNI8a/a7105.ino /^void A7105_WriteData(uint8_t *dpbuffer, uint8_t len, uint8_t channel)$/;" kind:function line:211 signature:(uint8_t *dpbuffer, uint8_t len, uint8_t channel) returntype:void +A7105_ReadData /tmp/apUNI8a/a7105.ino /^void A7105_ReadData(uint8_t *dpbuffer, uint8_t len)$/;" kind:function line:229 signature:(uint8_t *dpbuffer, uint8_t len) returntype:void +A7105_WriteID /tmp/apUNI8a/a7105.ino /^void A7105_WriteID(unsigned long id)$/;" kind:function line:247 signature:(unsigned long id) returntype:void +A7105_ReadID /tmp/apUNI8a/a7105.ino /^void A7105_ReadID()$/;" kind:function line:258 signature:() returntype:void +k13 /tmp/apUNI8a/a7105.ino /^unsigned char k13;$/;" kind:variable line:272 +make_test_packet /tmp/apUNI8a/a7105.ino /^void make_test_packet(uint8_t testpacket[]) {$/;" kind:function line:275 signature:(uint8_t testpacket[]) returntype:void +printpacket /tmp/apUNI8a/a7105.ino /^void printpacket(uint8_t packet[]) {$/;" kind:function line:295 signature:(uint8_t packet[]) returntype:void +A7105_shoutchannel /tmp/apUNI8a/a7105.ino /^void A7105_shoutchannel() {$/;" kind:function line:308 signature:() returntype:void +A7105_oneShout /tmp/apUNI8a/a7105.ino /^int A7105_oneShout() {$/;" kind:function line:337 signature:() returntype:int +A7105_oneShoutRAM /tmp/apUNI8a/a7105.ino /^int A7105_oneShoutRAM(unsigned char xState, unsigned char xType) {$/;" kind:function line:361 signature:(unsigned char xState, unsigned char xType) returntype:int +eavesdrop /tmp/apUNI8a/a7105.ino /^void eavesdrop() {$/;" kind:function line:391 signature:() returntype:void +A7105_findchannel /tmp/apUNI8a/a7105.ino /^uint8_t A7105_findchannel() {$/;" kind:function line:442 signature:() returntype:uint8_t +A7105_sniffchannel /tmp/apUNI8a/a7105.ino /^int A7105_sniffchannel() {$/;"kind:function line:464 signature:() returntype:int +A7105_sniffchannel /tmp/apUNI8a/a7105.ino /^void A7105_sniffchannel(uint8_t _channel) {$/;" kind:function line:484 signature:(uint8_t _channel) returntype:void +A7105_scanchannels /tmp/apUNI8a/a7105.ino /^void A7105_scanchannels(const uint8_t channels[]) {$/;" kind:function line:498 signature:(const uint8_t channels[]) returntype:void +Channels /tmp/apUNI8a/hubsan.ino /^volatile int16_t Channels[12];$/;" kind:variable line:6 +initialize /tmp/apUNI8a/hubsan.ino /^static void initialize() {$/;" kind:function line:8 signature:() returntype:void +hubsan_init /tmp/apUNI8a/hubsan.ino /^int hubsan_init()$/;" kind:function line:22 signature:() returntype:int +update_crc /tmp/apUNI8a/hubsan.ino /^static void update_crc()$/;" kind:function line:80 signature:() returntype:void +recdState /tmp/apUNI8a/main.ino /^unsigned char recdState, recdType;$/;"kind:variable line:5 +recdType /tmp/apUNI8a/main.ino /^unsigned char recdState, recdType;$/;"kind:variable line:5 +retries /tmp/apUNI8a/main.ino /^unsigned char retries;$/;" kind:variable line:6 +bwMap /tmp/apUNI8a/main.ino /^const unsigned char bwMap[4 \/* new cycle green yellow red blue (green) *\/] = {2, 6, 4, 1};$/;" kind:variable line:27 +bwButton /tmp/apUNI8a/main.ino /^unsigned char bwButton, bwCycle;$/;" kind:variable line:28 +bwCycle /tmp/apUNI8a/main.ino /^unsigned char bwButton, bwCycle;$/;" kind:variable line:28 +checkBW /tmp/apUNI8a/main.ino /^void checkBW(void); \/* watch button increment bwCycle *\/$/;" kind:prototype line:29 signature:(void) returntype:void +ledState /tmp/apUNI8a/main.ino /^unsigned char ledState;$/;" kind:variable line:31 +mySwitches /tmp/apUNI8a/main.ino /^unsigned char mySwitches;$/;" kind:variable line:32 +BWMODE /tmp/apUNI8a/main.ino /^unsigned char BWMODE, BLINKMODE;$/;" kind:variable line:34 +BLINKMODE /tmp/apUNI8a/main.ino /^unsigned char BWMODE, BLINKMODE;$/;" kind:variable line:34 +lightFSM /tmp/apUNI8a/main.ino /^void lightFSM(void);$/;" kind:prototype line:36 signature:(void) returntype:void +blinkLEDs /tmp/apUNI8a/main.ino /^void blinkLEDs(void);$/;" kind:prototype line:37 signature:(void) returntype:void +touchTimer /tmp/apUNI8a/main.ino /^unsigned touchTimer, lastTouch;$/;" kind:variable line:38 +lastTouch /tmp/apUNI8a/main.ino /^unsigned touchTimer, lastTouch;$/;" kind:variable line:38 +lightTimer /tmp/apUNI8a/main.ino /^unsigned char lightTimer;$/;" kind:variable line:40 +lamp /tmp/apUNI8a/main.ino /^unsigned int lamp;$/;" kind:variable line:45 +loops /tmp/apUNI8a/main.ino /^unsigned long loops;$/;" kind:variable line:46 +recFlag /tmp/apUNI8a/main.ino /^unsigned char recFlag; \/\/ have "we" asked for a packet?$/;" kind:variable line:48 +needAck /tmp/apUNI8a/main.ino /^unsigned char needAck;$/;" kind:variable line:49 +fsmFSM /tmp/apUNI8a/main.ino /^void fsmFSM(void);$/;" kind:prototype line:51 signature:(void) returntype:void +printFlag /tmp/apUNI8a/main.ino /^unsigned int printFlag;$/;" kind:variable line:52 +fsmTimer /tmp/apUNI8a/main.ino /^unsigned long fsmTimer;$/;" kind:variable line:53 +startval /tmp/apUNI8a/main.ino /^uint8_t startval, command;$/;" kind:variable line:57 +command /tmp/apUNI8a/main.ino /^uint8_t startval, command;$/;" kind:variable line:57 +iCnt /tmp/apUNI8a/main.ino /^int iCnt;$/;" kind:variable line:58 +myMessage /tmp/apUNI8a/main.ino /^char myMessage[8];$/;" kind:variable line:60 +ackMessage /tmp/apUNI8a/main.ino /^char ackMessage[8];$/;" kind:variable line:61 +setup /tmp/apUNI8a/main.ino /^void setup() {$/;" kind:function line:63signature:() returntype:void +valid /tmp/apUNI8a/main.ino /^unsigned char valid;$/;" kind:variable line:114 +loop /tmp/apUNI8a/main.ino /^void loop() {$/;" kind:function line:116signature:() returntype:void +listeni /tmp/apUNI8a/main.ino /^void listeni()$/;" kind:function line:165signature:() returntype:void +kickIt /tmp/apUNI8a/main.ino /^void kickIt(unsigned char xType)$/;" kind:function line:172 signature:(unsigned char xType) returntype:void +lightFSM /tmp/apUNI8a/main.ino /^void lightFSM()$/;" kind:function line:181 signature:() returntype:void +touchFSM /tmp/apUNI8a/main.ino /^void touchFSM()$/;" kind:function line:188 signature:() returntype:void +tween /tmp/apUNI8a/main.ino /^unsigned char tween[4] = {3, 5, 7, 11};$/;" kind:variable line:206 +fsmFSM /tmp/apUNI8a/main.ino /^void fsmFSM()$/;" kind:function line:207signature:() returntype:void +doBW /tmp/apUNI8a/main.ino /^void doBW(void) {$/;" kind:function line:243signature:(void) returntype:void +checkBW /tmp/apUNI8a/main.ino /^void checkBW()$/;" kind:function line:249signature:() returntype:void +getSwitches /tmp/apUNI8a/main.ino /^unsigned char getSwitches()$/;" kind:function line:260 signature:() returntype:unsigned char +xxLamp /tmp/apUNI8a/main.ino /^unsigned char xxLamp;$/;" kind:variable line:292 +setLEDs /tmp/apUNI8a/main.ino /^void setLEDs(unsigned char xx)$/;" kind:function line:294 signature:(unsigned char xx) returntype:void +blinks /tmp/apUNI8a/main.ino /^const unsigned char blinks[8] = {0, 1, 0, 1, 0, 0, 1, 1};$/;" kind:variable line:311 +blinkLEDs /tmp/apUNI8a/main.ino /^void blinkLEDs()$/;" kind:function line:312 signature:() returntype:void +proto_state /tmp/apUNI8a/protocol.ino /^static uint8_t proto_state;$/;" kind:variable line:4 +bind_time /tmp/apUNI8a/protocol.ino /^static uint32_t bind_time;$/;"kind:variable line:5 +PROTOCOL_SetBindState /tmp/apUNI8a/protocol.ino /^void PROTOCOL_SetBindState(uint32_t msec)$/;" kind:function line:11 signature:(uint32_t msec) returntype:void diff --git a/src/arduino.cc/builder/ctags_runner.go b/src/arduino.cc/builder/ctags_runner.go index b869d6f3..e2b6acbb 100644 --- a/src/arduino.cc/builder/ctags_runner.go +++ b/src/arduino.cc/builder/ctags_runner.go @@ -74,7 +74,8 @@ func (s *CTagsRunner) Run(ctx *types.Context) error { ctx.CTagsOutput = string(sourceBytes) parser := &ctags.CTagsParser{} - ctx.CTagsOfPreprocessedSource = parser.Parse(ctx.CTagsOutput) + ctx.CTagsOfPreprocessedSource = parser.Parse(ctx.CTagsOutput, ctx.Sketch.MainFile.Name) + protos, line := parser.GeneratePrototypes() if line != -1 { ctx.PrototypesLineWhereToInsert = line