Prefer plain 'static' to 'static inline'.
[bpt/emacs.git] / lib-src / etags.c
index b6af17b..aa8c773 100644 (file)
@@ -1,4 +1,4 @@
-/* Tags file maker to go with GNU Emacs           -*- coding: latin-1 -*-
+/* Tags file maker to go with GNU Emacs           -*- coding: utf-8 -*-
 
 Copyright (C) 1984 The Regents of the University of California
 
@@ -28,8 +28,8 @@ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2012
-  Free Software Foundation, Inc.
+Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2013 Free Software
+Foundation, Inc.
 
 This file is not considered part of GNU Emacs.
 
@@ -64,12 +64,12 @@ University of California, as described above. */
  * 1985 Emacs TAGS format by Richard Stallman.
  * 1989 Sam Kendall added C++.
  * 1992 Joseph B. Wells improved C and C++ parsing.
- * 1993 Francesco Potortì reorganized C and C++.
+ * 1993 Francesco Potortì reorganized C and C++.
  * 1994 Line-by-line regexp tags by Tom Tromey.
- * 2001 Nested classes by Francesco Potortì (concept by Mykola Dzyuba).
- * 2002 #line directives by Francesco Potortì.
+ * 2001 Nested classes by Francesco Potortì (concept by Mykola Dzyuba).
+ * 2002 #line directives by Francesco Potortì.
  *
- * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
+ * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
  */
 
 /*
@@ -316,15 +316,7 @@ static void Texinfo_nodes (FILE *);
 static void Yacc_entries (FILE *);
 static void just_read_file (FILE *);
 
-static void print_language_names (void);
-static void print_version (void);
-static void print_help (argument *);
-int main (int, char **);
-
-static compressor *get_compressor_from_suffix (char *, char **);
 static language *get_language_from_langname (const char *);
-static language *get_language_from_interpreter (char *);
-static language *get_language_from_filename (char *, bool);
 static void readline (linebuffer *, FILE *);
 static long readline_internal (linebuffer *, FILE *);
 static bool nocase_tail (const char *);
@@ -346,13 +338,13 @@ static void find_entries (FILE *);
 static void free_tree (node *);
 static void free_fdesc (fdesc *);
 static void pfnote (char *, bool, char *, int, int, long);
-static void make_tag (const char *, int, bool, char *, int, int, long);
 static void invalidate_nodes (fdesc *, node **);
 static void put_entries (node *);
 
 static char *concat (const char *, const char *, const char *);
 static char *skip_spaces (char *);
 static char *skip_non_spaces (char *);
+static char *skip_name (char *);
 static char *savenstr (const char *, int);
 static char *savestr (const char *);
 static char *etags_strchr (const char *, int);
@@ -619,7 +611,8 @@ static const char Lisp_help [] =
 "In Lisp code, any function defined with `defun', any variable\n\
 defined with `defvar' or `defconst', and in general the first\n\
 argument of any expression that starts with `(def' in column zero\n\
-is a tag.";
+is a tag.\n\
+The `--declarations' option tags \"(defvar foo)\" constructs too.";
 
 static const char *Lua_suffixes [] =
   { "lua", "LUA", NULL };
@@ -814,7 +807,7 @@ etags --help --lang=ada.");
 #ifndef VERSION
 # define VERSION "17.38.1.4"
 #endif
-static void
+static _Noreturn void
 print_version (void)
 {
   char emacs_copyright[] = COPYRIGHT;
@@ -830,7 +823,7 @@ print_version (void)
 # define PRINT_UNDOCUMENTED_OPTIONS_HELP FALSE
 #endif
 
-static void
+static _Noreturn void
 print_help (argument *argbuffer)
 {
   bool help_for_lang = FALSE;
@@ -2247,10 +2240,6 @@ enum sym_type
   st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef
 };
 
-static unsigned int hash (const char *, unsigned int);
-static struct C_stab_entry * in_word_set (const char *, unsigned int);
-static enum sym_type C_symtype (char *, int, int);
-
 /* Feed stuff between (but not including) %[ and %] lines to:
      gperf -m 5
 %[
@@ -2309,10 +2298,10 @@ and replace lines between %< and %> with its output, then:
 struct C_stab_entry { const char *name; int c_ext; enum sym_type type; };
 /* maximum key range = 33, duplicates = 0 */
 
