From d5d9186e6c03f34c9b44037360f66f5ccf5ddc0b Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 20 Dec 2016 09:25:11 +0100 Subject: [PATCH 1/2] Only trust function line number in main sketch file Previously, function line numbers are extracted from any tag (in any file) so exctracted line is nonsense if the main sketch is empty/has lots of lines and lots of comments/etc Fixes #199 --- src/arduino.cc/builder/ctags/ctags_parser.go | 7 +++++-- src/arduino.cc/builder/ctags/ctags_to_prototypes.go | 8 +++++--- src/arduino.cc/builder/ctags_runner.go | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) 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_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_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 From 316c57acb7c01a00c70f58e7528f1f0a13c4bcdb Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 20 Dec 2016 10:01:53 +0100 Subject: [PATCH 2/2] Fix tests for new Parse signature and add new test for multifile --- .../builder/ctags/ctags_parser_test.go | 2 +- .../builder/ctags/ctags_to_prototypes_test.go | 43 +++++++---- .../TestCTagsRunnerSketchWithMultifile.txt | 77 +++++++++++++++++++ 3 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 src/arduino.cc/builder/ctags/test_data/TestCTagsRunnerSketchWithMultifile.txt 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_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