/[emacs]/emacs/lib-src/etags.c
ViewVC logotype

Diff of /emacs/lib-src/etags.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3.21.2.4 by miles, Thu Sep 16 00:12:20 2004 UTC revision 3.21.2.5 by miles, Thu Sep 16 00:14:57 2004 UTC
# Line 32  Line 32 
32   * 2002 #line directives by Francesco Potort́.   * 2002 #line directives by Francesco Potort́.
33   *   *
34   * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993.   * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993.
  *  
35   */   */
36    
37  char pot_etags_version[] = "@(#) pot revision number is 16.58";  /*
38     * If you want to add support for a new language, start by looking at the LUA
39     * language, which is the simplest.  Alternatively, consider shipping a
40     * configuration file containing regexp definitions for etags.
41     */
42    
43    char pot_etags_version[] = "@(#) pot revision number is 17.5";
44    
45  #define TRUE    1  #define TRUE    1
46  #define FALSE   0  #define FALSE   0
# Line 61  char pot_etags_version[] = "@(#) pot rev Line 66  char pot_etags_version[] = "@(#) pot rev
66  # ifndef __P                    /* for Xemacs */  # ifndef __P                    /* for Xemacs */
67  #   define __P(args) args  #   define __P(args) args
68  # endif  # endif
69  #else  #else  /* no config.h */
70  # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))  # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
71  #   define __P(args) args       /* use prototypes */  #   define __P(args) args       /* use prototypes */
72  #   define PTR void *           /* for generic pointers */  #   define PTR void *           /* for generic pointers */
73  # else  # else /* not standard C */
74  #   define __P(args) ()         /* no prototypes */  #   define __P(args) ()         /* no prototypes */
75  #   define const                /* remove const for old compilers' sake */  #   define const                /* remove const for old compilers' sake */
76  #   define PTR long *           /* don't use void* */  #   define PTR long *           /* don't use void* */
# Line 118  char pot_etags_version[] = "@(#) pot rev Line 123  char pot_etags_version[] = "@(#) pot rev
123  # ifndef HAVE_GETCWD  # ifndef HAVE_GETCWD
124  #   define HAVE_GETCWD  #   define HAVE_GETCWD
125  # endif /* undef HAVE_GETCWD */  # endif /* undef HAVE_GETCWD */
126  #else /* !WINDOWSNT */  #else /* not WINDOWSNT */
127  # ifdef STDC_HEADERS  # ifdef STDC_HEADERS
128  #  include <stdlib.h>  #  include <stdlib.h>
129  #  include <string.h>  #  include <string.h>
130  # else  # else /* no standard C headers */
131      extern char *getenv ();      extern char *getenv ();
132    #  ifdef VMS
133    #   define EXIT_SUCCESS 1
134    #   define EXIT_FAILURE 0
135    #  else /* no VMS */
136    #   define EXIT_SUCCESS 0
137    #   define EXIT_FAILURE 1
138    #  endif
139  # endif  # endif
140  #endif /* !WINDOWSNT */  #endif /* !WINDOWSNT */
141    
# Line 333  static void Erlang_functions __P((FILE * Line 345  static void Erlang_functions __P((FILE *
345  static void Fortran_functions __P((FILE *));  static void Fortran_functions __P((FILE *));
346  static void HTML_labels __P((FILE *));  static void HTML_labels __P((FILE *));
347  static void Lisp_functions __P((FILE *));  static void Lisp_functions __P((FILE *));
348    static void Lua_functions __P((FILE *));
349  static void Makefile_targets __P((FILE *));  static void Makefile_targets __P((FILE *));
350  static void Pascal_functions __P((FILE *));  static void Pascal_functions __P((FILE *));
351  static void Perl_functions __P((FILE *));  static void Perl_functions __P((FILE *));
# Line 637  defined with `defvar' or `defconst', and Line 650  defined with `defvar' or `defconst', and
650  argument of any expression that starts with `(def' in column zero\n\  argument of any expression that starts with `(def' in column zero\n\
651  is a tag.";  is a tag.";
652    
653    static char *Lua_suffixes [] =
654      { "lua", "LUA", NULL };
655    static char Lua_help [] =
656    "In Lua scripts, all functions are tags.";
657    
658  static char *Makefile_filenames [] =  static char *Makefile_filenames [] =
659    { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};    { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};
660  static char Makefile_help [] =  static char Makefile_help [] =
# Line 763  static language lang_names [] = Line 781  static language lang_names [] =
781    { "html",      HTML_help,      HTML_labels,       HTML_suffixes      },    { "html",      HTML_help,      HTML_labels,       HTML_suffixes      },
782    { "java",      Cjava_help,     Cjava_entries,     Cjava_suffixes     },    { "java",      Cjava_help,     Cjava_entries,     Cjava_suffixes     },
783    { "lisp",      Lisp_help,      Lisp_functions,    Lisp_suffixes      },    { "lisp",      Lisp_help,      Lisp_functions,    Lisp_suffixes      },
784      { "lua",       Lua_help,       Lua_functions,     Lua_suffixes       },
785    { "makefile",  Makefile_help,Makefile_targets,NULL,Makefile_filenames},    { "makefile",  Makefile_help,Makefile_targets,NULL,Makefile_filenames},
786    { "objc",      Objc_help,      plain_C_entries,   Objc_suffixes      },    { "objc",      Objc_help,      plain_C_entries,   Objc_suffixes      },
787    { "pascal",    Pascal_help,    Pascal_functions,  Pascal_suffixes    },    { "pascal",    Pascal_help,    Pascal_functions,  Pascal_suffixes    },
# Line 1295  main (argc, argv) Line 1314  main (argc, argv)
1314        cwd = concat (oldcwd, "/", "");        cwd = concat (oldcwd, "/", "");
1315        free (oldcwd);        free (oldcwd);
1316      }      }
1317    if (streq (tagfile, "-"))    /* Relative file names are made relative to the current directory. */
1318      if (streq (tagfile, "-")
1319          || strneq (tagfile, "/dev/", 5))
1320      tagfiledir = cwd;      tagfiledir = cwd;
1321    else    else
1322      tagfiledir = absolute_dirname (tagfile, cwd);      tagfiledir = absolute_dirname (tagfile, cwd);
# Line 2373  enum sym_type Line 2394  enum sym_type
2394    st_none,    st_none,
2395    st_C_objprot, st_C_objimpl, st_C_objend,    st_C_objprot, st_C_objimpl, st_C_objend,
2396    st_C_gnumacro,    st_C_gnumacro,
2397    st_C_ignore,    st_C_ignore, st_C_attribute,
2398    st_C_javastruct,    st_C_javastruct,
2399    st_C_operator,    st_C_operator,
2400    st_C_class, st_C_template,    st_C_class, st_C_template,
2401    st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec    st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef
2402  };  };
2403    
2404  static unsigned int hash __P((const char *, unsigned int));  static unsigned int hash __P((const char *, unsigned int));
# Line 2385  static struct C_stab_entry * in_word_set Line 2406  static struct C_stab_entry * in_word_set
2406  static enum sym_type C_symtype __P((char *, int, int));  static enum sym_type C_symtype __P((char *, int, int));
2407    
2408  /* Feed stuff between (but not including) %[ and %] lines to:  /* Feed stuff between (but not including) %[ and %] lines to:
2409        gperf -c -k 1,3 -o -p -r -t       gperf -m 5
2410  %[  %[
2411    %compare-strncmp
2412    %enum
2413    %struct-type
2414  struct C_stab_entry { char *name; int c_ext; enum sym_type type; }  struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2415  %%  %%
2416  if,             0,      st_C_ignore  if,             0,                      st_C_ignore
2417  for,            0,      st_C_ignore  for,            0,                      st_C_ignore
2418  while,          0,      st_C_ignore  while,          0,                      st_C_ignore
2419  switch,         0,      st_C_ignore  switch,         0,                      st_C_ignore
2420  return,         0,      st_C_ignore  return,         0,                      st_C_ignore
2421  @interface,     0,      st_C_objprot  __attribute__,  0,                      st_C_attribute
2422  @protocol,      0,      st_C_objprot  @interface,     0,                      st_C_objprot
2423  @implementation,0,      st_C_objimpl  @protocol,      0,                      st_C_objprot
2424  @end,           0,      st_C_objend  @implementation,0,                      st_C_objimpl
2425  import,         C_JAVA, st_C_ignore  @end,           0,                      st_C_objend
2426  package,        C_JAVA, st_C_ignore  import,         (C_JAVA & !C_PLPL),     st_C_ignore
2427  friend,         C_PLPL, st_C_ignore  package,        (C_JAVA & !C_PLPL),     st_C_ignore
2428  extends,        C_JAVA, st_C_javastruct  friend,         C_PLPL,                 st_C_ignore
2429  implements,     C_JAVA, st_C_javastruct  extends,        (C_JAVA & !C_PLPL),     st_C_javastruct
2430  interface,      C_JAVA, st_C_struct  implements,     (C_JAVA & !C_PLPL),     st_C_javastruct
2431  class,          0,      st_C_class  interface,      (C_JAVA & !C_PLPL),     st_C_struct
2432  namespace,      C_PLPL, st_C_struct  class,          0,                      st_C_class
2433  domain,         C_STAR, st_C_struct  namespace,      C_PLPL,                 st_C_struct
2434  union,          0,      st_C_struct  domain,         C_STAR,                 st_C_struct
2435  struct,         0,      st_C_struct  union,          0,                      st_C_struct
2436  extern,         0,      st_C_extern  struct,         0,                      st_C_struct
2437  enum,           0,      st_C_enum  extern,         0,                      st_C_extern
2438  typedef,        0,      st_C_typedef  enum,           0,                      st_C_enum
2439  define,         0,      st_C_define  typedef,        0,                      st_C_typedef
2440  operator,       C_PLPL, st_C_operator  define,         0,                      st_C_define
2441  template,       0,      st_C_template  operator,       C_PLPL,                 st_C_operator
2442  bool,           C_PLPL, st_C_typespec  template,       0,                      st_C_template
 long,           0,      st_C_typespec  
 short,          0,      st_C_typespec  
 int,            0,      st_C_typespec  
 char,           0,      st_C_typespec  
 float,          0,      st_C_typespec  
 double,         0,      st_C_typespec  
 signed,         0,      st_C_typespec  
 unsigned,       0,      st_C_typespec  
 auto,           0,      st_C_typespec  
 void,           0,      st_C_typespec  
 static,         0,      st_C_typespec  
 const,          0,      st_C_typespec  
 volatile,       0,      st_C_typespec  
 explicit,       C_PLPL, st_C_typespec  
 mutable,        C_PLPL, st_C_typespec  
 typename,       C_PLPL, st_C_typespec  
2443  # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).  # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2444  DEFUN,          0,      st_C_gnumacro  DEFUN,          0,                      st_C_gnumacro
2445  SYSCALL,        0,      st_C_gnumacro  SYSCALL,        0,                      st_C_gnumacro
2446  ENTRY,          0,      st_C_gnumacro  ENTRY,          0,                      st_C_gnumacro
2447  PSEUDO,         0,      st_C_gnumacro  PSEUDO,         0,                      st_C_gnumacro
2448  # These are defined inside C functions, so currently they are not met.  # These are defined inside C functions, so currently they are not met.
2449  # EXFUN used in glibc, DEFVAR_* in emacs.  # EXFUN used in glibc, DEFVAR_* in emacs.
2450  #EXFUN,         0,      st_C_gnumacro  #EXFUN,         0,                      st_C_gnumacro
2451  #DEFVAR_,       0,      st_C_gnumacro  #DEFVAR_,       0,                      st_C_gnumacro
2452  %]  %]
2453  and replace lines between %< and %> with its output,  and replace lines between %< and %> with its output, then:
2454  then make in_word_set and C_stab_entry static. */   - remove the #if characterset check
2455     - make in_word_set static and not inline. */
2456  /*%<*/  /*%<*/
2457  /* C code produced by gperf version 2.7.1 (19981006 egcs) */  /* C code produced by gperf version 3.0.1 */
2458  /* Command-line: gperf -c -k 1,3 -o -p -r -t  */  /* Command-line: gperf -m 5  */
2459  struct C_stab_entry { char *name; int c_ext; enum sym_type type; };  /* Computed positions: -k'1-2' */
2460    
2461  #define TOTAL_KEYWORDS 47  struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
2462  #define MIN_WORD_LENGTH 2  /* maximum key range = 31, duplicates = 0 */
 #define MAX_WORD_LENGTH 15  
 #define MIN_HASH_VALUE 18  
 #define MAX_HASH_VALUE 138  
 /* maximum key range = 121, duplicates = 0 */  