-static inline unsigned int
-hash (register const char *str, register unsigned int len)
+static int
+hash (const char *str, int len)
 {
-  static unsigned char asso_values[] =
+  static char const asso_values[] =
     {
       35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
       35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
@@ -2341,15 +2330,15 @@ hash (register const char *str, register unsigned int len)
       35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
       35, 35, 35, 35, 35, 35
     };
-  register int hval = len;
+  int hval = len;
 
   switch (hval)
     {
       default:
-        hval += asso_values[(unsigned char)str[2]];
+        hval += asso_values[(unsigned char) str[2]];
       /*FALLTHROUGH*/
       case 2:
-        hval += asso_values[(unsigned char)str[1]];
+        hval += asso_values[(unsigned char) str[1]];
         break;
     }
   return hval;
@@ -2407,11 +2396,11 @@ in_word_set (register const char *str, register unsigned int len)
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
     {
-      register int key = hash (str, len);
+      int key = hash (str, len);
 
       if (key <= MAX_HASH_VALUE && key >= 0)
         {
-          register const char *s = wordlist[key].name;
+          const char *s = wordlist[key].name;
 
           if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
             return &wordlist[key];
@@ -4269,10 +4258,11 @@ Asm_labels (FILE *inf)
 /*
  * Perl support
  * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
+ *                 /^use constant[ \t\n]+[^ \t\n{=,;]+/
  * Perl variable names: /^(my|local).../
  * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
  * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
- * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
+ * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
  */
 static void
 Perl_functions (FILE *inf)
@@ -4291,9 +4281,10 @@ Perl_functions (FILE *inf)
        }
       else if (LOOKING_AT (cp, "sub"))
        {
-         char *pos;
-         char *sp = cp;
+         char *pos, *sp;
 
+       subr:
+         sp = cp;
          while (!notinname (*cp))
            cp++;
          if (cp == sp)
@@ -4316,8 +4307,21 @@ Perl_functions (FILE *inf)
                        lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
              free (name);
            }
+       }
+      else if (LOOKING_AT (cp, "use constant")
+              || LOOKING_AT (cp, "use constant::defer"))
+       {
+         /* For hash style multi-constant like
+               use constant { FOO => 123,
+                              BAR => 456 };
+            only the first FOO is picked up.  Parsing across the value
+            expressions would be difficult in general, due to possible nested
+            hashes, here-documents, etc.  */
+         if (*cp == '{')
+           cp = skip_spaces (cp+1);
+         goto subr;
        }
-       else if (globals)       /* only if we are tagging global vars */
+      else if (globals)        /* only if we are tagging global vars */
        {
          /* Skip a qualifier, if any. */
          bool qual = LOOKING_AT (cp, "my") || LOOKING_AT (cp, "local");
@@ -4732,6 +4736,19 @@ Lisp_functions (FILE *inf)
       if (dbp[0] != '(')
        continue;
 
+      /* "(defvar foo)" is a declaration rather than a definition.  */
+      if (! declarations)
+       {
+         char *p = dbp + 1;
+         if (LOOKING_AT (p, "defvar"))
+           {
+             p = skip_name (p); /* past var name */
+             p = skip_spaces (p);
+             if (*p == ')')
+               continue;
+           }
+       }
+
       if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3))
        {
          dbp = skip_non_spaces (dbp);
@@ -5075,7 +5092,7 @@ Texinfo_nodes (FILE *inf)
  * Contents of <title>, <h1>, <h2>, <h3> are tags.
  * Contents of <a name=xxx> are tags with name xxx.
  *
- * Francesco Potortì, 2002.
+ * Francesco Potortì, 2002.
  */
 static void
 HTML_labels (FILE *inf)
@@ -5598,10 +5615,7 @@ analyse_regex (char *regex_arg)
        /* regexfile is a file containing regexps, one per line. */
        regexfp = fopen (regexfile, "r");
        if (regexfp == NULL)
-         {
-           pfatal (regexfile);
-           return;
-         }
+         pfatal (regexfile);
        linebuffer_init (&regexbuf);
        while (readline_internal (&regexbuf, regexfp) > 0)
          analyse_regex (regexbuf.buffer);
@@ -6292,6 +6306,16 @@ skip_non_spaces (char *cp)
   return cp;
 }
 
+/* Skip any chars in the "name" class.*/
+static char *
+skip_name (char *cp)
+{
+  /* '\0' is a notinname() so loop stops there too */
+  while (! notinname (*cp))
+    cp++;
+  return cp;
+}
+
 /* Print error message and exit.  */
 void
 fatal (const char *s1, const char *s2)