diff options
| author | Francesco Potortì | 2001-01-28 16:14:04 +0000 |
|---|---|---|
| committer | Francesco Potortì | 2001-01-28 16:14:04 +0000 |
| commit | 8c463abe32e451893e5512b0e0dd6213661c2c8b (patch) | |
| tree | 2dc00ab0642d78a235ec0d4fa040737ec995206c /lib-src | |
| parent | b179a3a28f7dcd67532d0122c01837bf9a0e999c (diff) | |
| download | emacs-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/ChangeLog | 25 | ||||
| -rw-r--r-- | lib-src/etags.1 | 9 | ||||
| -rw-r--r-- | lib-src/etags.c | 665 |
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 @@ | |||
| 1 | 2001-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 | |||
| 1 | 2001-01-27 Eli Zaretskii <eliz@is.elta.co.il> | 24 | 2001-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 | ||
| 5 | 2001-01-26 Gerd Moellmann <gerd@gnu.org> | 28 | 2001-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 | |||
| 81 | through files. | 81 | through files. |
| 82 | Only \fBctags\fP accepts this option. | 82 | Only \fBctags\fP accepts this option. |
| 83 | .TP | 83 | .TP |
| 84 | .B \-C, \-\-c++ | ||
| 85 | Treat files with `\|.c\|' and `\|.h\|' extensions as C++ code, not C | ||
| 86 | code. 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 |
| 90 | In C and derived languages, create tags for function declarations, | 85 | In C and derived languages, create tags for function declarations, |
| 91 | and create tags for extern variables unless \-\-no\-globals is used. | 86 | and 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 | ||
| 35 | char pot_etags_version[] = "@(#) pot number is $Revision: 2.79 $"; | 35 | char 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\ | |||
| 601 | the first line of the file is read for a sharp-bang (#!) sequence\n\ | 603 | the first line of the file is read for a sharp-bang (#!) sequence\n\ |
| 602 | followed by the name of an interpreter. If no such sequence is found,\n\ | 604 | followed by the name of an interpreter. If no such sequence is found,\n\ |
| 603 | Fortran is tried first; if no tags are found, C is tried next.\n\ | 605 | Fortran is tried first; if no tags are found, C is tried next.\n\ |
| 606 | When parsing any C file, a \"class\" keyword switches to C++.\n\ | ||
| 604 | Compressed files are supported using gzip and bzip2."); | 607 | Compressed 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 | |||
| 1949 | extends, C_JAVA, st_C_javastruct | 1959 | extends, C_JAVA, st_C_javastruct |
| 1950 | implements, C_JAVA, st_C_javastruct | 1960 | implements, C_JAVA, st_C_javastruct |
| 1951 | interface, C_JAVA, st_C_struct | 1961 | interface, C_JAVA, st_C_struct |
| 1952 | class, C_PLPL, st_C_struct | 1962 | class, 0, st_C_class |
| 1953 | namespace, C_PLPL, st_C_struct | 1963 | namespace, C_PLPL, st_C_struct |
| 1954 | domain, C_STAR, st_C_struct | 1964 | domain, C_STAR, st_C_struct |
| 1955 | union, 0, st_C_struct | 1965 | union, 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 | %] |
| 1989 | and replace lines between %< and %> with its output. */ | 1999 | and replace lines between %< and %> with its output, |
| 2000 | then 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 |
| 2057 | static struct C_stab_entry * | 2068 | struct C_stab_entry * |
| 2058 | in_word_set (str, len) | 2069 | in_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 | */ |
| 2208 | enum | 2218 | enum |
| 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 | */ | ||
| 2221 | char *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 | */ |
| 2226 | char *objtag = "<uninited>"; | 2231 | char *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 */ |
| 2273 | linebuffer token_name; /* its name */ | 2279 | linebuffer token_name; /* its name */ |
| 2274 | 2280 | ||
| 2275 | static 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 | */ | ||
| 2285 | static void pushclass_above P_((int, char *, int)); | ||
| 2286 | static void popclass_above P_((int)); | ||
| 2287 | static void write_classname P_((linebuffer *, char *qualifier)); | ||
| 2288 | |||
| 2289 | struct { | ||
| 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 | |||
| 2301 | static void | ||
| 2302 | pushclass_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 | |||
| 2323 | static void | ||
| 2324 | popclass_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 | |||
| 2339 | static void | ||
| 2340 | write_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 | |||
| 2376 | static bool consider_token P_((char *, int, int, int *, int, int, bool *)); | ||
| 2276 | static void make_C_tag P_((bool)); | 2377 | static 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 | ||
| 2295 | static bool | 2396 | static bool |
| 2296 | consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) | 2397 | consider_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 | |||
| 3346 | default_C_entries (inf) | 3513 | default_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. */ |
| 3353 | static void | 3520 | static void |
| 3354 | plain_C_entries (inf) | 3521 | plain_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 | ||
| 5076 | static void | 5244 | static 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 */ |
| 5095 | static void | 5262 | static void |
| 5096 | initbuffer (lbp) | 5263 | initbuffer (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 | ||