2463    
2464  #ifdef __GNUC__  #ifdef __GNUC__
2465  __inline  __inline
2466    #else
2467    #ifdef __cplusplus
2468    inline
2469    #endif
2470  #endif  #endif
2471  static unsigned int  static unsigned int
2472  hash (str, len)  hash (str, len)
# Line 2466  hash (str, len) Line 2475  hash (str, len)
2475  {  {
2476    static unsigned char asso_values[] =    static unsigned char asso_values[] =
2477      {      {
2478        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2479        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2480        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2481        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2482        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2483        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2484        139, 139, 139, 139,  63, 139, 139, 139,  33,  44,        34, 34, 34, 34,  1, 34, 34, 34, 14, 14,
2485         62, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 13, 34,
2486         42, 139, 139,  12,  32, 139, 139, 139, 139, 139,        13, 34, 34, 12, 34, 34, 34, 34, 34, 11,
2487        139, 139, 139, 139, 139, 139, 139,  34,  59,  37,        34, 34, 34, 34, 34,  8, 34, 11, 34, 12,
2488         24,  58,  33,   3, 139,  16, 139, 139,  42,  60,        11,  0,  1, 34,  7,  0, 34, 34, 11,  9,
2489         18,  11,  39, 139,  23,  57,   4,  63,   6,  20,         0,  4,  0, 34,  7,  4, 14, 21, 34, 15,
2490        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,         0,  2, 34, 34, 34, 34, 34, 34, 34, 34,
2491        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2492        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2493        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2494        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2495        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2496        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2497        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2498        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2499        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2500        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2501        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2502        139, 139, 139, 139, 139, 139, 139, 139, 139, 139,        34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2503        139, 139, 139, 139, 139, 139        34, 34, 34, 34, 34, 34
2504      };      };
2505    register int hval = len;    return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]];
   
   switch (hval)  
     {  
       default:  
       case 3:  
         hval += asso_values[(unsigned char)str[2]];  
       case 2:  
       case 1:  
         hval += asso_values[(unsigned char)str[0]];  
         break;  
     }  
   return hval;  
2506  }  }
2507    
 #ifdef __GNUC__  
 __inline  
 #endif  
