aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorFrancesco Potortì2001-01-28 16:14:04 +0000
committerFrancesco Potortì2001-01-28 16:14:04 +0000
commit8c463abe32e451893e5512b0e0dd6213661c2c8b (patch)
tree2dc00ab0642d78a235ec0d4fa040737ec995206c /lib-src
parentb179a3a28f7dcd67532d0122c01837bf9a0e999c (diff)
downloademacs-8c463abe32e451893e5512b0e0dd6213661c2c8b.tar.gz
emacs-8c463abe32e451893e5512b0e0dd6213661c2c8b.zip
Many changes to the parsing capabilities of etags.
The -C or -c++ options are now mostly obsolete. Can delve at arbitrary deeps into structures of C-like languages.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog25
-rw-r--r--lib-src/etags.19
-rw-r--r--lib-src/etags.c665
3 files changed, 442 insertions, 257 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 7e738017121..fa819043329 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,10 +1,33 @@
12001-01-28 Francesco Potorti` <pot@gnu.org>
2
3 * etags.c: Be capable to parse nested struct-like structures.
4 (structdef, structtag): Struct state machine revisited.
5 (struct tok): Revisited.
6 (cstack, nestlev, instruct): New struct and macros.
7 (pushclass_above, popclass_above, write_classname): New functions
8 for dealing with nested class names, inspired by Mykola Dzyuba.
9 (consider_token, make_C_tag, C_entries): Many changes for dealing
10 with arbitrarily nested structures.
11 (etags_getcwd): #if MSDOS, not #ifdef MSDOS!
12 (C_entries): Consider templates in C++.
13 (sym_type): New constant st_C_class for detecting "class" also in
14 C mode.
15 (C_AUTO): New macro for automatic detection of C++.
16 (consider_token): Automatic set C++ mode.
17 (C_entries): New security check for yacc.
18 (print_language_names, print_help): Mention the autodetect
19 feature, do not show help for the -C option, now mostly useless.
20 (C_entries): Tag C++ forward declarations if --declarations.
21 (C_entries): Don't be fooled by things like XDEFUN.
22 (consider_token): Discard asm pseudo function.
23
12001-01-27 Eli Zaretskii <eliz@is.elta.co.il> 242001-01-27 Eli Zaretskii <eliz@is.elta.co.il>
2 25
3 * etags.c: Add a coding: tag. 26 * etags.c: Add a coding: tag.
4 27
52001-01-26 Gerd Moellmann <gerd@gnu.org> 282001-01-26 Gerd Moellmann <gerd@gnu.org>
6 29
7 * ebrowse.c (matching_regexp_buffer, matching_regexp_end_buf): 30 * ebrowse.c (matching_regexp_buffer, matching_regexp_end_buf):
8 New variables. 31 New variables.
9 (matching_regexp): Use them instead of static variables in 32 (matching_regexp): Use them instead of static variables in
10 function scope. 33 function scope.
diff --git a/lib-src/etags.1 b/lib-src/etags.1
index 5a85666cf90..3ae60ec9a87 100644
--- a/lib-src/etags.1
+++ b/lib-src/etags.1
@@ -16,7 +16,7 @@ etags, ctags \- generate tag file for Emacs, vi
16.if n .br 16.if n .br
17.B [\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|] 17.B [\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|]
18.br 18.br
19.B [\|\-\-append\|] [\|\-\-c++\|] [\|\-\-no\-defines\|] 19.B [\|\-\-append\|] [\|\-\-no\-defines\|]
20.B [\|\-\-no\-globals\|] [\|\-\-include=\fIfile\fP\|] 20.B [\|\-\-no\-globals\|] [\|\-\-include=\fIfile\fP\|]
21.B [\|\-\-ignore\-indentation\|] [\|\-\-language=\fIlanguage\fP\|] 21.B [\|\-\-ignore\-indentation\|] [\|\-\-language=\fIlanguage\fP\|]
22.B [\|\-\-members\|] [\|\-\-output=\fItagfile\fP\|] 22.B [\|\-\-members\|] [\|\-\-output=\fItagfile\fP\|]
@@ -29,7 +29,7 @@ etags, ctags \- generate tag file for Emacs, vi
29.if n .br 29.if n .br
30.B [\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|] 30.B [\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|]
31.br 31.br
32.B [\|\-\-append\|] [\|\-\-backward\-search\|] [\|\-\-c++\|] 32.B [\|\-\-append\|] [\|\-\-backward\-search\|]
33.B [\|\-\-cxref\|] [\|\-\-defines\|] [\|\-\-forward\-search\|] 33.B [\|\-\-cxref\|] [\|\-\-defines\|] [\|\-\-forward\-search\|]
34.B [\|\-\-globals\|] [\|\-\-ignore\-indentation\|] 34.B [\|\-\-globals\|] [\|\-\-ignore\-indentation\|]
35.B [\|\-\-language=\fIlanguage\fP\|] [\|\-\-members\|] 35.B [\|\-\-language=\fIlanguage\fP\|] [\|\-\-members\|]
@@ -81,11 +81,6 @@ The default is to use the delimiter `\|\fB/\fP\|', to search \fIforwards\fP
81through files. 81through files.
82Only \fBctags\fP accepts this option. 82Only \fBctags\fP accepts this option.
83.TP 83.TP
84.B \-C, \-\-c++
85Treat files with `\|.c\|' and `\|.h\|' extensions as C++ code, not C
86code. Files with `\|.C\|', `\|.H\|', `\|.cxx\|', `\|.hxx\|', or
87`\|.cc\|' extensions are always assumed to be C++ code.
88.TP
89.B \-\-declarations 84.B \-\-declarations
90In C and derived languages, create tags for function declarations, 85In C and derived languages, create tags for function declarations,
91and create tags for extern variables unless \-\-no\-globals is used. 86and create tags for extern variables unless \-\-no\-globals is used.
diff --git a/lib-src/etags.c b/lib-src/etags.c
index a2615da941c..57a25c4467a 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 number is $Revision: 2.79 $"; 35char pot_etags_version[] = "@(#) pot revision number is 14.11";
36 36
37#define TRUE 1 37#define TRUE 1
38#define FALSE 0 38#define FALSE 0
@@ -156,11 +156,13 @@ char pot_etags_version[] = "@(#) pot number is $Revision: 2.79 $";
156#endif 156#endif
157 157
158/* C extensions. */ 158/* C extensions. */
159#define C_EXT 0x00fff /* C extensions */
160#define C_PLAIN 0x00000 /* C */
159#define C_PLPL 0x00001 /* C++ */ 161#define C_PLPL 0x00001 /* C++ */
160#define C_STAR 0x00003 /* C* */ 162#define C_STAR 0x00003 /* C* */
161#define C_JAVA 0x00005 /* JAVA */ 163#define C_JAVA 0x00005 /* JAVA */
164#define C_AUTO 0x01000 /* C, switch to C++ if `class' is met */
162#define YACC 0x10000 /* yacc file */ 165#define YACC 0x10000 /* yacc file */
163#define PUREC (!(c_ext & ~YACC)) /* no extensions (apart from possibly yacc) */
164 166
165#define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t)) 167#define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
166#define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n)) 168#define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
@@ -601,6 +603,7 @@ If no language is specified and no matching suffix is found,\n\
601the first line of the file is read for a sharp-bang (#!) sequence\n\ 603the first line of the file is read for a sharp-bang (#!) sequence\n\
602followed by the name of an interpreter. If no such sequence is found,\n\ 604followed by the name of an interpreter. If no such sequence is found,\n\
603Fortran is tried first; if no tags are found, C is tried next.\n\ 605Fortran is tried first; if no tags are found, C is tried next.\n\
606When parsing any C file, a \"class\" keyword switches to C++.\n\
604Compressed files are supported using gzip and bzip2."); 607Compressed files are supported using gzip and bzip2.");
605} 608}
606 609
@@ -649,8 +652,13 @@ Relative ones are stored relative to the output file's directory.");
649 Write the search commands for the tag entries using '?', the\n\ 652 Write the search commands for the tag entries using '?', the\n\
650 backward-search command instead of '/', the forward-search command."); 653 backward-search command instead of '/', the forward-search command.");
651 654
655 /* This option is mostly obsolete, because etags can now automatically
656 detect C++. Retained for backward compatibility and for debugging and
657 experimentation. In principle, we could want to tag as C++ even
658 before any "class" keyword.
652 puts ("-C, --c++\n\ 659 puts ("-C, --c++\n\
653 Treat files whose name suffix defaults to C language as C++ files."); 660 Treat files whose name suffix defaults to C language as C++ files.");
661 */
654 662
655 puts ("--declarations\n\ 663 puts ("--declarations\n\
656 In C and derived languages, create tags for function declarations,"); 664 In C and derived languages, create tags for function declarations,");
@@ -934,13 +942,14 @@ main (argc, argv)
934 942
935 /* 943 /*
936 * If etags, always find typedefs and structure tags. Why not? 944 * If etags, always find typedefs and structure tags. Why not?
937 * Also default is to find macro constants, enum constants and 945 * Also default to find macro constants, enum constants and
938 * global variables. 946 * global variables.
939 */ 947 */
940 if (!CTAGS) 948 if (!CTAGS)
941 { 949 {
942 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE; 950 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
943 globals = TRUE; 951 globals = TRUE;
952 declarations = FALSE;
944 members = FALSE; 953 members = FALSE;
945 } 954 }
946 955
@@ -1440,7 +1449,7 @@ process_file (file)
1440 if (real_name == compressed_name) 1449 if (real_name == compressed_name)
1441 { 1450 {
1442 char *cmd = concat (compr->command, " ", real_name); 1451 char *cmd = concat (compr->command, " ", real_name);
1443 inf = popen (cmd, "r"); 1452 inf = (FILE *) popen (cmd, "r");
1444 free (cmd); 1453 free (cmd);
1445 } 1454 }
1446 else 1455 else
@@ -1922,6 +1931,7 @@ enum sym_type
1922 st_C_ignore, 1931 st_C_ignore,
1923 st_C_javastruct, 1932 st_C_javastruct,
1924 st_C_operator, 1933 st_C_operator,
1934 st_C_class,
1925 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec 1935 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1926}; 1936};
1927 1937
@@ -1949,7 +1959,7 @@ friend, C_PLPL, st_C_ignore
1949extends, C_JAVA, st_C_javastruct 1959extends, C_JAVA, st_C_javastruct
1950implements, C_JAVA, st_C_javastruct 1960implements, C_JAVA, st_C_javastruct
1951interface, C_JAVA, st_C_struct 1961interface, C_JAVA, st_C_struct
1952class, C_PLPL, st_C_struct 1962class, 0, st_C_class
1953namespace, C_PLPL, st_C_struct 1963namespace, C_PLPL, st_C_struct
1954domain, C_STAR, st_C_struct 1964domain, C_STAR, st_C_struct
1955union, 0, st_C_struct 1965union, 0, st_C_struct
@@ -1986,7 +1996,8 @@ PSEUDO, 0, st_C_gnumacro
1986#EXFUN, 0, st_C_gnumacro 1996#EXFUN, 0, st_C_gnumacro
1987#DEFVAR_, 0, st_C_gnumacro 1997#DEFVAR_, 0, st_C_gnumacro
1988%] 1998%]
1989and replace lines between %< and %> with its output. */ 1999and replace lines between %< and %> with its output,
2000then make in_word_set static. */
1990/*%<*/ 2001/*%<*/
1991/* C code produced by gperf version 2.7.1 (19981006 egcs) */ 2002/* C code produced by gperf version 2.7.1 (19981006 egcs) */
1992/* Command-line: gperf -c -k 1,3 -o -p -r -t */ 2003/* Command-line: gperf -c -k 1,3 -o -p -r -t */
@@ -1996,8 +2007,8 @@ struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1996#define MIN_WORD_LENGTH 2 2007#define MIN_WORD_LENGTH 2
1997#define MAX_WORD_LENGTH 15 2008#define MAX_WORD_LENGTH 15
1998#define MIN_HASH_VALUE 13 2009#define MIN_HASH_VALUE 13
1999#define MAX_HASH_VALUE 123 2010#define MAX_HASH_VALUE 121
2000/* maximum key range = 111, duplicates = 0 */ 2011/* maximum key range = 109, duplicates = 0 */
2001 2012
2002#ifdef __GNUC__ 2013#ifdef __GNUC__
2003__inline 2014__inline
@@ -2009,32 +2020,32 @@ hash (str, len)
2009{ 2020{
2010 static unsigned char asso_values[] = 2021 static unsigned char asso_values[] =
2011 { 2022 {
2012 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2023 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2013 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2024 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2014 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2025 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2015 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2026 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2016 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2027 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2017 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2028 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2018 124, 124, 124, 124, 3, 124, 124, 124, 43, 6, 2029 122, 122, 122, 122, 57, 122, 122, 122, 55, 6,
2019 11, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2030 60, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2020 11, 124, 124, 58, 7, 124, 124, 124, 124, 124, 2031 51, 122, 122, 10, 2, 122, 122, 122, 122, 122,
2021 124, 124, 124, 124, 124, 124, 124, 57, 7, 42, 2032 122, 122, 122, 122, 122, 122, 122, 2, 52, 59,
2022 4, 14, 52, 0, 124, 53, 124, 124, 29, 11, 2033 49, 38, 56, 41, 122, 22, 122, 122, 9, 32,
2023 6, 35, 32, 124, 29, 34, 59, 58, 51, 24, 2034 33, 60, 26, 122, 1, 28, 46, 59, 44, 51,
2024 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2035 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2025 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2036 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2026 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2037 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2027 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2038 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2028 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2039 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2029 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2040 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2030 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2041 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2031 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2042 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2032 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2043 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2033 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2044 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2034 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2045 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2035 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2046 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2036 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2047 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2037 124, 124, 124, 124, 124, 124 2048 122, 122, 122, 122, 122, 122
2038 }; 2049 };
2039 register int hval = len; 2050 register int hval = len;
2040 2051
@@ -2054,7 +2065,7 @@ hash (str, len)
2054#ifdef __GNUC__ 2065#ifdef __GNUC__
2055__inline 2066__inline
2056#endif 2067#endif
2057static struct C_stab_entry * 2068struct C_stab_entry *
2058in_word_set (str, len) 2069in_word_set (str, len)
2059 register const char *str; 2070 register const char *str;
2060 register unsigned int len; 2071 register unsigned int len;
@@ -2063,77 +2074,76 @@ in_word_set (str, len)
2063 { 2074 {
2064 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, 2075 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2065 {""}, {""}, {""}, {""}, 2076 {""}, {""}, {""}, {""},
2066 {"@end", 0, st_C_objend},
2067 {""}, {""}, {""}, {""},
2068 {"ENTRY", 0, st_C_gnumacro}, 2077 {"ENTRY", 0, st_C_gnumacro},
2069 {"@interface", 0, st_C_objprot}, 2078 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2070 {""},
2071 {"domain", C_STAR, st_C_struct},
2072 {""}, 2079 {""},
2073 {"PSEUDO", 0, st_C_gnumacro}, 2080 {"if", 0, st_C_ignore},
2074 {""}, {""},
2075 {"namespace", C_PLPL, st_C_struct},
2076 {""}, {""}, 2081 {""}, {""},
2077 {"@implementation",0, st_C_objimpl}, 2082 {"SYSCALL", 0, st_C_gnumacro},
2083 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2084 {"struct", 0, st_C_struct},
2085 {"static", 0, st_C_typespec},
2078 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, 2086 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2079 {"long", 0, st_C_typespec}, 2087 {"long", 0, st_C_typespec},
2080 {"signed", 0, st_C_typespec},
2081 {"@protocol", 0, st_C_objprot},
2082 {""}, {""}, {""}, {""},
2083 {"bool", C_PLPL, st_C_typespec},
2084 {""}, {""}, {""}, {""}, {""}, {""},
2085 {"const", 0, st_C_typespec},
2086 {"explicit", C_PLPL, st_C_typespec},
2087 {"if", 0, st_C_ignore},
2088 {""},
2089 {"operator", C_PLPL, st_C_operator},
2090 {""},
2091 {"DEFUN", 0, st_C_gnumacro},
2092 {""}, {""},
2093 {"define", 0, st_C_define},
2094 {""}, {""}, {""}, {""}, {""}, 2088 {""}, {""}, {""}, {""}, {""},
2095 {"double", 0, st_C_typespec}, 2089 {"auto", 0, st_C_typespec},
2096 {"struct", 0, st_C_struct}, 2090 {"return", 0, st_C_ignore},
2097 {""}, {""}, {""}, {""}, 2091 {"import", C_JAVA, st_C_ignore},
2098 {"short", 0, st_C_typespec},
2099 {""}, 2092 {""},
2100 {"enum", 0, st_C_enum}, 2093 {"switch", 0, st_C_ignore},
2101 {"mutable", C_PLPL, st_C_typespec},
2102 {""}, 2094 {""},
2103 {"extern", 0, st_C_extern}, 2095 {"implements", C_JAVA, st_C_javastruct},
2104 {"extends", C_JAVA, st_C_javastruct},
2105 {"package", C_JAVA, st_C_ignore},
2106 {"while", 0, st_C_ignore},
2107 {""}, 2096 {""},
2108 {"for", 0, st_C_ignore}, 2097 {"for", 0, st_C_ignore},
2109 {""}, {""}, {""},
2110 {"volatile", 0, st_C_typespec}, 2098 {"volatile", 0, st_C_typespec},
2099 {""},
2100 {"PSEUDO", 0, st_C_gnumacro},
2101 {""},
2102 {"char", 0, st_C_typespec},
2103 {"class", 0, st_C_class},
2104 {"@protocol", 0, st_C_objprot},
2111 {""}, {""}, 2105 {""}, {""},
2112 {"import", C_JAVA, st_C_ignore}, 2106 {"void", 0, st_C_typespec},
2113 {"float", 0, st_C_typespec}, 2107 {"int", 0, st_C_typespec},
2114 {"switch", 0, st_C_ignore}, 2108 {"explicit", C_PLPL, st_C_typespec},
2115 {"return", 0, st_C_ignore},
2116 {"implements", C_JAVA, st_C_javastruct},
2117 {""}, 2109 {""},
2118 {"static", 0, st_C_typespec}, 2110 {"namespace", C_PLPL, st_C_struct},
2111 {"signed", 0, st_C_typespec},
2112 {""},
2113 {"interface", C_JAVA, st_C_struct},
2114 {"while", 0, st_C_ignore},
2119 {"typedef", 0, st_C_typedef}, 2115 {"typedef", 0, st_C_typedef},
2120 {"typename", C_PLPL, st_C_typespec}, 2116 {"typename", C_PLPL, st_C_typespec},
2121 {"unsigned", 0, st_C_typespec},
2122 {""}, {""},
2123 {"char", 0, st_C_typespec},
2124 {"class", C_PLPL, st_C_struct},
2125 {""}, {""}, {""}, 2117 {""}, {""}, {""},
2126 {"void", 0, st_C_typespec},
2127 {""}, {""},
2128 {"friend", C_PLPL, st_C_ignore}, 2118 {"friend", C_PLPL, st_C_ignore},
2129 {""}, {""}, {""}, 2119 {"mutable", C_PLPL, st_C_typespec},
2130 {"int", 0, st_C_typespec},
2131 {"union", 0, st_C_struct}, 2120 {"union", 0, st_C_struct},
2132 {""}, {""}, {""}, 2121 {"domain", C_STAR, st_C_struct},
2133 {"auto", 0, st_C_typespec}, 2122 {""}, {""},
2134 {"interface", C_JAVA, st_C_struct}, 2123 {"extern", 0, st_C_extern},
2124 {"extends", C_JAVA, st_C_javastruct},
2125 {"package", C_JAVA, st_C_ignore},
2126 {"short", 0, st_C_typespec},
2127 {"@end", 0, st_C_objend},
2128 {"unsigned", 0, st_C_typespec},
2129 {""},
2130 {"const", 0, st_C_typespec},
2131 {""}, {""},
2132 {"@interface", 0, st_C_objprot},
2133 {"enum", 0, st_C_enum},
2134 {""}, {""},
2135 {"@implementation",0, st_C_objimpl},
2135 {""}, 2136 {""},
2136 {"SYSCALL", 0, st_C_gnumacro} 2137 {"operator", C_PLPL, st_C_operator},
2138 {""}, {""}, {""}, {""},
2139 {"define", 0, st_C_define},
2140 {""}, {""},
2141 {"double", 0, st_C_typespec},
2142 {""},
2143 {"bool", C_PLPL, st_C_typespec},
2144 {""}, {""}, {""},
2145 {"DEFUN", 0, st_C_gnumacro},
2146 {"float", 0, st_C_typespec}
2137 }; 2147 };
2138 2148
2139 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 2149 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -2207,20 +2217,15 @@ enum
2207 */ 2217 */
2208enum 2218enum
2209{ 2219{
2210 snone, /* nothing seen yet */ 2220 snone, /* nothing seen yet,
2221 or in struct body if cblev > 0 */
2211 skeyseen, /* struct-like keyword seen */ 2222 skeyseen, /* struct-like keyword seen */
2212 stagseen, /* struct-like tag seen */ 2223 stagseen, /* struct-like tag seen */
2213 scolonseen, /* colon seen after struct-like tag */ 2224 sintemplate, /* inside template (ignore) */
2214 sinbody /* in struct body: recognize member func defs*/ 2225 scolonseen /* colon seen after struct-like tag */
2215} structdef; 2226} structdef;
2216 2227
2217/* 2228/*
2218 * When structdef is stagseen, scolonseen, or sinbody, structtype is the
2219 * type of the preceding struct-like keyword.
2220 */
2221char *structtag = "<uninited>";
2222
2223/*
2224 * When objdef is different from onone, objtag is the name of the class. 2229 * When objdef is different from onone, objtag is the name of the class.
2225 */ 2230 */
2226char *objtag = "<uninited>"; 2231char *objtag = "<uninited>";
@@ -2265,14 +2270,110 @@ struct tok
2265{ 2270{
2266 bool valid; 2271 bool valid;
2267 bool named; 2272 bool named;
2268 int linelen; 2273 int offset;
2274 int length;
2269 int lineno; 2275 int lineno;
2270 long linepos; 2276 long linepos;
2271 char *line; 2277 char *line;
2272} token; /* latest token read */ 2278} token; /* latest token read */
2273linebuffer token_name; /* its name */ 2279linebuffer token_name; /* its name */
2274 2280
2275static bool consider_token P_((char *, int, int, int, int, int, bool *)); 2281/*
2282 * Variables and functions for dealing with nested structures.
2283 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2284 */
2285static void pushclass_above P_((int, char *, int));
2286static void popclass_above P_((int));
2287static void write_classname P_((linebuffer *, char *qualifier));
2288
2289struct {
2290 char **cname; /* nested class names */
2291 int *cblev; /* nested class curly brace level */
2292 int nl; /* class nesting level (elements used) */
2293 int size; /* length of the array */
2294} cstack; /* stack for nested declaration tags */
2295/* Current struct nesting depth (namespace, class, struct, union, enum). */
2296#define nestlev (cstack.nl)
2297/* After struct keyword or in struct body, not inside an nested function. */
2298#define instruct (structdef == snone && nestlev > 0 \
2299 && cblev == cstack.cblev[nestlev-1] + 1)
2300
2301static void
2302pushclass_above (cblev, str, len)
2303 int cblev;
2304 char *str;
2305 int len;
2306{
2307 int nl;
2308
2309 popclass_above (cblev);
2310 nl = cstack.nl;
2311 if (nl >= cstack.size)
2312 {
2313 int size = cstack.size *= 2;
2314 xrnew (cstack.cname, size, char *);
2315 xrnew (cstack.cblev, size, int);
2316 }
2317 assert (nl == 0 || cstack.cblev[nl-1] < cblev);
2318 cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
2319 cstack.cblev[nl] = cblev;
2320 cstack.nl = nl + 1;
2321}
2322
2323static void
2324popclass_above (cblev)
2325 int cblev;
2326{
2327 int nl;
2328
2329 for (nl = cstack.nl - 1;
2330 nl >= 0 && cstack.cblev[nl] >= cblev;
2331 nl--)
2332 {
2333 if (cstack.cname[nl] != NULL)
2334 free (cstack.cname[nl]);
2335 cstack.nl = nl;
2336 }
2337}
2338
2339static void
2340write_classname (cn, qualifier)
2341 linebuffer *cn;
2342 char *qualifier;
2343{
2344 int i, len;
2345 int qlen = strlen (qualifier);
2346
2347 if (cstack.nl == 0 || cstack.cname[0] == NULL)
2348 {
2349 len = 0;
2350 cn->len = 0;
2351 cn->buffer[0] = '\0';
2352 }
2353 else
2354 {
2355 len = strlen (cstack.cname[0]);
2356 linebuffer_setlen (cn, len);
2357 strcpy (cn->buffer, cstack.cname[0]);
2358 }
2359 for (i = 1; i < cstack.nl; i++)
2360 {
2361 char *s;
2362 int slen;
2363
2364 s = cstack.cname[i];
2365 if (s == NULL)
2366 continue;
2367 slen = strlen (s);
2368 len += slen + qlen;
2369 linebuffer_setlen (cn, len);
2370 strncat (cn->buffer, qualifier, qlen);
2371 strncat (cn->buffer, s, slen);
2372 }
2373}
2374
2375
2376static bool consider_token P_((char *, int, int, int *, int, int, bool *));
2276static void make_C_tag P_((bool)); 2377static void make_C_tag P_((bool));
2277 2378
2278/* 2379/*
@@ -2282,7 +2383,7 @@ static void make_C_tag P_((bool));
2282 * is a struct/union/enum tag, or #define, or an enum constant. 2383 * is a struct/union/enum tag, or #define, or an enum constant.
2283 * 2384 *
2284 * *IS_FUNC gets TRUE iff the token is a function or #define macro 2385 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2285 * with args. C_EXT is which language we are looking at. 2386 * with args. C_EXTP points to which language we are looking at.
2286 * 2387 *
2287 * Globals 2388 * Globals
2288 * fvdef IN OUT 2389 * fvdef IN OUT
@@ -2293,22 +2394,24 @@ static void make_C_tag P_((bool));
2293 */ 2394 */
2294 2395
2295static bool 2396static bool
2296consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) 2397consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var)
2297 register char *str; /* IN: token pointer */ 2398 register char *str; /* IN: token pointer */
2298 register int len; /* IN: token length */ 2399 register int len; /* IN: token length */
2299 register int c; /* IN: first char after the token */ 2400 register int c; /* IN: first char after the token */
2300 int c_ext; /* IN: C extensions mask */ 2401 int *c_extp; /* IN, OUT: C extensions mask */
2301 int cblev; /* IN: curly brace level */ 2402 int cblev; /* IN: curly brace level */
2302 int parlev; /* IN: parenthesis level */ 2403 int parlev; /* IN: parenthesis level */
2303 bool *is_func_or_var; /* OUT: function or variable found */ 2404 bool *is_func_or_var; /* OUT: function or variable found */
2304{ 2405{
2305 /* When structdef is stagseen, scolonseen, or snone with cblev > 0, 2406 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2306 structtype is the type of the preceding struct-like keyword. */ 2407 structtype is the type of the preceding struct-like keyword, and
2408 structcblev is the curly brace level where it has been seen. */
2307 static enum sym_type structtype; 2409 static enum sym_type structtype;
2410 static int structcblev;
2308 static enum sym_type toktype; 2411 static enum sym_type toktype;
2309 2412
2310 2413
2311 toktype = C_symtype (str, len, c_ext); 2414 toktype = C_symtype (str, len, *c_extp);
2312 2415
2313 /* 2416 /*
2314 * Advance the definedef state machine. 2417 * Advance the definedef state machine.
@@ -2370,17 +2473,25 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2370 { 2473 {
2371 case st_none: 2474 case st_none:
2372 case st_C_typespec: 2475 case st_C_typespec:
2476 case st_C_class:
2373 case st_C_struct: 2477 case st_C_struct:
2374 case st_C_enum: 2478 case st_C_enum:
2375 typdef = ttypeseen; 2479 typdef = ttypeseen;
2376 break; 2480 break;
2377 } 2481 }
2378 /* Do not return here, so the structdef stuff has a chance. */ 2482 break;
2483 case ttypeseen:
2484 if (structdef == snone && fvdef == fvnone)
2485 {
2486 fvdef = fvnameseen;
2487 return TRUE;
2488 }
2379 break; 2489 break;
2380 case tend: 2490 case tend:
2381 switch (toktype) 2491 switch (toktype)
2382 { 2492 {
2383 case st_C_typespec: 2493 case st_C_typespec:
2494 case st_C_class:
2384 case st_C_struct: 2495 case st_C_struct:
2385 case st_C_enum: 2496 case st_C_enum:
2386 return FALSE; 2497 return FALSE;
@@ -2389,11 +2500,6 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2389 } 2500 }
2390 2501
2391 /* 2502 /*
2392 * This structdef business is currently only invoked when cblev==0.
2393 * It should be recursively invoked whatever the curly brace level,
2394 * and a stack of states kept, to allow for definitions of structs
2395 * within structs.
2396 *
2397 * This structdef business is NOT invoked when we are ctags and the 2503 * This structdef business is NOT invoked when we are ctags and the
2398 * file is plain C. This is because a struct tag may have the same 2504 * file is plain C. This is because a struct tag may have the same
2399 * name as another tag, and this loses with ctags. 2505 * name as another tag, and this loses with ctags.
@@ -2404,25 +2510,29 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2404 if (structdef == stagseen) 2510 if (structdef == stagseen)
2405 structdef = scolonseen; 2511 structdef = scolonseen;
2406 return FALSE; 2512 return FALSE;
2513 case st_C_class:
2514 if (cblev == 0
2515 && (*c_extp & C_AUTO) /* automatic detection of C++ language */
2516 && definedef == dnone && structdef == snone
2517 && typdef == tnone && fvdef == fvnone)
2518 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
2519 /* FALLTHRU */
2407 case st_C_struct: 2520 case st_C_struct:
2408 case st_C_enum: 2521 case st_C_enum:
2409 if (typdef == tkeyseen 2522 if (parlev == 0
2410 || (typedefs_or_cplusplus && cblev == 0 && structdef == snone)) 2523 && fvdef != vignore
2524 && (typdef == tkeyseen
2525 || (typedefs_or_cplusplus && structdef == snone)))
2411 { 2526 {
2412 structdef = skeyseen; 2527 structdef = skeyseen;
2413 structtype = toktype; 2528 structtype = toktype;
2529 structcblev = cblev;
2414 } 2530 }
2415 return FALSE; 2531 return FALSE;
2416 } 2532 }
2417 2533
2418 if (structdef == skeyseen) 2534 if (structdef == skeyseen)
2419 { 2535 {
2420 /* Save the tag for struct/union/class, for functions and variables
2421 that may be defined inside. */
2422 if (structtype == st_C_struct)
2423 structtag = savenstr (str, len);
2424 else
2425 structtag = "<enum>";
2426 structdef = stagseen; 2536 structdef = stagseen;
2427 return TRUE; 2537 return TRUE;
2428 } 2538 }
@@ -2517,21 +2627,33 @@ consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2517 *is_func_or_var = TRUE; 2627 *is_func_or_var = TRUE;
2518 return TRUE; 2628 return TRUE;
2519 case st_none: 2629 case st_none:
2520 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10)) 2630 if (constantypedefs
2521 { 2631 && structdef == snone
2522 fvdef = foperator; 2632 && structtype == st_C_enum && cblev > structcblev)
2523 *is_func_or_var = TRUE; 2633 return TRUE; /* enum constant */
2524 return TRUE;
2525 }
2526 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2527 return TRUE;
2528 switch (fvdef) 2634 switch (fvdef)
2529 { 2635 {
2530 case fdefunkey: 2636 case fdefunkey:
2637 if (cblev > 0)
2638 break;
2531 fvdef = fdefunname; /* GNU macro */ 2639 fvdef = fdefunname; /* GNU macro */
2532 *is_func_or_var = TRUE; 2640 *is_func_or_var = TRUE;
2533 return TRUE; 2641 return TRUE;
2534 case fvnone: 2642 case fvnone:
2643 if ((strneq (str, "asm", 3) && endtoken (str[3]))
2644 || (strneq (str, "__asm__", 7) && endtoken (str[7])))
2645 {
2646 fvdef = vignore;
2647 return FALSE;
2648 }
2649 if ((*c_extp & C_PLPL) && strneq (str+len-10, "::operator", 10))
2650 {
2651 fvdef = foperator;
2652 *is_func_or_var = TRUE;
2653 return TRUE;
2654 }
2655 if (cblev > 0 && !instruct)
2656 break;
2535 fvdef = fvnameseen; /* function or variable */ 2657 fvdef = fvnameseen; /* function or variable */
2536 *is_func_or_var = TRUE; 2658 *is_func_or_var = TRUE;
2537 return TRUE; 2659 return TRUE;
@@ -2600,17 +2722,20 @@ make_C_tag (isfun)
2600 char *name = NULL; 2722 char *name = NULL;
2601 2723
2602 if (CTAGS || token.named) 2724 if (CTAGS || token.named)
2725 name = savestr (token_name.buffer);
2726 if (DEBUG && !token.valid)
2603 { 2727 {
2604 name = savestr (token_name.buffer); 2728 if (token.named)
2605 if (!token.valid)
2606 name = concat (name, "##invalid##", ""); 2729 name = concat (name, "##invalid##", "");
2730 else
2731 name = savestr ("##invalid##");
2607 } 2732 }
2608 pfnote (name, isfun, 2733 pfnote (name, isfun, token.line,
2609 token.line, token.linelen, token.lineno, token.linepos); 2734 token.offset+token.length+1, token.lineno, token.linepos);
2610 } 2735 }
2611 else 2736 else
2612 new_pfnote (token_name.buffer, token_name.len, isfun, 2737 new_pfnote (token_name.buffer, token_name.len, isfun, token.line,
2613 token.line, token.linelen, token.lineno, token.linepos); 2738 token.offset+token.length+1, token.lineno, token.linepos);
2614 token.valid = FALSE; 2739 token.valid = FALSE;
2615 } 2740 }
2616} 2741}
@@ -2636,6 +2761,7 @@ C_entries (c_ext, inf)
2636 int qlen; /* length of qualifier */ 2761 int qlen; /* length of qualifier */
2637 int cblev; /* current curly brace level */ 2762 int cblev; /* current curly brace level */
2638 int parlev; /* current parenthesis level */ 2763 int parlev; /* current parenthesis level */
2764 int typdefcblev; /* cblev where a typedef struct body begun */
2639 bool incomm, inquote, inchar, quotednl, midtoken; 2765 bool incomm, inquote, inchar, quotednl, midtoken;
2640 bool cplpl, cjava; 2766 bool cplpl, cjava;
2641 bool yacc_rules; /* in the rules part of a yacc file */ 2767 bool yacc_rules; /* in the rules part of a yacc file */
@@ -2645,6 +2771,13 @@ C_entries (c_ext, inf)
2645 initbuffer (&token_name); 2771 initbuffer (&token_name);
2646 initbuffer (&lbs[0].lb); 2772 initbuffer (&lbs[0].lb);
2647 initbuffer (&lbs[1].lb); 2773 initbuffer (&lbs[1].lb);
2774 if (cstack.size == 0)
2775 {
2776 cstack.size = (DEBUG) ? 1 : 4;
2777 cstack.nl = 0;
2778 cstack.cname = xnew (cstack.size, char *);
2779 cstack.cblev = xnew (cstack.size, int);
2780 }
2648 2781
2649 tokoff = toklen = 0; /* keep compiler quiet */ 2782 tokoff = toklen = 0; /* keep compiler quiet */
2650 curndx = newndx = 0; 2783 curndx = newndx = 0;
@@ -2741,6 +2874,7 @@ C_entries (c_ext, inf)
2741 switch (fvdef) 2874 switch (fvdef)
2742 { 2875 {
2743 case fdefunkey: 2876 case fdefunkey:
2877 case fstartlist:
2744 case finlist: 2878 case finlist:
2745 case fignore: 2879 case fignore:
2746 case vignore: 2880 case vignore:
@@ -2775,7 +2909,7 @@ C_entries (c_ext, inf)
2775 case '%': 2909 case '%':
2776 if ((c_ext & YACC) && *lp == '%') 2910 if ((c_ext & YACC) && *lp == '%')
2777 { 2911 {
2778 /* entering or exiting rules section in yacc file */ 2912 /* Entering or exiting rules section in yacc file. */
2779 lp++; 2913 lp++;
2780 definedef = dnone; fvdef = fvnone; fvextern = FALSE; 2914 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2781 typdef = tnone; structdef = snone; 2915 typdef = tnone; structdef = snone;
@@ -2814,15 +2948,13 @@ C_entries (c_ext, inf)
2814 } /* switch (c) */ 2948 } /* switch (c) */
2815 2949
2816 2950
2817 /* Consider token only if some complicated conditions are satisfied. */ 2951 /* Consider token only if some involved conditions are satisfied. */
2818 if (typdef != tignore 2952 if (typdef != tignore
2819 && definedef != dignorerest 2953 && definedef != dignorerest
2820 && fvdef != finlist 2954 && fvdef != finlist
2955 && structdef != sintemplate
2821 && (definedef != dnone 2956 && (definedef != dnone
2822 || (cblev == 0 && structdef != scolonseen) 2957 || structdef != scolonseen))
2823 || (cblev == 1 && cplpl && structdef == sinbody)
2824 || (PUREC && structdef == sinbody))
2825 )
2826 { 2958 {
2827 if (midtoken) 2959 if (midtoken)
2828 { 2960 {
@@ -2846,7 +2978,7 @@ C_entries (c_ext, inf)
2846 2978
2847 if (yacc_rules 2979 if (yacc_rules
2848 || consider_token (newlb.buffer + tokoff, toklen, c, 2980 || consider_token (newlb.buffer + tokoff, toklen, c,
2849 c_ext, cblev, parlev, &funorvar)) 2981 &c_ext, cblev, parlev, &funorvar))
2850 { 2982 {
2851 if (fvdef == foperator) 2983 if (fvdef == foperator)
2852 { 2984 {
@@ -2861,15 +2993,13 @@ C_entries (c_ext, inf)
2861 toklen += lp - oldlp; 2993 toklen += lp - oldlp;
2862 } 2994 }
2863 token.named = FALSE; 2995 token.named = FALSE;
2864 if (!PUREC 2996 if ((c_ext & C_EXT) /* not pure C */
2865 && funorvar 2997 && nestlev > 0 && definedef == dnone)
2866 && definedef == dnone 2998 /* in struct body */
2867 && structdef == sinbody)
2868 /* function or var defined in C++ class body */
2869 { 2999 {
2870 int len = strlen (structtag) + qlen + toklen; 3000 write_classname (&token_name, qualifier);
2871 linebuffer_setlen (&token_name, len); 3001 linebuffer_setlen (&token_name,
2872 strcpy (token_name.buffer, structtag); 3002 token_name.len+qlen+toklen);
2873 strcat (token_name.buffer, qualifier); 3003 strcat (token_name.buffer, qualifier);
2874 strncat (token_name.buffer, 3004 strncat (token_name.buffer,
2875 newlb.buffer + tokoff, toklen); 3005 newlb.buffer + tokoff, toklen);
@@ -2894,6 +3024,7 @@ C_entries (c_ext, inf)
2894 token.named = TRUE; 3024 token.named = TRUE;
2895 } 3025 }
2896 else if (fvdef == fdefunname) 3026 else if (fvdef == fdefunname)
3027 /* GNU DEFUN and similar macros */
2897 { 3028 {
2898 bool defun = (newlb.buffer[tokoff] == 'F'); 3029 bool defun = (newlb.buffer[tokoff] == 'F');
2899 int off = tokoff; 3030 int off = tokoff;
@@ -2931,10 +3062,12 @@ C_entries (c_ext, inf)
2931 && definedef == dignorerest) 3062 && definedef == dignorerest)
2932 || (funorvar 3063 || (funorvar
2933 && definedef == dnone 3064 && definedef == dnone
2934 && structdef == sinbody)); 3065 && structdef == snone
3066 && cblev > 0));
2935 } 3067 }
2936 token.lineno = lineno; 3068 token.lineno = lineno;
2937 token.linelen = tokoff + toklen + 1; 3069 token.offset = tokoff;
3070 token.length = toklen;
2938 token.line = newlb.buffer; 3071 token.line = newlb.buffer;
2939 token.linepos = newlinepos; 3072 token.linepos = newlinepos;
2940 token.valid = TRUE; 3073 token.valid = TRUE;
@@ -2944,12 +3077,15 @@ C_entries (c_ext, inf)
2944 || fvdef == foperator 3077 || fvdef == foperator
2945 || structdef == stagseen 3078 || structdef == stagseen
2946 || typdef == tend 3079 || typdef == tend
3080 || typdef == ttypeseen
2947 || objdef != onone)) 3081 || objdef != onone))
2948 { 3082 {
2949 if (current_lb_is_new) 3083 if (current_lb_is_new)
2950 switch_line_buffers (); 3084 switch_line_buffers ();
2951 } 3085 }
2952 else 3086 else if (definedef != dnone
3087 || fvdef == fdefunname
3088 || instruct)
2953 make_C_tag (funorvar); 3089 make_C_tag (funorvar);
2954 } 3090 }
2955 midtoken = FALSE; 3091 midtoken = FALSE;
@@ -2981,7 +3117,10 @@ C_entries (c_ext, inf)
2981 break; 3117 break;
2982 } 3118 }
2983 if (structdef == stagseen && !cjava) 3119 if (structdef == stagseen && !cjava)
2984 structdef = snone; 3120 {
3121 popclass_above (cblev);
3122 structdef = snone;
3123 }
2985 break; 3124 break;
2986 case dsharpseen: 3125 case dsharpseen:
2987 savetoken = token; 3126 savetoken = token;
@@ -3002,6 +3141,11 @@ C_entries (c_ext, inf)
3002 switch (c) 3141 switch (c)
3003 { 3142 {
3004 case ':': 3143 case ':':
3144 if (yacc_rules && token.offset == 0 && token.valid)
3145 {
3146 make_C_tag (FALSE); /* a yacc function */
3147 break;
3148 }
3005 if (definedef != dnone) 3149 if (definedef != dnone)
3006 break; 3150 break;
3007 switch (objdef) 3151 switch (objdef)
@@ -3019,60 +3163,57 @@ C_entries (c_ext, inf)
3019 } 3163 }
3020 if (structdef == stagseen) 3164 if (structdef == stagseen)
3021 structdef = scolonseen; 3165 structdef = scolonseen;
3022 else
3023 switch (fvdef)
3024 {
3025 case fvnameseen:
3026 if (yacc_rules)
3027 {
3028 make_C_tag (FALSE); /* a yacc function */
3029 fvdef = fignore;
3030 }
3031 break;
3032 case fstartlist:
3033 fvextern = FALSE;
3034 fvdef = fvnone;
3035 break;
3036 }
3037 break; 3166 break;
3038 case ';': 3167 case ';':
3039 if (definedef != dnone) 3168 if (definedef != dnone)
3040 break; 3169 break;
3041 switch (fvdef) 3170 switch (typdef)
3042 { 3171 {
3043 case fignore: 3172 case tend:
3044 break; 3173 case ttypeseen:
3045 case fvnameseen: 3174 make_C_tag (FALSE); /* a typedef */
3046 if ((members && cblev == 1) 3175 typdef = tnone;
3047 || (globals && cblev == 0 && (!fvextern || declarations)))
3048 make_C_tag (FALSE); /* a variable */
3049 fvextern = FALSE;
3050 fvdef = fvnone; 3176 fvdef = fvnone;
3051 token.valid = FALSE;
3052 break; 3177 break;
3053 case flistseen: 3178 case tnone:
3054 if ((declarations && typdef == tnone && cblev == 0) 3179 case tinbody:
3055 || (members && cblev == 1)) 3180 case tignore:
3056 make_C_tag (TRUE); /* a function declaration */ 3181 switch (fvdef)
3182 {
3183 case fignore:
3184 if (typdef == tignore)
3185 fvdef = fvnone;
3186 break;
3187 case fvnameseen:
3188 if ((globals && cblev == 0 && (!fvextern || declarations))
3189 || (members && instruct))
3190 make_C_tag (FALSE); /* a variable */
3191 fvextern = FALSE;
3192 fvdef = fvnone;
3193 token.valid = FALSE;
3194 break;
3195 case flistseen:
3196 if ((declarations && typdef == tnone && !instruct)
3197 || (members && typdef != tignore && instruct))
3198 make_C_tag (TRUE); /* a function declaration */
3199 /* FALLTHRU */
3200 default:
3201 fvextern = FALSE;
3202 fvdef = fvnone;
3203 if (declarations
3204 && structdef == stagseen && (c_ext & C_PLPL))
3205 make_C_tag (FALSE); /* forward declaration */
3206 else
3207 /* The following instruction invalidates the token.
3208 Probably the token should be invalidated in all other
3209 cases where some state machine is reset prematurely. */
3210 token.valid = FALSE;
3211 } /* switch (fvdef) */
3057 /* FALLTHRU */ 3212 /* FALLTHRU */
3058 default: 3213 default:
3059 fvextern = FALSE; 3214 if (!instruct)
3060 fvdef = fvnone;
3061 if (typdef != tend)
3062 /* The following instruction invalidates the token.
3063 Probably the token should be invalidated in all other
3064 cases where some state machine is reset prematurely. */
3065 token.valid = FALSE;
3066 }
3067 if (cblev == 0)
3068 switch (typdef)
3069 {
3070 case tend:
3071 make_C_tag (FALSE); /* a typedef */
3072 /* FALLTHRU */
3073 default:
3074 typdef = tnone; 3215 typdef = tnone;
3075 } 3216 }
3076 if (structdef == stagseen) 3217 if (structdef == stagseen)
3077 structdef = snone; 3218 structdef = snone;
3078 break; 3219 break;
@@ -3091,6 +3232,7 @@ C_entries (c_ext, inf)
3091 { 3232 {
3092 case fdefunkey: 3233 case fdefunkey:
3093 case foperator: 3234 case foperator:
3235 case fstartlist:
3094 case finlist: 3236 case finlist:
3095 case fignore: 3237 case fignore:
3096 case vignore: 3238 case vignore:
@@ -3098,18 +3240,22 @@ C_entries (c_ext, inf)
3098 case fdefunname: 3240 case fdefunname:
3099 fvdef = fignore; 3241 fvdef = fignore;
3100 break; 3242 break;
3243 case fvnameseen: /* a variable */
3244 if ((globals && cblev == 0 && (!fvextern || declarations))
3245 || (members && instruct))
3246 make_C_tag (FALSE);
3247 break;
3101 case flistseen: /* a function */ 3248 case flistseen: /* a function */
3102 if (!declarations) 3249 if ((declarations && typdef == tnone && !instruct)
3250 || (members && typdef != tignore && instruct))
3103 { 3251 {
3104 fvdef = fvnone; 3252 make_C_tag (TRUE); /* a function declaration */
3105 break; 3253 fvdef = fvnameseen;
3106 } 3254 }
3107 /* FALLTHRU */ 3255 else if (!declarations)
3108 case fvnameseen: /* a variable */ 3256 fvdef = fvnone;
3109 if ((members && structdef == sinbody && cblev == 1) 3257 token.valid = FALSE;
3110 || (globals && cblev == 0 && (!fvextern || declarations))) 3258 break;
3111 make_C_tag (FALSE);
3112 /* FALLTHRU */
3113 default: 3259 default:
3114 fvdef = fvnone; 3260 fvdef = fvnone;
3115 } 3261 }
@@ -3119,29 +3265,35 @@ C_entries (c_ext, inf)
3119 case '[': 3265 case '[':
3120 if (definedef != dnone) 3266 if (definedef != dnone)
3121 break; 3267 break;
3122 if (cblev == 0 && typdef == tend) 3268 if (structdef == stagseen)
3269 structdef = snone;
3270 switch (typdef)
3123 { 3271 {
3272 case ttypeseen:
3273 case tend:
3124 typdef = tignore; 3274 typdef = tignore;
3125 make_C_tag (FALSE); /* a typedef */ 3275 make_C_tag (FALSE); /* a typedef */
3126 break; 3276 break;
3127 } 3277 case tnone:
3128 switch (fvdef) 3278 case tinbody:
3129 { 3279 switch (fvdef)
3130 case foperator: 3280 {
3131 case finlist: 3281 case foperator:
3132 case fignore: 3282 case finlist:
3133 case vignore: 3283 case fignore:
3284 case vignore:
3285 break;
3286 case fvnameseen:
3287 if ((members && cblev == 1)
3288 || (globals && cblev == 0
3289 && (!fvextern || declarations)))
3290 make_C_tag (FALSE); /* a variable */
3291 /* FALLTHRU */
3292 default:
3293 fvdef = fvnone;
3294 }
3134 break; 3295 break;
3135 case fvnameseen:
3136 if ((members && cblev == 1)
3137 || (globals && cblev == 0 && (!fvextern || declarations)))
3138 make_C_tag (FALSE); /* a variable */
3139 /* FALLTHRU */
3140 default:
3141 fvdef = fvnone;
3142 } 3296 }
3143 if (structdef == stagseen)
3144 structdef = snone;
3145 break; 3297 break;
3146 case '(': 3298 case '(':
3147 if (definedef != dnone) 3299 if (definedef != dnone)
@@ -3152,14 +3304,15 @@ C_entries (c_ext, inf)
3152 { 3304 {
3153 case fvnameseen: 3305 case fvnameseen:
3154 if (typdef == ttypeseen 3306 if (typdef == ttypeseen
3155 && token.valid
3156 && *lp != '*' 3307 && *lp != '*'
3157 && structdef != sinbody) 3308 && !instruct)
3158 { 3309 {
3159 /* This handles constructs like: 3310 /* This handles constructs like:
3160 typedef void OperatorFun (int fun); */ 3311 typedef void OperatorFun (int fun); */
3161 make_C_tag (FALSE); 3312 make_C_tag (FALSE);
3162 typdef = tignore; 3313 typdef = tignore;
3314 fvdef = fignore;
3315 break;
3163 } 3316 }
3164 /* FALLTHRU */ 3317 /* FALLTHRU */
3165 case foperator: 3318 case foperator:
@@ -3188,7 +3341,9 @@ C_entries (c_ext, inf)
3188 fvdef = flistseen; 3341 fvdef = flistseen;
3189 break; 3342 break;
3190 } 3343 }
3191 if (cblev == 0 && (typdef == tend)) 3344 if (!instruct
3345 && (typdef == tend
3346 || typdef == ttypeseen))
3192 { 3347 {
3193 typdef = tignore; 3348 typdef = tignore;
3194 make_C_tag (FALSE); /* a typedef */ 3349 make_C_tag (FALSE); /* a typedef */
@@ -3201,7 +3356,10 @@ C_entries (c_ext, inf)
3201 if (definedef != dnone) 3356 if (definedef != dnone)
3202 break; 3357 break;
3203 if (typdef == ttypeseen) 3358 if (typdef == ttypeseen)
3204 typdef = tinbody; 3359 {
3360 typdefcblev = cblev;
3361 typdef = tinbody;
3362 }
3205 switch (fvdef) 3363 switch (fvdef)
3206 { 3364 {
3207 case flistseen: 3365 case flistseen:
@@ -3224,20 +3382,22 @@ C_entries (c_ext, inf)
3224 break; 3382 break;
3225 default: 3383 default:
3226 /* Neutralize `extern "C" {' grot. */ 3384 /* Neutralize `extern "C" {' grot. */
3227 if (cblev == 0 && structdef == snone && typdef == tnone) 3385 if (cblev == 0 && structdef == snone && nestlev == 0
3386 && typdef == tnone)
3228 cblev = -1; 3387 cblev = -1;
3229 } 3388 }
3230 } 3389 }
3231 switch (structdef) 3390 switch (structdef)
3232 { 3391 {
3233 case skeyseen: /* unnamed struct */ 3392 case skeyseen: /* unnamed struct */
3234 structdef = sinbody; 3393 pushclass_above (cblev, NULL, 0);
3235 structtag = "_anonymous_"; 3394 structdef = snone;
3236 break; 3395 break;
3237 case stagseen: 3396 case stagseen: /* named struct or enum */
3238 case scolonseen: /* named struct */ 3397 case scolonseen: /* a class */
3239 structdef = sinbody; 3398 pushclass_above (cblev, token.line+token.offset, token.length);
3240 make_C_tag (FALSE); /* a struct */ 3399 structdef = snone;
3400 make_C_tag (FALSE); /* a struct or enum */
3241 break; 3401 break;
3242 } 3402 }
3243 cblev++; 3403 cblev++;
@@ -3258,20 +3418,12 @@ C_entries (c_ext, inf)
3258 } 3418 }
3259 else if (cblev > 0) 3419 else if (cblev > 0)
3260 cblev--; 3420 cblev--;
3261 if (cblev == 0) 3421 popclass_above (cblev);
3422 structdef = snone;
3423 if (typdef == tinbody && cblev <= typdefcblev)
3262 { 3424 {
3263 if (typdef == tinbody) 3425 assert (cblev == typdefcblev);
3264 typdef = tend; 3426 typdef = tend;
3265 /* Memory leakage here: the string pointed by structtag is
3266 never released, because I fear to miss something and
3267 break things while freeing the area. The amount of
3268 memory leaked here is the sum of the lengths of the
3269 struct tags.
3270 if (structdef == sinbody)
3271 free (structtag); */
3272
3273 structdef = snone;
3274 structtag = "<error>";
3275 } 3427 }
3276 break; 3428 break;
3277 case '=': 3429 case '=':
@@ -3293,6 +3445,20 @@ C_entries (c_ext, inf)
3293 fvdef = vignore; 3445 fvdef = vignore;
3294 } 3446 }
3295 break; 3447 break;
3448 case '<':
3449 if (cplpl && structdef == stagseen)
3450 {
3451 structdef = sintemplate;
3452 break;
3453 }
3454 goto resetfvdef;
3455 case '>':
3456 if (structdef == sintemplate)
3457 {
3458 structdef = stagseen;
3459 break;
3460 }
3461 goto resetfvdef;
3296 case '+': 3462 case '+':
3297 case '-': 3463 case '-':
3298 if (objdef == oinbody && cblev == 0) 3464 if (objdef == oinbody && cblev == 0)
@@ -3301,8 +3467,9 @@ C_entries (c_ext, inf)
3301 break; 3467 break;
3302 } 3468 }
3303 /* FALLTHRU */ 3469 /* FALLTHRU */
3470 resetfvdef:
3304 case '#': case '~': case '&': case '%': case '/': case '|': 3471 case '#': case '~': case '&': case '%': case '/': case '|':
3305 case '^': case '!': case '<': case '>': case '.': case '?': case ']': 3472 case '^': case '!': case '.': case '?': case ']':
3306 if (definedef != dnone) 3473 if (definedef != dnone)
3307 break; 3474 break;
3308 /* These surely cannot follow a function tag in C. */ 3475 /* These surely cannot follow a function tag in C. */
@@ -3346,10 +3513,10 @@ static void
3346default_C_entries (inf) 3513default_C_entries (inf)
3347 FILE *inf; 3514 FILE *inf;
3348{ 3515{
3349 C_entries (cplusplus ? C_PLPL : 0, inf); 3516 C_entries (cplusplus ? C_PLPL : C_AUTO, inf);
3350} 3517}
3351 3518
3352/* Always do plain ANSI C. */ 3519/* Always do plain C. */
3353static void 3520static void
3354plain_C_entries (inf) 3521plain_C_entries (inf)
3355 FILE *inf; 3522 FILE *inf;
@@ -5071,6 +5238,7 @@ free_patterns ()
5071 } 5238 }
5072 return; 5239 return;
5073} 5240}
5241#endif /* ETAGS_REGEXPS */
5074 5242
5075 5243
5076static void 5244static void
@@ -5090,7 +5258,6 @@ get_tag (bp)
5090 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 5258 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
5091} 5259}
5092 5260
5093#endif /* ETAGS_REGEXPS */
5094/* Initialize a linebuffer for use */ 5261/* Initialize a linebuffer for use */
5095static void 5262static void
5096initbuffer (lbp) 5263initbuffer (lbp)
@@ -5405,7 +5572,7 @@ etags_getcwd ()
5405 return path; 5572 return path;
5406 5573
5407#else /* not HAVE_GETCWD */ 5574#else /* not HAVE_GETCWD */
5408#ifdef MSDOS 5575#if MSDOS
5409 5576
5410 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ 5577 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
5411 5578