# HG changeset patch # User Francesco Potort # Date 1008432451 0 # Node ID 481d38f6aec203f5ea9a8616d83252530c258f4f # Parent b4eeb5fd09f9d484cda15696d6e010665706d201 * etags.c (PHP_functions): New function by Diez B. Roggisch, heavily adapted by me, for parsing PHP. (LOOKING_AT): New macro. (Perl_functions, Python_functions, PHP_functions) (Scheme_functions, Texinfo_nodes): Use it. (Perl_functions): Use strneq. (prolog_pred): Renamed to prolog_pr. (prolog_pr): Recognise Prolog rules (thanks to Geert Kloosterman) in addition to predicates. [ETAGS_REGEXPS] [!HAVE_CONFIG_H] [__CYGWIN__]: Prevent unmodified compile, as Cygwin's regex.h is incompatible with us (thanks to Markus Hoenicka). [!HAVE_CONFIG_H] [!__STDC__]: #define const as the empty string. diff -r b4eeb5fd09f9 -r 481d38f6aec2 lib-src/etags.c --- a/lib-src/etags.c Sat Dec 15 10:32:44 2001 +0000 +++ b/lib-src/etags.c Sat Dec 15 16:07:31 2001 +0000 @@ -32,7 +32,7 @@ * Francesco Potort has maintained it since 1993. */ -char pot_etags_version[] = "@(#) pot revision number is 14.21"; +char pot_etags_version[] = "@(#) pot revision number is 14.26"; #define TRUE 1 #define FALSE 0 @@ -61,6 +61,7 @@ #else # ifndef __STDC__ # define static /* remove static for old compilers' sake */ +# define const /* same for const */ # endif #endif /* !HAVE_CONFIG_H */ @@ -148,6 +149,14 @@ #endif /* LONG_OPTIONS */ #ifdef ETAGS_REGEXPS +# ifndef HAVE_CONFIG_H /* this is a standalone compilation */ +# ifdef __CYGWIN__ /* compiling on Cygwin */ + !!! NOTICE !!! + the regex.h distributed with Cygwin is not compatible with etags, alas! +If you want regular expression support, you should delete this notice and + arrange to use the GNU regex.h and regex.c. +# endif +# endif # include #endif /* ETAGS_REGEXPS */ @@ -272,6 +281,7 @@ static void Makefile_targets P_((FILE *)); static void Pascal_functions P_((FILE *)); static void Perl_functions P_((FILE *)); +static void PHP_functions P_((FILE *)); static void Postscript_functions P_((FILE *)); static void Prolog_functions P_((FILE *)); static void Python_functions P_((FILE *)); @@ -521,6 +531,9 @@ char *Perl_interpreters [] = { "perl", "@PERL@", NULL }; +char *PHP_suffixes [] = + { "php", "php3", "php4", NULL }; + char *plain_C_suffixes [] = { "lm", /* Objective lex file */ "m", /* Objective C file */ @@ -571,6 +584,7 @@ { "makefile", Makefile_targets, Makefile_filenames, NULL, NULL }, { "pascal", Pascal_functions, NULL, Pascal_suffixes, NULL }, { "perl", Perl_functions, NULL, Perl_suffixes, Perl_interpreters }, + { "php", PHP_functions, NULL, PHP_suffixes, NULL }, { "postscript", Postscript_functions, NULL, Postscript_suffixes, NULL }, { "proc", plain_C_entries, NULL, plain_C_suffixes, NULL }, { "prolog", Prolog_functions, NULL, Prolog_suffixes, NULL }, @@ -3582,7 +3596,7 @@ } -/* A useful macro. */ +/* Useful macros. */ #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ for (lineno = charno = 0; /* loop initialization */ \ !feof (file_pointer) /* loop test */ \ @@ -3592,7 +3606,10 @@ char_pointer = lb.buffer, \ TRUE); \ ) - +#define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \ + (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at kyword */ \ + && iswhite((cp)[sizeof(keyword)-1]) /* followed by a blank */ \ + && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip blanks */ /* * Read a file, but do no processing. This is used to do regexp @@ -3971,11 +3988,8 @@ LOOP_ON_INPUT_LINES (inf, lb, cp) { - if (*cp++ == 's' - && *cp++ == 'u' - && *cp++ == 'b' && iswhite (*cp++)) + if (LOOKING_AT (cp, "sub")) { - cp = skip_spaces (cp); if (*cp != '\0') { char *sp = cp; @@ -3987,15 +4001,8 @@ } } else if (globals /* only if tagging global vars is enabled */ - && ((cp = lb.buffer, - *cp++ == 'm' - && *cp++ == 'y') - || (cp = lb.buffer, - *cp++ == 'l' - && *cp++ == 'o' - && *cp++ == 'c' - && *cp++ == 'a' - && *cp++ == 'l')) + && ((strneq (cp, "my", 2) && (cp+=2)) + || (strneq (cp, "local", 5) && (cp+=5))) && (*cp == '(' || iswhite (*cp))) { /* After "my" or "local", but before any following paren or space. */ @@ -4025,7 +4032,7 @@ } } - + /* * Python support * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ @@ -4038,29 +4045,89 @@ register char *cp; LOOP_ON_INPUT_LINES (inf, lb, cp) + if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class")) + { + while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') + cp++; + pfnote (NULL, TRUE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } +} + + +/* + * PHP support + * Look for: + * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/ + * - /^[ \t]*class[ \t\n]+[^ \t\n]+/ + * - /^[ \t]*define\(\"[^\"]+/ + * Only with --members: + * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/ + * originally by Diez B. Roggisch 2001-06-06 + */ +static void +PHP_functions (inf) + FILE *inf; +{ + register char *cp; + bool search_identifier = FALSE; + + LOOP_ON_INPUT_LINES (inf, lb, cp) { - if (*cp++ == 'd' - && *cp++ == 'e' - && *cp++ == 'f' && iswhite (*cp++)) + cp = skip_spaces (cp); + if (search_identifier + && *cp != '\0') { - cp = skip_spaces (cp); - while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') + while (*cp != '\0' && !iswhite (*cp) && *cp != '(') cp++; pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + search_identifier = FALSE; } - - cp = lb.buffer; - if (*cp++ == 'c' - && *cp++ == 'l' - && *cp++ == 'a' - && *cp++ == 's' - && *cp++ == 's' && iswhite (*cp++)) + else if (LOOKING_AT (cp, "function")) + { + if(*cp == '&') + cp = skip_spaces (cp+1); + if(*cp != '\0') + { + while (*cp != '\0' && !iswhite (*cp) && *cp != '(') + cp++; + pfnote (NULL, TRUE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + else + search_identifier = TRUE; + } + else if (LOOKING_AT (cp, "class")) { - cp = skip_spaces (cp); - while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') + if (*cp != '\0') + { + while (*cp != '\0' && !iswhite (*cp)) + cp++; + pfnote (NULL, FALSE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + else + search_identifier = TRUE; + } + else if (strneq (cp, "define", 6) + && (cp = skip_spaces (cp+6)) + && *cp++ == '(' + && (*cp == '"' || *cp == '\'')) + { + char quote = *cp++; + while (*cp != quote && *cp != '\0') cp++; - pfnote (NULL, TRUE, + pfnote (NULL, FALSE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + else if (members + && LOOKING_AT (cp, "var") + && *cp == '$') + { + while (*cp != '=' && *cp != ';' && *cp != '\0' && !iswhite(*cp)) + cp++; + pfnote (NULL, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } } @@ -4461,17 +4528,8 @@ bp++; get_tag (bp); } - if (bp[0] == '(' - && (bp[1] == 'S' || bp[1] == 's') - && (bp[2] == 'E' || bp[2] == 'e') - && (bp[3] == 'T' || bp[3] == 't') - && (bp[4] == '!' || bp[4] == '!') - && (iswhite (bp[5]))) - { - bp = skip_non_spaces (bp); - bp = skip_spaces (bp); - get_tag (bp); - } + if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!")) + get_tag (bp); } } @@ -4666,20 +4724,14 @@ { char *cp, *start; LOOP_ON_INPUT_LINES (inf, lb, cp) - { - if ((*cp++ == '@' - && *cp++ == 'n' - && *cp++ == 'o' - && *cp++ == 'd' - && *cp++ == 'e' && iswhite (*cp++))) - { - start = cp = skip_spaces(cp); - while (*cp != '\0' && *cp != ',') - cp++; - pfnote (savenstr (start, cp - start), TRUE, - lb.buffer, cp - lb.buffer + 1, lineno, linecharno); - } - } + if (LOOKING_AT (cp, "@node")) + { + start = cp; + while (*cp != '\0' && *cp != ',') + cp++; + pfnote (savenstr (start, cp - start), TRUE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } } @@ -4689,7 +4741,7 @@ * Assumes that the predicate starts at column 0. * Only the first clause of a predicate is added. */ -static int prolog_pred P_((char *, char *)); +static int prolog_pr P_((char *, char *)); static void prolog_skip_comment P_((linebuffer *, FILE *)); static int prolog_atom P_((char *, int)); @@ -4713,7 +4765,7 @@ continue; else if (cp[0] == '/' && cp[1] == '*') /* comment. */ prolog_skip_comment (&lb, inf); - else if ((len = prolog_pred (cp, last)) > 0) + else if ((len = prolog_pr (cp, last)) > 0) { /* Predicate. Store the function name so that we only generate a tag for the first clause. */ @@ -4748,17 +4800,18 @@ } /* - * A predicate definition is added if it matches: + * A predicate or rule definition is added if it matches: * ( + * or :- * * It is added to the tags database if it doesn't match the * name of the previous clause header. * - * Return the size of the name of the predicate, or 0 if no header - * was found. + * Return the size of the name of the predicate or rule, or 0 if no + * header was found. */ static int -prolog_pred (s, last) +prolog_pr (s, last) char *s; char *last; /* Name of last clause. */ { @@ -4772,21 +4825,18 @@ len = pos; pos = skip_spaces (s + pos) - s; - if ((s[pos] == '(') || (s[pos] == '.')) - { - if (s[pos] == '(') - pos++; - - /* Save only the first clause. */ - if (last == NULL - || len != (int)strlen (last) - || !strneq (s, last, len)) + if ((s[pos] == '.' + || (s[pos] == '(' && (pos += 1)) + || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) + && (last == NULL /* save only the first clause */ + || len != strlen (last) + || !strneq (s, last, len))) { pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); return len; } - } - return 0; + else + return 0; } /* @@ -5817,3 +5867,12 @@ fatal ("virtual memory exhausted", (char *)NULL); return result; } + +/* + * Local Variables: + * c-indentation-style: gnu + * indent-tabs-mode: t + * tab-width: 8 + * c-font-lock-extra-types: ("FILE" "bool" "linebuffer") + * End: + */