2508  static struct C_stab_entry *  static struct C_stab_entry *
2509  in_word_set (str, len)  in_word_set (str, len)
2510       register const char *str;       register const char *str;
2511       register unsigned int len;       register unsigned int len;
2512  {  {
2513      enum
2514        {
2515          TOTAL_KEYWORDS = 31,
2516          MIN_WORD_LENGTH = 2,
2517          MAX_WORD_LENGTH = 15,
2518          MIN_HASH_VALUE = 3,
2519          MAX_HASH_VALUE = 33
2520        };
2521    
2522    static struct C_stab_entry wordlist[] =    static struct C_stab_entry wordlist[] =
2523      {      {
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {"if",            0,      st_C_ignore},  
       {""}, {""}, {""}, {""},  
       {"int",           0,      st_C_typespec},  
       {""}, {""},  
       {"void",          0,      st_C_typespec},  
       {""}, {""},  
       {"interface",     C_JAVA, st_C_struct},  
       {""},  
       {"SYSCALL",       0,      st_C_gnumacro},  
       {""},  
       {"return",                0,      st_C_ignore},  
       {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {"while",         0,      st_C_ignore},  
       {"auto",          0,      st_C_typespec},  
       {""}, {""}, {""}, {""}, {""}, {""},  
       {"float",         0,      st_C_typespec},  
       {"typedef",       0,      st_C_typedef},  
       {"typename",      C_PLPL, st_C_typespec},  
2524        {""}, {""}, {""},        {""}, {""}, {""},
2525        {"friend",                C_PLPL, st_C_ignore},        {"if",            0,                      st_C_ignore},
2526        {"volatile",      0,      st_C_typespec},        {"enum",          0,                      st_C_enum},
2527        {""}, {""},        {"@end",          0,                      st_C_objend},
2528        {"for",           0,      st_C_ignore},        {"extern",                0,                      st_C_extern},
2529        {"const",         0,      st_C_typespec},        {"extends",       (C_JAVA & !C_PLPL),     st_C_javastruct},
2530        {"import",                C_JAVA, st_C_ignore},        {"for",           0,                      st_C_ignore},
2531        {""},        {"interface",     (C_JAVA & !C_PLPL),     st_C_struct},
2532        {"define",        0,      st_C_define},        {"@protocol",     0,                      st_C_objprot},
2533        {"long",          0,      st_C_typespec},        {"@interface",    0,                      st_C_objprot},
2534        {"implements",    C_JAVA, st_C_javastruct},        {"operator",      C_PLPL,                 st_C_operator},
2535        {"signed",        0,      st_C_typespec},        {"return",                0,                      st_C_ignore},
2536        {""},        {"friend",                C_PLPL,                 st_C_ignore},
2537        {"extern",        0,      st_C_extern},        {"import",                (C_JAVA & !C_PLPL),     st_C_ignore},
2538        {"extends",       C_JAVA, st_C_javastruct},        {"@implementation",0,                     st_C_objimpl},
2539        {""},        {"define",                0,                      st_C_define},
2540        {"mutable",       C_PLPL, st_C_typespec},        {"package",       (C_JAVA & !C_PLPL),     st_C_ignore},
2541        {"template",      0,      st_C_template},        {"implements",    (C_JAVA & !C_PLPL),     st_C_javastruct},
2542        {"short",         0,      st_C_typespec},        {"namespace",     C_PLPL,                 st_C_struct},
2543        {"bool",          C_PLPL, st_C_typespec},        {"domain",                C_STAR,                 st_C_struct},
2544        {"char",          0,      st_C_typespec},        {"template",      0,                      st_C_template},
2545        {"class",         0,      st_C_class},        {"typedef",       0,                      st_C_typedef},
2546        {"operator",      C_PLPL, st_C_operator},        {"struct",                0,                      st_C_struct},
2547        {""},        {"switch",                0,                      st_C_ignore},
2548        {"switch",                0,      st_C_ignore},        {"union",         0,                      st_C_struct},
2549        {""},        {"while",         0,                      st_C_ignore},
2550        {"ENTRY",         0,      st_C_gnumacro},        {"class",         0,                      st_C_class},
2551        {""},        {"__attribute__", 0,                      st_C_attribute},
2552        {"package",       C_JAVA, st_C_ignore},        {"SYSCALL",       0,                      st_C_gnumacro},
2553        {"union",         0,      st_C_struct},        {"PSEUDO",                0,                      st_C_gnumacro},
2554        {"@end",          0,      st_C_objend},        {"ENTRY",         0,                      st_C_gnumacro},
2555        {"struct",        0,      st_C_struct},        {"DEFUN",         0,                      st_C_gnumacro}
       {"namespace",     C_PLPL, st_C_struct},  
       {""}, {""},  
       {"domain",        C_STAR, st_C_struct},  
       {"@interface",    0,      st_C_objprot},  
       {"PSEUDO",                0,      st_C_gnumacro},  
       {"double",        0,      st_C_typespec},  
       {""},  
       {"@protocol",     0,      st_C_objprot},  
       {""},  
       {"static",        0,      st_C_typespec},  
       {""}, {""},  
       {"DEFUN",         0,      st_C_gnumacro},  
       {""}, {""}, {""}, {""},  
       {"explicit",      C_PLPL, st_C_typespec},  
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {""},  
       {"enum",          0,      st_C_enum},  
       {""}, {""},  
       {"unsigned",      0,      st_C_typespec},  
       {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},  
       {"@implementation",0,     st_C_objimpl}  
2556      };      };
2557    
2558    if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)    if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
# Line 2602  in_word_set (str, len) Line 2563  in_word_set (str, len)
2563          {          {
2564            register const char *s = wordlist[key].name;            register const char *s = wordlist[key].name;
2565    
2566            if (*str == *s && !strncmp (str + 1, s + 1, len - 1))            if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
2567              return &wordlist[key];              return &wordlist[key];
2568          }          }
2569      }      }
# Line 2625  C_symtype (str, len, c_ext) Line 2586  C_symtype (str, len, c_ext)
2586    
2587    
2588  /*  /*
2589     * Ignoring __attribute__ ((list))
2590     */
2591    static bool inattribute;        /* looking at an __attribute__ construct */
2592    
2593    /*
2594   * C functions and variables are recognized using a simple   * C functions and variables are recognized using a simple
2595   * finite automaton.  fvdef is its state variable.   * finite automaton.  fvdef is its state variable.
2596   */   */
# Line 2666  static enum Line 2632  static enum
2632  static enum  static enum
2633  {  {
2634    snone,                        /* nothing seen yet,    snone,                        /* nothing seen yet,
2635                                     or in struct body if cblev > 0 */                                     or in struct body if bracelev > 0 */
2636    skeyseen,                     /* struct-like keyword seen */    skeyseen,                     /* struct-like keyword seen */
2637    stagseen,                     /* struct-like tag seen */    stagseen,                     /* struct-like tag seen */
   sintemplate,                  /* inside template (ignore) */  
2638    scolonseen                    /* colon seen after struct-like tag */    scolonseen                    /* colon seen after struct-like tag */
2639  } structdef;  } structdef;
2640    
# Line 2743  static void write_classname __P((linebuf Line 2708  static void write_classname __P((linebuf
2708    
2709  static struct {  static struct {
2710    char **cname;                 /* nested class names */    char **cname;                 /* nested class names */
2711    int *cblev;                   /* nested class curly brace level */    int *bracelev;                /* nested class brace level */
2712    int nl;                       /* class nesting level (elements used) */    int nl;                       /* class nesting level (elements used) */
2713    int size;                     /* length of the array */    int size;                     /* length of the array */
2714  } cstack;                       /* stack for nested declaration tags */  } cstack;                       /* stack for nested declaration tags */
# Line 2751  static struct { Line 2716  static struct {
2716  #define nestlev         (cstack.nl)  #define nestlev         (cstack.nl)
2717  /* After struct keyword or in struct body, not inside a nested function. */  /* After struct keyword or in struct body, not inside a nested function. */
2718  #define instruct        (structdef == snone && nestlev > 0                      \  #define instruct        (structdef == snone && nestlev > 0                      \
2719                           && cblev == cstack.cblev[nestlev-1] + 1)                           && bracelev == cstack.bracelev[nestlev-1] + 1)
2720    
2721  static void  static void
2722  pushclass_above (cblev, str, len)  pushclass_above (bracelev, str, len)
2723       int cblev;       int bracelev;
2724       char *str;       char *str;
2725       int len;       int len;
2726  {  {
2727    int nl;    int nl;
2728    
2729    popclass_above (cblev);    popclass_above (bracelev);
2730    nl = cstack.nl;    nl = cstack.nl;
2731    if (nl >= cstack.size)    if (nl >= cstack.size)
2732      {      {
2733        int size = cstack.size *= 2;        int size = cstack.size *= 2;
2734        xrnew (cstack.cname, size, char *);        xrnew (cstack.cname, size, char *);
2735        xrnew (cstack.cblev, size, int);        xrnew (cstack.bracelev, size, int);
2736      }      }
2737    assert (nl == 0 || cstack.cblev[nl-1] < cblev);    assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
2738    cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);    cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
2739    cstack.cblev[nl] = cblev;    cstack.bracelev[nl] = bracelev;
2740    cstack.nl = nl + 1;    cstack.nl = nl + 1;
2741  }  }
2742    
2743  static void  static void
2744  popclass_above (cblev)  popclass_above (bracelev)
2745       int cblev;       int bracelev;
2746  {  {
2747    int nl;    int nl;
2748    
2749    for (nl = cstack.nl - 1;    for (nl = cstack.nl - 1;
2750         nl >= 0 && cstack.cblev[nl] >= cblev;         nl >= 0 && cstack.bracelev[nl] >= bracelev;
2751         nl--)         nl--)
2752      {      {
2753        if (cstack.cname[nl] != NULL)        if (cstack.cname[nl] != NULL)
# Line 2849  static void make_C_tag __P((bool)); Line 2814  static void make_C_tag __P((bool));
2814   */   */
2815    
2816  static bool  static bool
2817  consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var)  consider_token (str, len, c, c_extp, bracelev, parlev, is_func_or_var)
2818       register char *str;        /* IN: token pointer */       register char *str;        /* IN: token pointer */
2819       register int len;          /* IN: token length */       register int len;          /* IN: token length */
2820       register int c;            /* IN: first char after the token */       register int c;            /* IN: first char after the token */
2821       int *c_extp;               /* IN, OUT: C extensions mask */       int *c_extp;               /* IN, OUT: C extensions mask */
2822       int cblev;                 /* IN: curly brace level */       int bracelev;              /* IN: brace level */
2823       int parlev;                /* IN: parenthesis level */       int parlev;                /* IN: parenthesis level */
2824       bool *is_func_or_var;      /* OUT: function or variable found */       bool *is_func_or_var;      /* OUT: function or variable found */
2825  {  {
2826    /* When structdef is stagseen, scolonseen, or snone with cblev > 0,    /* When structdef is stagseen, scolonseen, or snone with bracelev > 0,
2827       structtype is the type of the preceding struct-like keyword, and       structtype is the type of the preceding struct-like keyword, and
2828       structcblev is the curly brace level where it has been seen. */       structbracelev is the brace level where it has been seen. */
2829    static enum sym_type structtype;    static enum sym_type structtype;
2830    static int structcblev;    static int structbracelev;
2831    static enum sym_type toktype;    static enum sym_type toktype;
2832    
2833    
2834    toktype = C_symtype (str, len, *c_extp);    toktype = C_symtype (str, len, *c_extp);
2835    
2836    /*    /*
2837     * Advance the definedef state machine.     * Skip __attribute__
    */  
   switch (definedef)  
     {  
     case dnone:  
       /* We're not on a preprocessor line. */  
       if (toktype == st_C_gnumacro)  
         {  
           fvdef = fdefunkey;  
           return FALSE;  
         }  
       break;  
     case dsharpseen:  
       if (toktype == st_C_define)  
         {  
           definedef = ddefineseen;  
         }  
       else  
         {  
           definedef = dignorerest;  
         }  
       return FALSE;  
     case ddefineseen:  
       /*  
        * Make a tag for any macro, unless it is a constant  
        * and constantypedefs is FALSE.  
        */  
       definedef = dignorerest;  
       *is_func_or_var = (c == '(');  
       if (!*is_func_or_var && !constantypedefs)  
         return FALSE;  
       else  
         return TRUE;  
     case dignorerest:  
       return FALSE;  
     default:  
       error ("internal error: definedef value.", (char *)NULL);  
     }  
   
   /*  
    * Now typedefs  
    */  
   switch (typdef)  
     {  
     case tnone:  
       if (toktype == st_C_typedef)  
         {  
           if (typedefs)  
             typdef = tkeyseen;  
           fvextern = FALSE;  
           fvdef = fvnone;  
           return FALSE;  
         }  
       break;  
     case tkeyseen:  
       switch (toktype)  
         {  
         case st_none:  
         case st_C_typespec:  
         case st_C_class:  
         case st_C_struct:  
         case st_C_enum:  
           typdef = ttypeseen;  
           break;  
         }  
       break;  
     case ttypeseen:  
       if (structdef == snone && fvdef == fvnone)  
         {  
           fvdef = fvnameseen;  
           return TRUE;  
         }  
       break;  
     case tend:  
       switch (toktype)  
         {  
         case st_C_typespec:  
         case st_C_class:  
         case st_C_struct:  
         case st_C_enum:  
           return FALSE;  
         }  
       return TRUE;  
     }  
   
   /*  
    * This structdef business is NOT invoked when we are ctags and the  
    * file is plain C.  This is because a struct tag may have the same  
    * name as another tag, and this loses with ctags.  
2838     */     */
2839    switch (toktype)    if (toktype == st_C_attribute)
     {  
     case st_C_javastruct:  
       if (structdef == stagseen)  
         structdef = scolonseen;  
       return FALSE;  
     case st_C_template:  
     case st_C_class:  
       if ((*c_extp & C_AUTO)    /* automatic detection of C++ language */  
           && cblev == 0  
           && definedef == dnone && structdef == snone  
           && typdef == tnone && fvdef == fvnone)  
         *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;  
       if (toktype == st_C_template)  
         break;  
       /* FALLTHRU */  
     case st_C_struct:  
     case st_C_enum:  
       if (parlev == 0  
           && fvdef != vignore  
           && (typdef == tkeyseen  
               || (typedefs_or_cplusplus && structdef == snone)))  
         {  
           structdef = skeyseen;  
           structtype = toktype;  
           structcblev = cblev;  
         }  
       return FALSE;  
     }  
   
   if (structdef == skeyseen)  
     {  
       structdef = stagseen;  
       return TRUE;  
     }  
   
   if (typdef != tnone)  
     definedef = dnone;  
   
   /* Detect Objective C constructs. */  
   switch (objdef)  
2840      {      {
2841      case onone:        inattribute = TRUE;
       switch (toktype)  
         {  
         case st_C_objprot:  
           objdef = oprotocol;  
           return FALSE;  
         case st_C_objimpl:  
           objdef = oimplementation;  
           return FALSE;  
         }  
       break;  
     case oimplementation:  
       /* Save the class tag for functions or variables defined inside. */  
       objtag = savenstr (str, len);  
       objdef = oinbody;  
       return FALSE;  
     case oprotocol:  
       /* Save the class tag for categories. */  
       objtag = savenstr (str, len);  
       objdef = otagseen;  
       *is_func_or_var = TRUE;  
       return TRUE;  
     case oparenseen:  
       objdef = ocatseen;  
       *is_func_or_var = TRUE;  
       return TRUE;  
     case oinbody:  
       break;  
     case omethodsign:  
       if (parlev == 0)  
         {  
           objdef = omethodtag;  
           linebuffer_setlen (&token_name, len);  
           strncpy (token_name.buffer, str, len);  
           token_name.buffer[len] = '\0';  
           return TRUE;  
         }  
       return FALSE;  
     case omethodcolon:  
       if (parlev == 0)  
         objdef = omethodparm;  
       return FALSE;  
     case omethodparm:  
       if (parlev == 0)  
         {  
           objdef = omethodtag;  
           linebuffer_setlen (&token_name, token_name.len + len);  
           strncat (token_name.buffer, str, len);  
           return TRUE;  
         }  
2842        return FALSE;        return FALSE;
2843      case oignore:       }
       if (toktype == st_C_objend)  
         {  
           /* Memory leakage here: the string pointed by objtag is  
              never released, because many tests would be needed to  
              avoid breaking on incorrect input code.  The amount of  
              memory leaked here is the sum of the lengths of the  
              class tags.  
           free (objtag); */  
           objdef = onone;  
         }  
       return FALSE;  
     }  
2844    
2845    /* A function, variable or enum constant? */     /*
2846    switch (toktype)      * Advance the definedef state machine.
2847      {      */
2848      case st_C_extern:     switch (definedef)
2849        fvextern = TRUE;       {
2850        /* FALLTHRU */       case dnone:
2851      case st_C_typespec:         /* We're not on a preprocessor line. */
2852        switch  (fvdef)         if (toktype == st_C_gnumacro)
2853          {           {
2854          case finlist:             fvdef = fdefunkey;
2855          case flistseen:             return FALSE;
2856          case fignore:           }
2857          case vignore:         break;
2858            break;       case dsharpseen:
2859          default:         if (toktype == st_C_define)
2860            fvdef = fvnone;           {
2861          }             definedef = ddefineseen;
2862        return FALSE;           }
2863      case st_C_ignore:         else
2864        fvextern = FALSE;           {
2865        fvdef = vignore;             definedef = dignorerest;
2866        return FALSE;           }
2867      case st_C_operator:         return FALSE;
2868        fvdef = foperator;       case ddefineseen:
2869        *is_func_or_var = TRUE;         /*
2870        return TRUE;          * Make a tag for any macro, unless it is a constant
2871      case st_none:          * and constantypedefs is FALSE.
2872        if (constantypedefs          */
2873            && structdef == snone         definedef = dignorerest;
2874            && structtype == st_C_enum && cblev > structcblev)         *is_func_or_var = (c == '(');
2875          return TRUE;            /* enum constant */         if (!*is_func_or_var && !constantypedefs)
2876        switch (fvdef)           return FALSE;
2877          {         else
2878          case fdefunkey:           return TRUE;
2879            if (cblev > 0)       case dignorerest:
2880              break;         return FALSE;
2881            fvdef = fdefunname;   /* GNU macro */       default:
2882            *is_func_or_var = TRUE;         error ("internal error: definedef value.", (char *)NULL);
2883            return TRUE;       }
2884          case fvnone:  
2885            if ((strneq (str, "asm", 3) && endtoken (str[3]))     /*
2886                || (strneq (str, "__asm__", 7) && endtoken (str[7])))      * Now typedefs
2887              {      */
2888                fvdef = vignore;     switch (typdef)
2889                return FALSE;       {
2890              }       case tnone:
2891           if (toktype == st_C_typedef)
2892             {
2893               if (typedefs)
2894                 typdef = tkeyseen;
2895               fvextern = FALSE;
2896               fvdef = fvnone;
2897               return FALSE;
2898             }
2899           break;
2900         case tkeyseen:
2901           switch (toktype)
2902             {
2903             case st_none:
2904             case st_C_class:
2905             case st_C_struct:
2906             case st_C_enum:
2907               typdef = ttypeseen;
2908             }
2909           break;
2910         case ttypeseen:
2911           if (structdef == snone && fvdef == fvnone)
2912             {
2913               fvdef = fvnameseen;
2914               return TRUE;
2915             }
2916           break;
2917         case tend:
2918           switch (toktype)
2919             {
2920             case st_C_class:
2921             case st_C_struct:
2922             case st_C_enum:
2923               return FALSE;
2924             }
2925           return TRUE;
2926         }
2927    
2928       /*
2929        * This structdef business is NOT invoked when we are ctags and the
2930        * file is plain C.  This is because a struct tag may have the same
2931        * name as another tag, and this loses with ctags.
2932        */
2933       switch (toktype)
2934         {
2935         case st_C_javastruct:
2936           if (structdef == stagseen)
2937             structdef = scolonseen;
2938           return FALSE;
2939         case st_C_template:
2940         case st_C_class:
2941           if ((*c_extp & C_AUTO)   /* automatic detection of C++ language */
2942               && bracelev == 0
2943               && definedef == dnone && structdef == snone
2944               && typdef == tnone && fvdef == fvnone)
2945             *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
2946           if (toktype == st_C_template)
2947             break;
2948           /* FALLTHRU */
2949         case st_C_struct:
2950         case st_C_enum:
2951           if (parlev == 0
2952               && fvdef != vignore
2953               && (typdef == tkeyseen
2954                   || (typedefs_or_cplusplus && structdef == snone)))
2955             {
2956               structdef = skeyseen;
2957               structtype = toktype;
2958               structbracelev = bracelev;
2959               if (fvdef == fvnameseen)
2960                 fvdef = fvnone;
2961             }
2962           return FALSE;
2963         }
2964    
2965       if (structdef == skeyseen)
2966         {
2967           structdef = stagseen;
2968           return TRUE;
2969         }
2970    
2971       if (typdef != tnone)
2972         definedef = dnone;
2973    
2974       /* Detect Objective C constructs. */
2975       switch (objdef)
2976         {
2977         case onone:
2978           switch (toktype)
2979             {
2980             case st_C_objprot:
2981               objdef = oprotocol;
2982               return FALSE;
2983             case st_C_objimpl:
2984               objdef = oimplementation;
2985               return FALSE;
2986             }
2987           break;
2988         case oimplementation:
2989           /* Save the class tag for functions or variables defined inside. */
2990           objtag = savenstr (str, len);
2991           objdef = oinbody;
2992           return FALSE;
2993         case oprotocol:
2994           /* Save the class tag for categories. */
2995           objtag = savenstr (str, len);
2996           objdef = otagseen;
2997           *is_func_or_var = TRUE;
2998           return TRUE;
2999         case oparenseen:
3000           objdef = ocatseen;
3001           *is_func_or_var = TRUE;
3002           return TRUE;
3003         case oinbody:
3004           break;
3005         case omethodsign:
3006           if (parlev == 0)
3007             {
3008               fvdef = fvnone;
3009               objdef = omethodtag;
3010               linebuffer_setlen (&token_name, len);
3011               strncpy (token_name.buffer, str, len);
3012               token_name.buffer[len] = '\0';
3013               return TRUE;
3014             }
3015           return FALSE;
3016         case omethodcolon:
3017           if (parlev == 0)
3018             objdef = omethodparm;
3019           return FALSE;
3020         case omethodparm:
3021           if (parlev == 0)
3022             {
3023               fvdef = fvnone;
3024               objdef = omethodtag;
3025               linebuffer_setlen (&token_name, token_name.len + len);
3026               strncat (token_name.buffer, str, len);
3027               return TRUE;
3028             }
3029           return FALSE;
3030         case oignore:
3031           if (toktype == st_C_objend)
3032             {
3033               /* Memory leakage here: the string pointed by objtag is
3034                  never released, because many tests would be needed to
3035                  avoid breaking on incorrect input code.  The amount of
3036                  memory leaked here is the sum of the lengths of the
3037                  class tags.
3038               free (objtag); */
3039               objdef = onone;
3040             }
3041           return FALSE;
3042         }
3043    
3044       /* A function, variable or enum constant? */
3045       switch (toktype)
3046         {
3047         case st_C_extern:
3048           fvextern = TRUE;
3049           switch  (fvdef)
3050             {
3051             case finlist:
3052             case flistseen:
3053             case fignore:
3054             case vignore:
3055               break;
3056             default:
3057               fvdef = fvnone;
3058             }
3059           return FALSE;
3060         case st_C_ignore:
3061           fvextern = FALSE;
3062           fvdef = vignore;
3063           return FALSE;
3064         case st_C_operator:
3065           fvdef = foperator;
3066           *is_func_or_var = TRUE;
3067           return TRUE;
3068         case st_none:
3069           if (constantypedefs
3070               && structdef == snone
3071               && structtype == st_C_enum && bracelev > structbracelev)
3072             return TRUE;           /* enum constant */
3073           switch (fvdef)
3074             {
3075             case fdefunkey:
3076               if (bracelev > 0)
3077                 break;
3078               fvdef = fdefunname;  /* GNU macro */
3079               *is_func_or_var = TRUE;
3080               return TRUE;
3081             case fvnone:
3082               switch (typdef)
3083                 {
3084                 case ttypeseen:
3085                   return FALSE;
3086                 case tnone:
3087                   if ((strneq (str, "asm", 3) && endtoken (str[3]))
3088                       || (strneq (str, "__asm__", 7) && endtoken (str[7])))
3089                     {
3090                       fvdef = vignore;
3091                       return FALSE;
3092                     }
3093                   break;
3094                 }
3095              /* FALLTHRU */
3096              case fvnameseen:
3097            if (len >= 10 && strneq (str+len-10, "::operator", 10))            if (len >= 10 && strneq (str+len-10, "::operator", 10))
3098              {              {
3099                if (*c_extp & C_AUTO) /* automatic detection of C++ */                if (*c_extp & C_AUTO) /* automatic detection of C++ */
# Line 3120  consider_token (str, len, c, c_extp, cbl Line 3102  consider_token (str, len, c, c_extp, cbl
3102                *is_func_or_var = TRUE;                *is_func_or_var = TRUE;
3103                return TRUE;                return TRUE;
3104              }              }
3105            if (cblev > 0 && !instruct)            if (bracelev > 0 && !instruct)
3106              break;              break;
3107            fvdef = fvnameseen;   /* function or variable */            fvdef = fvnameseen;   /* function or variable */
3108            *is_func_or_var = TRUE;            *is_func_or_var = TRUE;
# Line 3216  C_entries (c_ext, inf) Line 3198  C_entries (c_ext, inf)
3198    register int toklen;          /* length of current token */    register int toklen;          /* length of current token */
3199    char *qualifier;              /* string used to qualify names */    char *qualifier;              /* string used to qualify names */
3200    int qlen;                     /* length of qualifier */    int qlen;                     /* length of qualifier */
3201    int cblev;                    /* current curly brace level */    int bracelev;                 /* current brace level */
3202      int bracketlev;               /* current bracket level */
3203    int parlev;                   /* current parenthesis level */    int parlev;                   /* current parenthesis level */
3204    int typdefcblev;              /* cblev where a typedef struct body begun */    int attrparlev;               /* __attribute__ parenthesis level */
3205      int templatelev;              /* current template level */
3206      int typdefbracelev;           /* bracelev where a typedef struct body begun */
3207    bool incomm, inquote, inchar, quotednl, midtoken;    bool incomm, inquote, inchar, quotednl, midtoken;
3208    bool yacc_rules;              /* in the rules part of a yacc file */    bool yacc_rules;              /* in the rules part of a yacc file */
3209    struct tok savetoken;         /* token saved during preprocessor handling */    struct tok savetoken;         /* token saved during preprocessor handling */
# Line 3231  C_entries (c_ext, inf) Line 3216  C_entries (c_ext, inf)
3216        cstack.size = (DEBUG) ? 1 : 4;        cstack.size = (DEBUG) ? 1 : 4;
3217        cstack.nl = 0;        cstack.nl = 0;
3218        cstack.cname = xnew (cstack.size, char *);        cstack.cname = xnew (cstack.size, char *);
3219        cstack.cblev = xnew (cstack.size, int);        cstack.bracelev = xnew (cstack.size, int);
3220      }      }
3221    
3222    tokoff = toklen = typdefcblev = 0; /* keep compiler quiet */    tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */
3223    curndx = newndx = 0;    curndx = newndx = 0;
3224    lp = curlb.buffer;    lp = curlb.buffer;
3225    *lp = 0;    *lp = 0;
# Line 3244  C_entries (c_ext, inf) Line 3229  C_entries (c_ext, inf)
3229    yacc_rules = FALSE;    yacc_rules = FALSE;
3230    midtoken = inquote = inchar = incomm = quotednl = FALSE;    midtoken = inquote = inchar = incomm = quotednl = FALSE;
3231    token.valid = savetoken.valid = FALSE;    token.valid = savetoken.valid = FALSE;
3232    cblev = 0;    bracelev = bracketlev = parlev = attrparlev = templatelev = 0;
   parlev = 0;  
3233    if (cjava)    if (cjava)
3234      { qualifier = "."; qlen = 1; }      { qualifier = "."; qlen = 1; }
3235    else    else
# Line 3257  C_entries (c_ext, inf) Line 3241  C_entries (c_ext, inf)
3241        c = *lp++;        c = *lp++;
3242        if (c == '\\')        if (c == '\\')
3243          {          {
3244            /* If we're at the end of the line, the next character is a            /* If we are at the end of the line, the next character is a
3245               '\0'; don't skip it, because it's the thing that tells us               '\0'; do not skip it, because it is what tells us
3246               to read the next line.  */               to read the next line.  */
3247            if (*lp == '\0')            if (*lp == '\0')
3248              {              {
# Line 3317  C_entries (c_ext, inf) Line 3301  C_entries (c_ext, inf)
3301              }              }
3302            continue;            continue;
3303          }          }
3304        else        else if (bracketlev > 0)
3305          switch (c)          {
3306            {            switch (c)
3307            case '"':              {
3308              inquote = TRUE;              case ']':
3309              switch (fvdef)                if (--bracketlev > 0)
               {  
               case fdefunkey:  
               case fstartlist:  
               case finlist:  
               case fignore:  
               case vignore:  
                 break;  
               default:  
                 fvextern = FALSE;  
                 fvdef = fvnone;  
               }  
             continue;  
           case '\'':  
             inchar = TRUE;  
             if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)  
               {  
                 fvextern = FALSE;  
                 fvdef = fvnone;  
               }  
             continue;  
           case '/':  
             if (*lp == '*')  
               {  
                 lp++;  
                 incomm = TRUE;  
3310                  continue;                  continue;
               }  
             else if (/* cplpl && */ *lp == '/')  
               {  
                 c = '\0';  
                 break;  
               }  
             else  
3311                break;                break;
3312            case '%':              case '\0':
3313              if ((c_ext & YACC) && *lp == '%')                CNL_SAVE_DEFINEDEF ();
               {  
                 /* Entering or exiting rules section in yacc file. */  
                 lp++;  
                 definedef = dnone; fvdef = fvnone; fvextern = FALSE;  
                 typdef = tnone; structdef = snone;  
                 midtoken = inquote = inchar = incomm = quotednl = FALSE;  
                 cblev = 0;  
                 yacc_rules = !yacc_rules;  
                 continue;  
               }  
             else  
3314                break;                break;
3315            case '#':              }
3316              if (definedef == dnone)            continue;
3317                {          }
3318                  char *cp;        else switch (c)
3319                  bool cpptoken = TRUE;          {
3320            case '"':
3321                  /* Look back on this line.  If all blanks, or nonblanks            inquote = TRUE;
3322                     followed by an end of comment, this is a preprocessor            if (inattribute)
3323                     token. */              break;
3324                  for (cp = newlb.buffer; cp < lp-1; cp++)            switch (fvdef)
3325                    if (!iswhite (*cp))              {
3326                      {              case fdefunkey:
3327                        if (*cp == '*' && *(cp+1) == '/')              case fstartlist:
3328                          {              case finlist:
3329                            cp++;              case fignore:
3330                            cpptoken = TRUE;              case vignore:
3331                          }                break;
3332                        else              default:
3333                          cpptoken = FALSE;                fvextern = FALSE;
3334                      }                fvdef = fvnone;
3335                  if (cpptoken)              }
3336                    definedef = dsharpseen;            continue;
3337                } /* if (definedef == dnone) */          case '\'':
3338              inchar = TRUE;
3339              if (inattribute)
3340                break;
3341              if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
3342                {
3343                  fvextern = FALSE;
3344                  fvdef = fvnone;
3345                }
3346              continue;
3347            case '/':
3348              if (*lp == '*')
3349                {
3350                  lp++;
3351                  incomm = TRUE;
3352                  continue;
3353                }
3354              else if (/* cplpl && */ *lp == '/')
3355                {
3356                  c = '\0';
3357                  break;
3358                }
3359              else
3360                break;
3361            case '%':
3362              if ((c_ext & YACC) && *lp == '%')
3363                {
3364                  /* Entering or exiting rules section in yacc file. */
3365                  lp++;
3366                  definedef = dnone; fvdef = fvnone; fvextern = FALSE;
3367                  typdef = tnone; structdef = snone;
3368                  midtoken = inquote = inchar = incomm = quotednl = FALSE;
3369                  bracelev = 0;
3370                  yacc_rules = !yacc_rules;
3371                  continue;
3372                }
3373              else
3374                break;
3375            case '#':
3376              if (definedef == dnone)
3377                {
3378                  char *cp;
3379                  bool cpptoken = TRUE;
3380    
3381                  /* Look back on this line.  If all blanks, or nonblanks
3382                     followed by an end of comment, this is a preprocessor
3383                     token. */
3384                  for (cp = newlb.buffer; cp < lp-1; cp++)
3385                    if (!iswhite (*cp))
3386                      {
3387                        if (*cp == '*' && *(cp+1) == '/')
3388                          {
3389                            cp++;
3390                            cpptoken = TRUE;
3391                          }
3392                        else
3393                          cpptoken = FALSE;
3394                      }
3395                  if (cpptoken)
3396                    definedef = dsharpseen;
3397                } /* if (definedef == dnone) */
3398              continue;
3399            case '[':
3400              bracketlev++;
3401              continue;              continue;
3402            } /* switch (c) */          } /* switch (c) */
3403    
3404    
3405        /* Consider token only if some involved conditions are satisfied. */        /* Consider token only if some involved conditions are satisfied. */
3406        if (typdef != tignore        if (typdef != tignore
3407            && definedef != dignorerest            && definedef != dignorerest
3408            && fvdef != finlist            && fvdef != finlist
3409            && structdef != sintemplate            && templatelev == 0
3410            && (definedef != dnone            && (definedef != dnone
3411                || structdef != scolonseen))                || structdef != scolonseen)
3412              && !inattribute)
3413          {          {
3414            if (midtoken)            if (midtoken)
3415              {              {
# Line 3429  C_entries (c_ext, inf) Line 3433  C_entries (c_ext, inf)
3433    
3434                        if (yacc_rules                        if (yacc_rules
3435                            || consider_token (newlb.buffer + tokoff, toklen, c,                            || consider_token (newlb.buffer + tokoff, toklen, c,
3436                                               &c_ext, cblev, parlev, &funorvar))                                               &c_ext, bracelev, parlev,
3437                                                 &funorvar))
3438                          {                          {
3439                            if (fvdef == foperator)                            if (fvdef == foperator)
3440                              {                              {
# Line 3514  C_entries (c_ext, inf) Line 3519  C_entries (c_ext, inf)
3519                                               || (funorvar                                               || (funorvar
3520                                                   && definedef == dnone                                                   && definedef == dnone
3521                                                   && structdef == snone                                                   && structdef == snone
3522                                                   && cblev > 0));                                                   && bracelev > 0));
3523                              }                              }
3524                            token.lineno = lineno;                            token.lineno = lineno;
3525                            token.offset = tokoff;                            token.offset = tokoff;
# Line 3539  C_entries (c_ext, inf) Line 3544  C_entries (c_ext, inf)
3544                                     || instruct)                                     || instruct)
3545                              make_C_tag (funorvar);                              make_C_tag (funorvar);
3546                          }                          }
3547                          else /* not yacc and consider_token failed */
3548                            {
3549                              if (inattribute && fvdef == fignore)
3550                                {
3551                                  /* We have just met __attribute__ after a
3552                                     function parameter list: do not tag the
3553                                     function again. */
3554                                  fvdef = fvnone;
3555                                }
3556                            }
3557                        midtoken = FALSE;                        midtoken = FALSE;
3558                      }                      }
3559                  } /* if (endtoken (c)) */                  } /* if (endtoken (c)) */
# Line 3557  C_entries (c_ext, inf) Line 3572  C_entries (c_ext, inf)
3572                    switch (fvdef)                    switch (fvdef)
3573                      {                      {
3574                      case fstartlist:                      case fstartlist:
3575                          /* This prevents tagging fb in
3576                             void (__attribute__((noreturn)) *fb) (void);
3577                             Fixing this is not easy and not very important. */
3578                        fvdef = finlist;                        fvdef = finlist;
3579                        continue;                        continue;
3580                      case flistseen:                      case flistseen:
# Line 3566  C_entries (c_ext, inf) Line 3584  C_entries (c_ext, inf)
3584                            fvdef = fignore;                            fvdef = fignore;
3585                          }                          }
3586                        break;                        break;
                     case fvnameseen:  
                       fvdef = fvnone;  
                       break;  
