diff --git a/tagmanager/ctags/make.c b/tagmanager/ctags/make.c index 9ed0042a..195dfa2f 100644 --- a/tagmanager/ctags/make.c +++ b/tagmanager/ctags/make.c @@ -59,25 +59,23 @@ static void skipLine (void) fileUngetc (c); } -static int skipToNonWhite (void) +static int skipToNonWhite (int c) { - int c; - do + while (c != '\n' && isspace (c)) c = nextChar (); - while (c != '\n' && isspace (c)); return c; } static boolean isIdentifier (int c) { - return (boolean)(c != '\0' && (isalnum (c) || strchr (".-_/", c) != NULL)); + return (boolean)(c != '\0' && (isalnum (c) || strchr (".-_/$(){}%", c) != NULL)); } static boolean isSpecialTarget (vString *const name) { size_t i = 0; /* All special targets begin with '.'. */ - if (vStringChar (name, i++) != '.') { + if (vStringLength (name) < 1 || vStringChar (name, i++) != '.') { return FALSE; } while (i < vStringLength (name)) { @@ -105,67 +103,27 @@ static void newMacro (vString *const name) makeSimpleTag (name, MakeKinds, K_MACRO); } -static void newMacroFromDefine (vString *const name) -{ - /* name is something like "define JAVAHPP_RULE", find the space and jump to the next char */ - char *name_val = strchr (vStringValue (name), ' '); - - if (name_val != NULL) { - vStringCopyS (name, name_val + 1); - makeSimpleTag (name, MakeKinds, K_MACRO); - } -} - static void readIdentifier (const int first, vString *const id) { + int depth = 0; int c = first; - int c_prev = first; - int c_next = first; vStringClear (id); - while (isIdentifier (c) || c == ' ') + while (isIdentifier (c) || (depth > 0 && c != EOF && c != '\n')) { - c_next = nextChar (); - if (c == ' ') { - /* add the space character only if the previous and - * next character are valid identifiers */ - if (isIdentifier (c_prev) && isIdentifier (c_next)) - vStringPut (id, c); - } - else { - vStringPut (id, c); - } - c_prev = c; - c = c_next; + if (c == '(' || c == '}') + depth++; + else if (depth > 0 && (c == ')' || c == '}')) + depth--; + vStringPut (id, c); + c = nextChar (); } fileUngetc (c); vStringTerminate (id); } -static void skipToMatch (const char *const pair) -{ - const int begin = pair [0], end = pair [1]; - const unsigned long inputLineNumber = getInputLineNumber (); - int matchLevel = 1; - int c = '\0'; - - while (matchLevel > 0) - { - c = nextChar (); - if (c == begin) - ++matchLevel; - else if (c == end) - --matchLevel; - else if (c == '\n' || c == EOF) - break; - } - if (c == EOF) - verbose ("%s: failed to find match for '%c' at line %lu\n", - getInputFileName (), begin, inputLineNumber); -} - static void findMakeTags (void) { - vString *name = vStringNew (); + stringList *identifiers = stringListNew (); boolean newline = TRUE; boolean in_define = FALSE; boolean in_rule = FALSE; @@ -178,14 +136,15 @@ static void findMakeTags (void) { if (in_rule) { - if (c == '\t') + if (c == '\t' || (c = skipToNonWhite (c)) == '#') { - skipLine (); /* skip rule */ - continue; + skipLine (); /* skip rule or comment */ + c = nextChar (); } - else + else if (c != '\n') in_rule = FALSE; } + stringListClear (identifiers); variable_possible = (boolean)(!in_rule); newline = FALSE; } @@ -195,77 +154,70 @@ static void findMakeTags (void) continue; else if (c == '#') skipLine (); - else if (c == '(') - skipToMatch ("()"); - else if (c == '{') - skipToMatch ("{}"); - else if (c == ':') + else if (variable_possible && c == '?') { - variable_possible = TRUE; - in_rule = TRUE; + c = nextChar (); + fileUngetc (c); + variable_possible = (c == '='); + } + else if (variable_possible && c == ':' && + stringListCount (identifiers) > 0) + { + c = nextChar (); + fileUngetc (c); + if (c != '=') + { + unsigned int i; + for (i = 0; i < stringListCount (identifiers); i++) + newTarget (stringListItem (identifiers, i)); + stringListClear (identifiers); + in_rule = TRUE; + } + } + else if (variable_possible && c == '=' && + stringListCount (identifiers) == 1) + { + newMacro (stringListItem (identifiers, 0)); + skipLine (); + in_rule = FALSE; } else if (variable_possible && isIdentifier (c)) { + vString *name = vStringNew (); readIdentifier (c, name); - if (strncmp (vStringValue (name), "endef", 5) == 0) - in_define = FALSE; - else if (in_define) - skipLine (); - else if (strncmp (vStringValue (name), "define", 6) == 0 && - isIdentifier (c)) + stringListAdd (identifiers, name); + + if (stringListCount (identifiers) == 1) { - in_define = TRUE; - c = skipToNonWhite (); - newMacroFromDefine (name); - skipLine (); - } - else { - c = skipToNonWhite (); - if (strchr (":?+", c) != NULL) - { - boolean append = (boolean)(c == '+'); - boolean was_colon = (c == ':'); - c = nextChar (); - if (was_colon) - { - if (c == '=') - { - newMacro (name); - in_rule = FALSE; - skipLine (); - } - else - { - in_rule = TRUE; - newTarget (name); - } - } - else if (append) - { - skipLine (); - continue; - } - else - { - fileUngetc (c); - } - } - else if (c == '=') - { - newMacro (name); - in_rule = FALSE; + if (in_define && ! strcmp (vStringValue (name), "endef")) + in_define = FALSE; + else if (in_define) skipLine (); - } - else + else if (! strcmp (vStringValue (name), "define")) { - fileUngetc (c); + in_define = TRUE; + c = skipToNonWhite (nextChar ()); + vStringClear (name); + /* all remaining characters on the line are the name -- even spaces */ + while (c != EOF && c != '\n') + { + vStringPut (name, c); + c = nextChar (); + } + if (c == '\n') + fileUngetc (c); + vStringTerminate (name); + vStringStripTrailing (name); + newMacro (name); } + else if (! strcmp (vStringValue (name), "export")) + stringListClear (identifiers); } } else variable_possible = FALSE; } - vStringDelete (name); + stringListDelete (identifiers); } extern parserDefinition* MakefileParser (void) diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index e2ff92a3..475fd33e 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -200,6 +200,11 @@ test_sources = \ line_directives.c \ local.c \ macros.c \ + make-comment-in-rule.mak \ + make-gnumake-pattern-rules.mak \ + make-multi-target.mak \ + make-target-with-parentheses.mak \ + make-variable-on-cmdline.mak \ masm.asm \ matlab_backtracking.m \ matlab_test.m \ diff --git a/tests/ctags/make-comment-in-rule.mak b/tests/ctags/make-comment-in-rule.mak new file mode 100644 index 00000000..c6aafd45 --- /dev/null +++ b/tests/ctags/make-comment-in-rule.mak @@ -0,0 +1,17 @@ +# all this is one single rule +all: + a=1; echo "$$a" +# foo + b=2; echo "$$b" + # foo + c=3; echo "$$c" + # foo + d=4; echo "$$d" + # foo + e=5; echo "$$e" + + + f=6; echo "$$f" + # foo + + g=7; echo "$$g" diff --git a/tests/ctags/make-comment-in-rule.mak.tags b/tests/ctags/make-comment-in-rule.mak.tags new file mode 100644 index 00000000..4d085951 --- /dev/null +++ b/tests/ctags/make-comment-in-rule.mak.tags @@ -0,0 +1,2 @@ +# format=tagmanager +allÌ16Ö0 diff --git a/tests/ctags/make-gnumake-pattern-rules.mak b/tests/ctags/make-gnumake-pattern-rules.mak new file mode 100644 index 00000000..5efc3eed --- /dev/null +++ b/tests/ctags/make-gnumake-pattern-rules.mak @@ -0,0 +1,8 @@ +%.o: %.c + touch $@ + +%.p %.q: %.d + touch $@ + +%a b%: + touch $@ diff --git a/tests/ctags/make-gnumake-pattern-rules.mak.tags b/tests/ctags/make-gnumake-pattern-rules.mak.tags new file mode 100644 index 00000000..92d1bee8 --- /dev/null +++ b/tests/ctags/make-gnumake-pattern-rules.mak.tags @@ -0,0 +1,6 @@ +# format=tagmanager +%.oÌ16Ö0 +%.pÌ16Ö0 +%.qÌ16Ö0 +%aÌ16Ö0 +b%Ì16Ö0 diff --git a/tests/ctags/make-multi-target.mak b/tests/ctags/make-multi-target.mak new file mode 100644 index 00000000..e4a30837 --- /dev/null +++ b/tests/ctags/make-multi-target.mak @@ -0,0 +1,8 @@ + +all: foo bar + +foo bar: baz + echo $@ + +baz: + echo $@ diff --git a/tests/ctags/make-multi-target.mak.tags b/tests/ctags/make-multi-target.mak.tags new file mode 100644 index 00000000..c2fd9409 --- /dev/null +++ b/tests/ctags/make-multi-target.mak.tags @@ -0,0 +1,5 @@ +# format=tagmanager +allÌ16Ö0 +barÌ16Ö0 +bazÌ16Ö0 +fooÌ16Ö0 diff --git a/tests/ctags/make-target-with-parentheses.mak b/tests/ctags/make-target-with-parentheses.mak new file mode 100644 index 00000000..5d596986 --- /dev/null +++ b/tests/ctags/make-target-with-parentheses.mak @@ -0,0 +1 @@ +$(obj)/raid6int1.c: F := 6 diff --git a/tests/ctags/make-target-with-parentheses.mak.tags b/tests/ctags/make-target-with-parentheses.mak.tags new file mode 100644 index 00000000..d9b0562d --- /dev/null +++ b/tests/ctags/make-target-with-parentheses.mak.tags @@ -0,0 +1,3 @@ +# format=tagmanager +$(obj)/raid6int1.cÌ16Ö0 +FÌ65536Ö0 diff --git a/tests/ctags/make-variable-on-cmdline.mak b/tests/ctags/make-variable-on-cmdline.mak new file mode 100644 index 00000000..51f2555b --- /dev/null +++ b/tests/ctags/make-variable-on-cmdline.mak @@ -0,0 +1,2 @@ +fixme: + cmd -g FOO=BAR diff --git a/tests/ctags/make-variable-on-cmdline.mak.tags b/tests/ctags/make-variable-on-cmdline.mak.tags new file mode 100644 index 00000000..4b949767 --- /dev/null +++ b/tests/ctags/make-variable-on-cmdline.mak.tags @@ -0,0 +1,2 @@ +# format=tagmanager +fixmeÌ16Ö0 diff --git a/tests/ctags/simple.mak.tags b/tests/ctags/simple.mak.tags index b4db040a..e6879130 100644 --- a/tests/ctags/simple.mak.tags +++ b/tests/ctags/simple.mak.tags @@ -1,15 +1,14 @@ # format=tagmanager +$(obj)/raid6int1.cÌ16Ö0 AÌ65536Ö0 BÌ65536Ö0 CÌ65536Ö0 DÌ65536Ö0 EÌ65536Ö0 -ENV_VAR1Ì65536Ö0 -ENV_VAR2Ì65536Ö0 FÌ65536Ö0 GÌ65536Ö0 HÌ65536Ö0 +IÌ65536Ö0 a.oÌ16Ö0 b.oÌ16Ö0 defaultÌ16Ö0 -export IÌ65536Ö0