aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì2001-12-15 16:07:31 +0000
committerFrancesco Potortì2001-12-15 16:07:31 +0000
commit62aec606f5f6d73ef52c10b4d8ee147c2c9657b9 (patch)
tree64b7a54461b5fe90a3ae7bfc43e080345045ae50 /lib-src
parent846dc4bae094e35ca600ad1614de41c5479665d2 (diff)
downloademacs-62aec606f5f6d73ef52c10b4d8ee147c2c9657b9.tar.gz
emacs-62aec606f5f6d73ef52c10b4d8ee147c2c9657b9.zip
* 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.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c207
1 files changed, 133 insertions, 74 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index f0c613f232b..510648f95a9 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -32,7 +32,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
32 * Francesco Potortì <pot@gnu.org> has maintained it since 1993. 32 * Francesco Potortì <pot@gnu.org> has maintained it since 1993.
33 */ 33 */
34 34
35char pot_etags_version[] = "@(#) pot revision number is 14.21"; 35char pot_etags_version[] = "@(#) pot revision number is 14.26";
36 36
37#define TRUE 1 37#define TRUE 1
38#define FALSE 0 38#define FALSE 0
@@ -61,6 +61,7 @@ char pot_etags_version[] = "@(#) pot revision number is 14.21";
61#else 61#else
62# ifndef __STDC__ 62# ifndef __STDC__
63# define static /* remove static for old compilers' sake */ 63# define static /* remove static for old compilers' sake */
64# define const /* same for const */
64# endif 65# endif
65#endif /* !HAVE_CONFIG_H */ 66#endif /* !HAVE_CONFIG_H */
66 67
@@ -148,6 +149,14 @@ char pot_etags_version[] = "@(#) pot revision number is 14.21";
148#endif /* LONG_OPTIONS */ 149#endif /* LONG_OPTIONS */
149 150
150#ifdef ETAGS_REGEXPS 151#ifdef ETAGS_REGEXPS
152# ifndef HAVE_CONFIG_H /* this is a standalone compilation */
153# ifdef __CYGWIN__ /* compiling on Cygwin */
154 !!! NOTICE !!!
155 the regex.h distributed with Cygwin is not compatible with etags, alas!
156If you want regular expression support, you should delete this notice and
157 arrange to use the GNU regex.h and regex.c.
158# endif
159# endif
151# include <regex.h> 160# include <regex.h>
152#endif /* ETAGS_REGEXPS */ 161#endif /* ETAGS_REGEXPS */
153 162
@@ -272,6 +281,7 @@ static void Lisp_functions P_((FILE *));
272static void Makefile_targets P_((FILE *)); 281static void Makefile_targets P_((FILE *));
273static void Pascal_functions P_((FILE *)); 282static void Pascal_functions P_((FILE *));
274static void Perl_functions P_((FILE *)); 283static void Perl_functions P_((FILE *));
284static void PHP_functions P_((FILE *));
275static void Postscript_functions P_((FILE *)); 285static void Postscript_functions P_((FILE *));
276static void Prolog_functions P_((FILE *)); 286static void Prolog_functions P_((FILE *));
277static void Python_functions P_((FILE *)); 287static void Python_functions P_((FILE *));
@@ -521,6 +531,9 @@ char *Perl_suffixes [] =
521char *Perl_interpreters [] = 531char *Perl_interpreters [] =
522 { "perl", "@PERL@", NULL }; 532 { "perl", "@PERL@", NULL };
523 533
534char *PHP_suffixes [] =
535 { "php", "php3", "php4", NULL };
536
524char *plain_C_suffixes [] = 537char *plain_C_suffixes [] =
525 { "lm", /* Objective lex file */ 538 { "lm", /* Objective lex file */
526 "m", /* Objective C file */ 539 "m", /* Objective C file */
@@ -571,6 +584,7 @@ language lang_names [] =
571 { "makefile", Makefile_targets, Makefile_filenames, NULL, NULL }, 584 { "makefile", Makefile_targets, Makefile_filenames, NULL, NULL },
572 { "pascal", Pascal_functions, NULL, Pascal_suffixes, NULL }, 585 { "pascal", Pascal_functions, NULL, Pascal_suffixes, NULL },
573 { "perl", Perl_functions, NULL, Perl_suffixes, Perl_interpreters }, 586 { "perl", Perl_functions, NULL, Perl_suffixes, Perl_interpreters },
587 { "php", PHP_functions, NULL, PHP_suffixes, NULL },
574 { "postscript", Postscript_functions, NULL, Postscript_suffixes, NULL }, 588 { "postscript", Postscript_functions, NULL, Postscript_suffixes, NULL },
575 { "proc", plain_C_entries, NULL, plain_C_suffixes, NULL }, 589 { "proc", plain_C_entries, NULL, plain_C_suffixes, NULL },
576 { "prolog", Prolog_functions, NULL, Prolog_suffixes, NULL }, 590 { "prolog", Prolog_functions, NULL, Prolog_suffixes, NULL },
@@ -3582,7 +3596,7 @@ Yacc_entries (inf)
3582} 3596}
3583 3597
3584 3598
3585/* A useful macro. */ 3599/* Useful macros. */
3586#define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ 3600#define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3587 for (lineno = charno = 0; /* loop initialization */ \ 3601 for (lineno = charno = 0; /* loop initialization */ \
3588 !feof (file_pointer) /* loop test */ \ 3602 !feof (file_pointer) /* loop test */ \
@@ -3592,7 +3606,10 @@ Yacc_entries (inf)
3592 char_pointer = lb.buffer, \ 3606 char_pointer = lb.buffer, \
3593 TRUE); \ 3607 TRUE); \
3594 ) 3608 )
3595 3609#define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
3610 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at kyword */ \
3611 && iswhite((cp)[sizeof(keyword)-1]) /* followed by a blank */ \
3612 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip blanks */
3596 3613
3597/* 3614/*
3598 * Read a file, but do no processing. This is used to do regexp 3615 * Read a file, but do no processing. This is used to do regexp
@@ -3971,11 +3988,8 @@ Perl_functions (inf)
3971 3988
3972 LOOP_ON_INPUT_LINES (inf, lb, cp) 3989 LOOP_ON_INPUT_LINES (inf, lb, cp)
3973 { 3990 {
3974 if (*cp++ == 's' 3991 if (LOOKING_AT (cp, "sub"))
3975 && *cp++ == 'u'
3976 && *cp++ == 'b' && iswhite (*cp++))
3977 { 3992 {
3978 cp = skip_spaces (cp);
3979 if (*cp != '\0') 3993 if (*cp != '\0')
3980 { 3994 {
3981 char *sp = cp; 3995 char *sp = cp;
@@ -3987,15 +4001,8 @@ Perl_functions (inf)
3987 } 4001 }
3988 } 4002 }
3989 else if (globals /* only if tagging global vars is enabled */ 4003 else if (globals /* only if tagging global vars is enabled */
3990 && ((cp = lb.buffer, 4004 && ((strneq (cp, "my", 2) && (cp+=2))
3991 *cp++ == 'm' 4005 || (strneq (cp, "local", 5) && (cp+=5)))
3992 && *cp++ == 'y')
3993 || (cp = lb.buffer,
3994 *cp++ == 'l'
3995 && *cp++ == 'o'
3996 && *cp++ == 'c'
3997 && *cp++ == 'a'
3998 && *cp++ == 'l'))
3999 && (*cp == '(' || iswhite (*cp))) 4006 && (*cp == '(' || iswhite (*cp)))
4000 { 4007 {
4001 /* After "my" or "local", but before any following paren or space. */ 4008 /* After "my" or "local", but before any following paren or space. */
@@ -4025,7 +4032,7 @@ Perl_functions (inf)
4025 } 4032 }
4026} 4033}
4027 4034
4028 4035
4029/* 4036/*
4030 * Python support 4037 * Python support
4031 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ 4038 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
@@ -4038,29 +4045,89 @@ Python_functions (inf)
4038 register char *cp; 4045 register char *cp;
4039 4046
4040 LOOP_ON_INPUT_LINES (inf, lb, cp) 4047 LOOP_ON_INPUT_LINES (inf, lb, cp)
4048 if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class"))
4049 {
4050 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':')
4051 cp++;
4052 pfnote (NULL, TRUE,
4053 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4054 }
4055}
4056
4057
4058/*
4059 * PHP support
4060 * Look for:
4061 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4062 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4063 * - /^[ \t]*define\(\"[^\"]+/
4064 * Only with --members:
4065 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4066 * originally by Diez B. Roggisch 2001-06-06
4067 */
4068static void
4069PHP_functions (inf)
4070 FILE *inf;
4071{
4072 register char *cp;
4073 bool search_identifier = FALSE;
4074
4075 LOOP_ON_INPUT_LINES (inf, lb, cp)
4041 { 4076 {
4042 if (*cp++ == 'd' 4077 cp = skip_spaces (cp);
4043 && *cp++ == 'e' 4078 if (search_identifier
4044 && *cp++ == 'f' && iswhite (*cp++)) 4079 && *cp != '\0')
4045 { 4080 {
4046 cp = skip_spaces (cp); 4081 while (*cp != '\0' && !iswhite (*cp) && *cp != '(')
4047 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':')
4048 cp++; 4082 cp++;
4049 pfnote (NULL, TRUE, 4083 pfnote (NULL, TRUE,
4050 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4084 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4085 search_identifier = FALSE;
4051 } 4086 }
4052 4087 else if (LOOKING_AT (cp, "function"))
4053 cp = lb.buffer; 4088 {
4054 if (*cp++ == 'c' 4089 if(*cp == '&')
4055 && *cp++ == 'l' 4090 cp = skip_spaces (cp+1);
4056 && *cp++ == 'a' 4091 if(*cp != '\0')
4057 && *cp++ == 's' 4092 {
4058 && *cp++ == 's' && iswhite (*cp++)) 4093 while (*cp != '\0' && !iswhite (*cp) && *cp != '(')
4094 cp++;
4095 pfnote (NULL, TRUE,
4096 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4097 }
4098 else
4099 search_identifier = TRUE;
4100 }
4101 else if (LOOKING_AT (cp, "class"))
4102 {
4103 if (*cp != '\0')
4104 {
4105 while (*cp != '\0' && !iswhite (*cp))
4106 cp++;
4107 pfnote (NULL, FALSE,
4108 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4109 }
4110 else
4111 search_identifier = TRUE;
4112 }
4113 else if (strneq (cp, "define", 6)
4114 && (cp = skip_spaces (cp+6))
4115 && *cp++ == '('
4116 && (*cp == '"' || *cp == '\''))
4059 { 4117 {
4060 cp = skip_spaces (cp); 4118 char quote = *cp++;
4061 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') 4119 while (*cp != quote && *cp != '\0')
4062 cp++; 4120 cp++;
4063 pfnote (NULL, TRUE, 4121 pfnote (NULL, FALSE,
4122 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4123 }
4124 else if (members
4125 && LOOKING_AT (cp, "var")
4126 && *cp == '$')
4127 {
4128 while (*cp != '=' && *cp != ';' && *cp != '\0' && !iswhite(*cp))
4129 cp++;
4130 pfnote (NULL, FALSE,
4064 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4131 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4065 } 4132 }
4066 } 4133 }
@@ -4461,17 +4528,8 @@ Scheme_functions (inf)
4461 bp++; 4528 bp++;
4462 get_tag (bp); 4529 get_tag (bp);
4463 } 4530 }
4464 if (bp[0] == '(' 4531 if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
4465 && (bp[1] == 'S' || bp[1] == 's') 4532 get_tag (bp);
4466 && (bp[2] == 'E' || bp[2] == 'e')
4467 && (bp[3] == 'T' || bp[3] == 't')
4468 && (bp[4] == '!' || bp[4] == '!')
4469 && (iswhite (bp[5])))
4470 {
4471 bp = skip_non_spaces (bp);
4472 bp = skip_spaces (bp);
4473 get_tag (bp);
4474 }
4475 } 4533 }
4476} 4534}
4477 4535
@@ -4666,20 +4724,14 @@ Texinfo_nodes (inf)
4666{ 4724{
4667 char *cp, *start; 4725 char *cp, *start;
4668 LOOP_ON_INPUT_LINES (inf, lb, cp) 4726 LOOP_ON_INPUT_LINES (inf, lb, cp)
4669 { 4727 if (LOOKING_AT (cp, "@node"))
4670 if ((*cp++ == '@' 4728 {
4671 && *cp++ == 'n' 4729 start = cp;
4672 && *cp++ == 'o' 4730 while (*cp != '\0' && *cp != ',')
4673 && *cp++ == 'd' 4731 cp++;
4674 && *cp++ == 'e' && iswhite (*cp++))) 4732 pfnote (savenstr (start, cp - start), TRUE,
4675 { 4733 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4676 start = cp = skip_spaces(cp); 4734 }
4677 while (*cp != '\0' && *cp != ',')
4678 cp++;
4679 pfnote (savenstr (start, cp - start), TRUE,
4680 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4681 }
4682 }
4683} 4735}
4684 4736
4685 4737
@@ -4689,7 +4741,7 @@ Texinfo_nodes (inf)
4689 * Assumes that the predicate starts at column 0. 4741 * Assumes that the predicate starts at column 0.
4690 * Only the first clause of a predicate is added. 4742 * Only the first clause of a predicate is added.
4691 */ 4743 */
4692static int prolog_pred P_((char *, char *)); 4744static int prolog_pr P_((char *, char *));
4693static void prolog_skip_comment P_((linebuffer *, FILE *)); 4745static void prolog_skip_comment P_((linebuffer *, FILE *));
4694static int prolog_atom P_((char *, int)); 4746static int prolog_atom P_((char *, int));
4695 4747
@@ -4713,7 +4765,7 @@ Prolog_functions (inf)
4713 continue; 4765 continue;
4714 else if (cp[0] == '/' && cp[1] == '*') /* comment. */ 4766 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
4715 prolog_skip_comment (&lb, inf); 4767 prolog_skip_comment (&lb, inf);
4716 else if ((len = prolog_pred (cp, last)) > 0) 4768 else if ((len = prolog_pr (cp, last)) > 0)
4717 { 4769 {
4718 /* Predicate. Store the function name so that we only 4770 /* Predicate. Store the function name so that we only
4719 generate a tag for the first clause. */ 4771 generate a tag for the first clause. */
@@ -4748,17 +4800,18 @@ prolog_skip_comment (plb, inf)
4748} 4800}
4749 4801
4750/* 4802/*
4751 * A predicate definition is added if it matches: 4803 * A predicate or rule definition is added if it matches:
4752 * <beginning of line><Prolog Atom><whitespace>( 4804 * <beginning of line><Prolog Atom><whitespace>(
4805 * or <beginning of line><Prolog Atom><whitespace>:-
4753 * 4806 *
4754 * It is added to the tags database if it doesn't match the 4807 * It is added to the tags database if it doesn't match the
4755 * name of the previous clause header. 4808 * name of the previous clause header.
4756 * 4809 *
4757 * Return the size of the name of the predicate, or 0 if no header 4810 * Return the size of the name of the predicate or rule, or 0 if no
4758 * was found. 4811 * header was found.
4759 */ 4812 */
4760static int 4813static int
4761prolog_pred (s, last) 4814prolog_pr (s, last)
4762 char *s; 4815 char *s;
4763 char *last; /* Name of last clause. */ 4816 char *last; /* Name of last clause. */
4764{ 4817{
@@ -4772,21 +4825,18 @@ prolog_pred (s, last)
4772 len = pos; 4825 len = pos;
4773 pos = skip_spaces (s + pos) - s; 4826 pos = skip_spaces (s + pos) - s;
4774 4827
4775 if ((s[pos] == '(') || (s[pos] == '.')) 4828 if ((s[pos] == '.'
4776 { 4829 || (s[pos] == '(' && (pos += 1))
4777 if (s[pos] == '(') 4830 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2)))
4778 pos++; 4831 && (last == NULL /* save only the first clause */
4779 4832 || len != strlen (last)
4780 /* Save only the first clause. */ 4833 || !strneq (s, last, len)))
4781 if (last == NULL
4782 || len != (int)strlen (last)
4783 || !strneq (s, last, len))
4784 { 4834 {
4785 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); 4835 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4786 return len; 4836 return len;
4787 } 4837 }
4788 } 4838 else
4789 return 0; 4839 return 0;
4790} 4840}
4791 4841
4792/* 4842/*
@@ -5817,3 +5867,12 @@ xrealloc (ptr, size)
5817 fatal ("virtual memory exhausted", (char *)NULL); 5867 fatal ("virtual memory exhausted", (char *)NULL);
5818 return result; 5868 return result;
5819} 5869}
5870
5871/*
5872 * Local Variables:
5873 * c-indentation-style: gnu
5874 * indent-tabs-mode: t
5875 * tab-width: 8
5876 * c-font-lock-extra-types: ("FILE" "bool" "linebuffer")
5877 * End:
5878 */