3587                      }                      }
3588                    if (structdef == stagseen && !cjava)                    if (structdef == stagseen && !cjava)
3589                      {                      {
3590                        popclass_above (cblev);                        popclass_above (bracelev);
3591                        structdef = snone;                        structdef = snone;
3592                      }                      }
3593                    break;                    break;
# Line 3596  C_entries (c_ext, inf) Line 3611  C_entries (c_ext, inf)
3611        switch (c)        switch (c)
3612          {          {
3613          case ':':          case ':':
3614              if (inattribute)
3615                break;
3616            if (yacc_rules && token.offset == 0 && token.valid)            if (yacc_rules && token.offset == 0 && token.valid)
3617              {              {
3618                make_C_tag (FALSE); /* a yacc function */                make_C_tag (FALSE); /* a yacc function */
# Line 3630  C_entries (c_ext, inf) Line 3647  C_entries (c_ext, inf)
3647              }              }
3648            break;            break;
3649          case ';':          case ';':
3650            if (definedef != dnone)            if (definedef != dnone || inattribute)
3651              break;              break;
3652            switch (typdef)            switch (typdef)
3653              {              {
# Line 3650  C_entries (c_ext, inf) Line 3667  C_entries (c_ext, inf)
3667                      fvdef = fvnone;                      fvdef = fvnone;
3668                    break;                    break;
3669                  case fvnameseen:                  case fvnameseen:
3670                    if ((globals && cblev == 0 && (!fvextern || declarations))                    if ((globals && bracelev == 0 && (!fvextern || declarations))
3671                        || (members && instruct))                        || (members && instruct))
3672                      make_C_tag (FALSE); /* a variable */                      make_C_tag (FALSE); /* a variable */
3673                    fvextern = FALSE;                    fvextern = FALSE;
# Line 3658  C_entries (c_ext, inf) Line 3675  C_entries (c_ext, inf)
3675                    token.valid = FALSE;                    token.valid = FALSE;
3676                    break;                    break;
3677                  case flistseen:                  case flistseen:
3678                    if (declarations                    if ((declarations
3679                        && (typdef == tnone || (typdef != tignore && instruct)))                         && (cplpl || !instruct)
3680                      make_C_tag (TRUE);  /* a function declaration */                         && (typdef == tnone || (typdef != tignore && instruct)))
3681                          || (members
3682                              && plainc && instruct))
3683                        make_C_tag (TRUE);  /* a function */
3684                    /* FALLTHRU */                    /* FALLTHRU */
3685                  default:                  default:
3686                    fvextern = FALSE;                    fvextern = FALSE;
# Line 3680  C_entries (c_ext, inf) Line 3700  C_entries (c_ext, inf)
3700              structdef = snone;              structdef = snone;
3701            break;            break;
3702          case ',':          case ',':
3703            if (definedef != dnone)            if (definedef != dnone || inattribute)
3704              break;              break;
3705            switch (objdef)            switch (objdef)
3706              {              {
# Line 3702  C_entries (c_ext, inf) Line 3722  C_entries (c_ext, inf)
3722              case fdefunname:              case fdefunname:
3723                fvdef = fignore;                fvdef = fignore;
3724                break;                break;
3725              case fvnameseen:    /* a variable */              case fvnameseen:
3726                if ((globals && cblev == 0 && (!fvextern || declarations))                if (parlev == 0
3727                    || (members && instruct))                    && ((globals
3728                  make_C_tag (FALSE);                         && bracelev == 0
3729                           && templatelev == 0
3730                           && (!fvextern || declarations))
3731                          || (members && instruct)))
3732                      make_C_tag (FALSE); /* a variable */
3733                break;                break;
3734              case flistseen:     /* a function */              case flistseen:
3735                if ((declarations && typdef == tnone && !instruct)                if ((declarations && typdef == tnone && !instruct)
3736                    || (members && typdef != tignore && instruct))                    || (members && typdef != tignore && instruct))
3737                  {                  {
3738                    make_C_tag (TRUE); /* a function declaration */                    make_C_tag (TRUE); /* a function */
3739                    fvdef = fvnameseen;                    fvdef = fvnameseen;
3740                  }                  }
3741                else if (!declarations)                else if (!declarations)
# Line 3724  C_entries (c_ext, inf) Line 3748  C_entries (c_ext, inf)
3748            if (structdef == stagseen)            if (structdef == stagseen)
3749              structdef = snone;              structdef = snone;
3750            break;            break;
3751          case '[':          case ']':
3752            if (definedef != dnone)            if (definedef != dnone || inattribute)
3753              break;              break;
3754            if (structdef == stagseen)            if (structdef == stagseen)
3755              structdef = snone;              structdef = snone;
# Line 3746  C_entries (c_ext, inf) Line 3770  C_entries (c_ext, inf)
3770                  case vignore:                  case vignore:
3771                    break;                    break;
3772                  case fvnameseen:                  case fvnameseen:
3773                    if ((members && cblev == 1)                    if ((members && bracelev == 1)
3774                        || (globals && cblev == 0                        || (globals && bracelev == 0
3775                            && (!fvextern || declarations)))                            && (!fvextern || declarations)))
3776                      make_C_tag (FALSE); /* a variable */                      make_C_tag (FALSE); /* a variable */
3777                    /* FALLTHRU */                    /* FALLTHRU */
# Line 3758  C_entries (c_ext, inf) Line 3782  C_entries (c_ext, inf)
3782              }              }
3783            break;            break;
3784          case '(':          case '(':
3785              if (inattribute)
3786                {
3787                  attrparlev++;
3788                  break;
3789                }
3790            if (definedef != dnone)            if (definedef != dnone)
3791              break;              break;
3792            if (objdef == otagseen && parlev == 0)            if (objdef == otagseen && parlev == 0)
# Line 3787  C_entries (c_ext, inf) Line 3816  C_entries (c_ext, inf)
3816            parlev++;            parlev++;
3817            break;            break;
3818          case ')':          case ')':
3819              if (inattribute)
3820                {
3821                  if (--attrparlev == 0)
3822                    inattribute = FALSE;
3823                  break;
3824                }
3825            if (definedef != dnone)            if (definedef != dnone)
3826              break;              break;
3827            if (objdef == ocatseen && parlev == 1)            if (objdef == ocatseen && parlev == 1)
# Line 3820  C_entries (c_ext, inf) Line 3855  C_entries (c_ext, inf)
3855            if (typdef == ttypeseen)            if (typdef == ttypeseen)
3856              {              {
3857                /* Whenever typdef is set to tinbody (currently only                /* Whenever typdef is set to tinbody (currently only
3858                   here), typdefcblev should be set to cblev. */                   here), typdefbracelev should be set to bracelev. */
3859                typdef = tinbody;                typdef = tinbody;
3860                typdefcblev = cblev;                typdefbracelev = bracelev;
3861              }              }
3862            switch (fvdef)            switch (fvdef)
3863              {              {
# Line 3846  C_entries (c_ext, inf) Line 3881  C_entries (c_ext, inf)
3881                    break;                    break;
3882                  default:                  default:
3883                    /* Neutralize `extern "C" {' grot. */                    /* Neutralize `extern "C" {' grot. */
3884                    if (cblev == 0 && structdef == snone && nestlev == 0                    if (bracelev == 0 && structdef == snone && nestlev == 0
3885                        && typdef == tnone)                        && typdef == tnone)
3886                      cblev = -1;                      bracelev = -1;
3887                  }                  }
3888                break;                break;
3889              }              }
3890            switch (structdef)            switch (structdef)
3891              {              {
3892              case skeyseen:         /* unnamed struct */              case skeyseen:         /* unnamed struct */
3893                pushclass_above (cblev, NULL, 0);                pushclass_above (bracelev, NULL, 0);
3894                structdef = snone;                structdef = snone;
3895                break;                break;
3896              case stagseen:         /* named struct or enum */              case stagseen:         /* named struct or enum */
3897              case scolonseen:       /* a class */              case scolonseen:       /* a class */
3898                pushclass_above (cblev, token.line+token.offset, token.length);                pushclass_above (bracelev,token.line+token.offset, token.length);
3899                structdef = snone;                structdef = snone;
3900                make_C_tag (FALSE);  /* a struct or enum */                make_C_tag (FALSE);  /* a struct or enum */
3901                break;                break;
3902              }              }
3903            cblev++;            bracelev++;
3904            break;            break;
3905          case '*':          case '*':
3906            if (definedef != dnone)            if (definedef != dnone)
# Line 3881  C_entries (c_ext, inf) Line 3916  C_entries (c_ext, inf)
3916              break;              break;
3917            if (!ignoreindent && lp == newlb.buffer + 1)            if (!ignoreindent && lp == newlb.buffer + 1)
3918              {              {
3919                if (cblev != 0)                if (bracelev != 0)
3920                  token.valid = FALSE;                  token.valid = FALSE;
3921                cblev = 0;        /* reset curly brace level if first column */                bracelev = 0;     /* reset brace level if first column */
3922                parlev = 0;       /* also reset paren level, just in case... */                parlev = 0;       /* also reset paren level, just in case... */
3923              }              }
3924            else if (cblev > 0)            else if (bracelev > 0)
3925              cblev--;              bracelev--;
3926            else            else
3927              token.valid = FALSE; /* something gone amiss, token unreliable */              token.valid = FALSE; /* something gone amiss, token unreliable */
3928            popclass_above (cblev);            popclass_above (bracelev);
3929            structdef = snone;            structdef = snone;
3930            /* Only if typdef == tinbody is typdefcblev significant. */            /* Only if typdef == tinbody is typdefbracelev significant. */
3931            if (typdef == tinbody && cblev <= typdefcblev)            if (typdef == tinbody && bracelev <= typdefbracelev)
3932              {              {
3933                assert (cblev == typdefcblev);                assert (bracelev == typdefbracelev);
3934                typdef = tend;                typdef = tend;
3935              }              }
3936            break;            break;
# Line 3910  C_entries (c_ext, inf) Line 3945  C_entries (c_ext, inf)
3945              case vignore:              case vignore:
3946                break;                break;
3947              case fvnameseen:              case fvnameseen:
3948                if ((members && cblev == 1)                if ((members && bracelev == 1)
3949                    || (globals && cblev == 0 && (!fvextern || declarations)))                    || (globals && bracelev == 0 && (!fvextern || declarations)))
3950                  make_C_tag (FALSE); /* a variable */                  make_C_tag (FALSE); /* a variable */
3951                /* FALLTHRU */                /* FALLTHRU */
3952              default:              default:
# Line 3919  C_entries (c_ext, inf) Line 3954  C_entries (c_ext, inf)
3954              }              }
3955            break;            break;
3956          case '<':          case '<':
3957            if (cplpl && structdef == stagseen)            if (cplpl
3958                  && (structdef == stagseen || fvdef == fvnameseen))
3959              {              {
3960                structdef = sintemplate;                templatelev++;
3961                break;                break;
3962              }              }
3963            goto resetfvdef;            goto resetfvdef;
3964          case '>':          case '>':
3965            if (structdef == sintemplate)            if (templatelev > 0)
3966              {              {
3967                structdef = stagseen;                templatelev--;
3968                break;                break;
3969              }              }
3970            goto resetfvdef;            goto resetfvdef;
3971          case '+':          case '+':
3972          case '-':          case '-':
3973            if (objdef == oinbody && cblev == 0)            if (objdef == oinbody && bracelev == 0)
3974              {              {
3975                objdef = omethodsign;                objdef = omethodsign;
3976                break;                break;
3977              }              }
3978            /* FALLTHRU */            /* FALLTHRU */
3979          resetfvdef:          resetfvdef:
3980          case '#': case '~': case '&': case '%': case '/': case '|':          case '#': case '~': case '&': case '%': case '/':
3981          case '^': case '!': case '.': case '?': case ']':          case '|': case '^': case '!': case '.': case '?':
3982            if (definedef != dnone)            if (definedef != dnone)
3983              break;              break;
3984            /* These surely cannot follow a function tag in C. */            /* These surely cannot follow a function tag in C. */
# Line 4892  Lisp_functions (inf) Line 4928  Lisp_functions (inf)
4928      }      }
4929  }  }
4930    
4931    
4932    /*
4933     * Lua script language parsing
4934     * Original code by David A. Capello <dacap@users.sourceforge.net> (2004)
4935     *
4936     *  "function" and "local function" are tags if they start at column 1.
4937     */
4938    static void
4939    Lua_functions (inf)
4940         FILE *inf;
4941    {
4942      register char *bp;
4943    
4944      LOOP_ON_INPUT_LINES (inf, lb, bp)
4945        {
4946          if (bp[0] != 'f' && bp[0] != 'l')
4947            continue;
4948    
4949          LOOKING_AT (bp, "local"); /* skip possible "local" */
4950    
4951          if (LOOKING_AT (bp, "function"))
4952            get_tag (bp, NULL);
4953        }
4954    }
4955    
4956    
4957  /*  /*
4958   * Postscript tag functions   * Postscript tag functions

Legend:
Removed from v.3.21.2.4  
changed lines
  Added in v.3.21.2.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26