[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lib-src/etags.c
From: |
Francesco Potortì |
Subject: |
[Emacs-diffs] Changes to emacs/lib-src/etags.c |
Date: |
Tue, 05 Mar 2002 06:28:28 -0500 |
Index: emacs/lib-src/etags.c
diff -c emacs/lib-src/etags.c:3.7 emacs/lib-src/etags.c:3.8
*** emacs/lib-src/etags.c:3.7 Wed Dec 26 17:11:21 2001
--- emacs/lib-src/etags.c Tue Mar 5 06:28:26 2002
***************
*** 33,39 ****
* Francesco Potortì <address@hidden> has maintained it since 1993.
*/
! char pot_etags_version[] = "@(#) pot revision number is 14.35";
#define TRUE 1
#define FALSE 0
--- 33,39 ----
* Francesco Potortì <address@hidden> has maintained it since 1993.
*/
! char pot_etags_version[] = "@(#) pot revision number is 14.39";
#define TRUE 1
#define FALSE 0
***************
*** 299,311 ****
static void print_version __P((void));
static void print_help __P((void));
int main __P((int, char **));
- static int number_len __P((long));
static compressor *get_compressor_from_suffix __P((char *, char **));
static language *get_language_from_langname __P((const char *));
static language *get_language_from_interpreter __P((char *));
static language *get_language_from_filename __P((char *));
- static int total_size_of_entries __P((node *));
static long readline __P((linebuffer *, FILE *));
static long readline_internal __P((linebuffer *, FILE *));
static bool nocase_tail __P((char *));
--- 299,309 ----
***************
*** 345,377 ****
static bool filename_is_absolute __P((char *f));
static void canonicalize_filename __P((char *));
static void linebuffer_setlen __P((linebuffer *, int));
! PTR xmalloc __P((unsigned int));
! PTR xrealloc __P((char *, unsigned int));
! char searchar = '/'; /* use /.../ searches */
!
! char *tagfile; /* output file */
! char *progname; /* name this program was invoked with */
! char *cwd; /* current working directory */
! char *tagfiledir; /* directory of tagfile */
! FILE *tagf; /* ioptr for tags file */
! char *curfile; /* current input file name */
! language *curlang; /* current language */
! int lineno; /* line number of current line */
! long charno; /* current character number */
! long linecharno; /* charno of start of current line */
! char *dbp; /* pointer to start of current tag */
! node *head; /* the head of the binary tree of tags */
!
! linebuffer lb; /* the current line */
/* boolean "functions" (see init) */
! bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
! char
/* white chars */
*white = " \f\t\n\r\v",
/* not in a name */
--- 343,377 ----
static bool filename_is_absolute __P((char *f));
static void canonicalize_filename __P((char *));
static void linebuffer_setlen __P((linebuffer *, int));
! static PTR xmalloc __P((unsigned int));
! static PTR xrealloc __P((char *, unsigned int));
! static char searchar = '/'; /* use /.../ searches */
! static char *tagfile; /* output file */
! static char *progname; /* name this program was invoked with */
! static char *cwd; /* current working directory */
! static char *tagfiledir; /* directory of tagfile */
! static FILE *tagf; /* ioptr for tags file */
!
! static char *curfile; /* current input file name */
! static language *curlang; /* current language */
!
! static int lineno; /* line number of current line */
! static long charno; /* current character number */
! static long linecharno; /* charno of start of current line */
! static char *dbp; /* pointer to start of current tag */
! static bool nocharno; /* only use line number when making tag */
! static const int invalidcharno = -1;
! static node *head; /* the head of the binary tree of tags */
! static linebuffer lb; /* the current line */
/* boolean "functions" (see init) */
! static bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
! static char
/* white chars */
*white = " \f\t\n\r\v",
/* not in a name */
***************
*** 383,440 ****
/* valid in-token chars */
*midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
! bool append_to_tagfile; /* -a: append to tags */
/* The following four default to TRUE for etags, but to FALSE for ctags. */
! bool typedefs; /* -t: create tags for C and Ada
typedefs */
! bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
/* 0 struct/enum/union decls, and C++ */
/* member functions. */
! bool constantypedefs; /* -d: create tags for C #define, enum */
/* constants and variables. */
/* -D: opposite of -d. Default under ctags. */
! bool declarations; /* --declarations: tag them and extern in C&Co*/
! bool globals; /* create tags for global variables */
! bool members; /* create tags for C member variables */
! bool update; /* -u: update tags */
! bool vgrind_style; /* -v: create vgrind style index output */
! bool no_warnings; /* -w: suppress warnings */
! bool cxref_style; /* -x: create cxref style output */
! bool cplusplus; /* .[hc] means C++, not C */
! bool noindentypedefs; /* -I: ignore indentation in C */
! bool packages_only; /* --packages-only: in Ada, only tag packages*/
#ifdef LONG_OPTIONS
! struct option longopts[] =
{
! { "packages-only", no_argument, &packages_only, TRUE },
! { "append", no_argument, NULL, 'a' },
! { "backward-search", no_argument, NULL, 'B' },
! { "c++", no_argument, NULL, 'C' },
! { "cxref", no_argument, NULL, 'x' },
! { "defines", no_argument, NULL, 'd' },
! { "declarations", no_argument, &declarations, TRUE },
! { "no-defines", no_argument, NULL, 'D' },
! { "globals", no_argument, &globals, TRUE },
! { "no-globals", no_argument, &globals, FALSE },
! { "help", no_argument, NULL, 'h' },
! { "help", no_argument, NULL, 'H' },
! { "ignore-indentation", no_argument, NULL, 'I' },
! { "include", required_argument, NULL, 'i' },
! { "language", required_argument, NULL, 'l' },
! { "members", no_argument, &members, TRUE },
! { "no-members", no_argument, &members, FALSE },
! { "no-warn", no_argument, NULL, 'w' },
! { "output", required_argument, NULL, 'o' },
#ifdef ETAGS_REGEXPS
! { "regex", required_argument, NULL, 'r' },
! { "no-regex", no_argument, NULL, 'R' },
! { "ignore-case-regex", required_argument, NULL, 'c' },
#endif /* ETAGS_REGEXPS */
! { "typedefs", no_argument, NULL, 't' },
! { "typedefs-and-c++", no_argument, NULL, 'T' },
! { "update", no_argument, NULL, 'u' },
! { "version", no_argument, NULL, 'V' },
! { "vgrind", no_argument, NULL, 'v' },
{ NULL }
};
#endif /* LONG_OPTIONS */
--- 383,442 ----
/* valid in-token chars */
*midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
! static bool append_to_tagfile; /* -a: append to tags */
/* The following four default to TRUE for etags, but to FALSE for ctags. */
! static bool typedefs; /* -t: create tags for C and Ada typedefs */
! static bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
/* 0 struct/enum/union decls, and C++ */
/* member functions. */
! static bool constantypedefs; /* -d: create tags for C #define, enum */
/* constants and variables. */
/* -D: opposite of -d. Default under ctags. */
! static bool declarations; /* --declarations: tag them and extern in C&Co*/
! static bool globals; /* create tags for global variables */
! static bool no_line_directive; /* ignore #line directives */
! static bool members; /* create tags for C member variables */
! static bool update; /* -u: update tags */
! static bool vgrind_style; /* -v: create vgrind style index output */
! static bool no_warnings; /* -w: suppress warnings */
! static bool cxref_style; /* -x: create cxref style output */
! static bool cplusplus; /* .[hc] means C++, not C */
! static bool noindentypedefs; /* -I: ignore indentation in C */
! static bool packages_only; /* --packages-only: in Ada, only tag packages*/
#ifdef LONG_OPTIONS
! static struct option longopts[] =
{
! { "packages-only", no_argument, &packages_only, TRUE
},
! { "append", no_argument, NULL, 'a' },
! { "backward-search", no_argument, NULL, 'B'
},
! { "c++", no_argument, NULL, 'C' },
! { "cxref", no_argument, NULL, 'x' },
! { "defines", no_argument, NULL, 'd'
},
! { "declarations", no_argument, &declarations, TRUE },
! { "no-defines", no_argument, NULL, 'D' },
! { "globals", no_argument, &globals, TRUE
},
! { "no-globals", no_argument, &globals, FALSE },
! { "no-line-directive", no_argument, &no_line_directive, TRUE
},
! { "help", no_argument, NULL, 'h' },
! { "help", no_argument, NULL, 'H' },
! { "ignore-indentation", no_argument, NULL, 'I'
},
! { "include", required_argument, NULL, 'i'
},
! { "language", required_argument, NULL, 'l'
},
! { "members", no_argument, &members, TRUE
},
! { "no-members", no_argument, &members, FALSE },
! { "no-warn", no_argument, NULL, 'w'
},
! { "output", required_argument, NULL, 'o' },
#ifdef ETAGS_REGEXPS
! { "regex", required_argument, NULL, 'r' },
! { "no-regex", no_argument, NULL, 'R'
},
! { "ignore-case-regex", required_argument, NULL, 'c' },
#endif /* ETAGS_REGEXPS */
! { "typedefs", no_argument, NULL, 't'
},
! { "typedefs-and-c++", no_argument, NULL, 'T'
},
! { "update", no_argument, NULL, 'u' },
! { "version", no_argument, NULL, 'V'
},
! { "vgrind", no_argument, NULL, 'v' },
{ NULL }
};
#endif /* LONG_OPTIONS */
***************
*** 454,468 ****
} pattern;
/* List of all regexps. */
! pattern *p_head = NULL;
/* How many characters in the character set. (From regex.c.) */
#define CHAR_SET_SIZE 256
/* Translation table for case-insensitive matching. */
! char lc_trans[CHAR_SET_SIZE];
#endif /* ETAGS_REGEXPS */
! compressor compressors[] =
{
{ "z", "gzip -d -c"},
{ "Z", "gzip -d -c"},
--- 456,470 ----
} pattern;
/* List of all regexps. */
! static pattern *p_head = NULL;
/* How many characters in the character set. (From regex.c.) */
#define CHAR_SET_SIZE 256
/* Translation table for case-insensitive matching. */
! static char lc_trans[CHAR_SET_SIZE];
#endif /* ETAGS_REGEXPS */
! static compressor compressors[] =
{
{ "z", "gzip -d -c"},
{ "Z", "gzip -d -c"},
***************
*** 477,570 ****
*/
/* Non-NULL if language fixed. */
! language *forced_lang = NULL;
/* Ada code */
! char *Ada_suffixes [] =
{ "ads", "adb", "ada", NULL };
/* Assembly code */
! char *Asm_suffixes [] = { "a", /* Unix assembler */
! "asm", /* Microcontroller assembly */
! "def", /* BSO/Tasking definition includes */
! "inc", /* Microcontroller include files */
! "ins", /* Microcontroller include files */
! "s", "sa", /* Unix assembler */
! "S", /* cpp-processed Unix assembler */
! "src", /* BSO/Tasking C compiler output */
! NULL
! };
/* Note that .c and .h can be considered C++, if the --c++ flag was
given, or if the `class' keyowrd is met inside the file.
That is why default_C_entries is called for these. */
! char *default_C_suffixes [] =
{ "c", "h", NULL };
! char *Cplusplus_suffixes [] =
{ "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
"M", /* Objective C++ */
"pdb", /* Postscript with C syntax */
NULL };
! char *Cjava_suffixes [] =
{ "java", NULL };
! char *Cobol_suffixes [] =
{ "COB", "cob", NULL };
! char *Cstar_suffixes [] =
{ "cs", "hs", NULL };
! char *Erlang_suffixes [] =
{ "erl", "hrl", NULL };
! char *Fortran_suffixes [] =
{ "F", "f", "f90", "for", NULL };
! char *Lisp_suffixes [] =
{ "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL };
! char *Makefile_filenames [] =
{ "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am",
NULL};
! char *Pascal_suffixes [] =
{ "p", "pas", NULL };
! char *Perl_suffixes [] =
{ "pl", "pm", NULL };
! char *Perl_interpreters [] =
{ "perl", "@PERL@", NULL };
! char *PHP_suffixes [] =
{ "php", "php3", "php4", NULL };
! char *plain_C_suffixes [] =
{ "lm", /* Objective lex file */
"m", /* Objective C file */
"pc", /* Pro*C file */
NULL };
! char *Postscript_suffixes [] =
{ "ps", "psw", NULL }; /* .psw is for PSWrap */
! char *Prolog_suffixes [] =
{ "prolog", NULL };
! char *Python_suffixes [] =
{ "py", NULL };
/* Can't do the `SCM' or `scm' prefix with a version number. */
! char *Scheme_suffixes [] =
{ "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL };
! char *TeX_suffixes [] =
{ "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL };
! char *Texinfo_suffixes [] =
{ "texi", "texinfo", "txi", NULL };
! char *Yacc_suffixes [] =
{ "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */
/*
--- 479,574 ----
*/
/* Non-NULL if language fixed. */
! static language *forced_lang = NULL;
/* Ada code */
! static char *Ada_suffixes [] =
{ "ads", "adb", "ada", NULL };
/* Assembly code */
! static char *Asm_suffixes [] =
! { "a", /* Unix assembler */
! "asm", /* Microcontroller assembly */
! "def", /* BSO/Tasking definition includes */
! "inc", /* Microcontroller include files */
! "ins", /* Microcontroller include files */
! "s", "sa", /* Unix assembler */
! "S", /* cpp-processed Unix assembler */
! "src", /* BSO/Tasking C compiler output */
! NULL
! };
/* Note that .c and .h can be considered C++, if the --c++ flag was
given, or if the `class' keyowrd is met inside the file.
That is why default_C_entries is called for these. */
! static char *default_C_suffixes [] =
{ "c", "h", NULL };
! static char *Cplusplus_suffixes [] =
{ "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
"M", /* Objective C++ */
"pdb", /* Postscript with C syntax */
NULL };
! static char *Cjava_suffixes [] =
{ "java", NULL };
! static char *Cobol_suffixes [] =
{ "COB", "cob", NULL };
! static char *Cstar_suffixes [] =
{ "cs", "hs", NULL };
! static char *Erlang_suffixes [] =
{ "erl", "hrl", NULL };
! static char *Fortran_suffixes [] =
{ "F", "f", "f90", "for", NULL };
! static char *Lisp_suffixes [] =
{ "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL };
! static char *Makefile_filenames [] =
{ "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am",
NULL};
! static char *Pascal_suffixes [] =
{ "p", "pas", NULL };
! static char *Perl_suffixes [] =
{ "pl", "pm", NULL };
!
! static char *Perl_interpreters [] =
{ "perl", "@PERL@", NULL };
! static char *PHP_suffixes [] =
{ "php", "php3", "php4", NULL };
! static char *plain_C_suffixes [] =
{ "lm", /* Objective lex file */
"m", /* Objective C file */
"pc", /* Pro*C file */
NULL };
! static char *Postscript_suffixes [] =
{ "ps", "psw", NULL }; /* .psw is for PSWrap */
! static char *Prolog_suffixes [] =
{ "prolog", NULL };
! static char *Python_suffixes [] =
{ "py", NULL };
/* Can't do the `SCM' or `scm' prefix with a version number. */
! static char *Scheme_suffixes [] =
{ "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL };
! static char *TeX_suffixes [] =
{ "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL };
! static char *Texinfo_suffixes [] =
{ "texi", "texinfo", "txi", NULL };
! static char *Yacc_suffixes [] =
{ "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */
/*
***************
*** 574,580 ****
* name. I just didn't.
*/
! language lang_names [] =
{
{ "ada", Ada_funcs, NULL, Ada_suffixes,
NULL },
{ "asm", Asm_labels, NULL, Asm_suffixes,
NULL },
--- 578,584 ----
* name. I just didn't.
*/
! static language lang_names [] =
{
{ "ada", Ada_funcs, NULL, Ada_suffixes,
NULL },
{ "asm", Asm_labels, NULL, Asm_suffixes,
NULL },
***************
*** 1042,1048 ****
}
}
break;
- #ifdef ETAGS_REGEXPS
case 'r':
argbuffer[current_arg].arg_type = at_regexp;
argbuffer[current_arg].what = optarg;
--- 1046,1051 ----
***************
*** 1058,1064 ****
argbuffer[current_arg].what = optarg;
++current_arg;
break;
- #endif /* ETAGS_REGEXPS */
case 'V':
print_version ();
break;
--- 1061,1066 ----
***************
*** 1072,1090 ****
case 'T':
typedefs = typedefs_or_cplusplus = TRUE;
break;
- #if (!CTAGS)
/* Etags options */
case 'i':
included_files[nincluded_files++] = optarg;
break;
- #else /* CTAGS */
/* Ctags options. */
case 'B': searchar = '?'; break;
case 'u': update = TRUE; break;
case 'v': vgrind_style = TRUE; /*FALLTHRU*/
case 'x': cxref_style = TRUE; break;
case 'w': no_warnings = TRUE; break;
- #endif /* CTAGS */
default:
suggest_asking_for_help ();
}
--- 1074,1089 ----
***************
*** 1193,1214 ****
free_patterns ();
#endif /* ETAGS_REGEXPS */
! if (!CTAGS)
! {
! while (nincluded_files-- > 0)
! fprintf (tagf, "\f\n%s,include\n", *included_files++);
!
! fclose (tagf);
! exit (GOOD);
! }
!
! /* If CTAGS, we are here. process_file did not write the tags yet,
! because we want them ordered. Let's do it now. */
! if (cxref_style)
{
put_entries (head);
free_tree (head);
head = NULL;
exit (GOOD);
}
--- 1192,1208 ----
free_patterns ();
#endif /* ETAGS_REGEXPS */
! if (!CTAGS || cxref_style)
{
put_entries (head);
free_tree (head);
head = NULL;
+ if (!CTAGS)
+ while (nincluded_files-- > 0)
+ fprintf (tagf, "\f\n%s,include\n", *included_files++);
+
+ if (fclose (tagf) == EOF)
+ pfatal (tagfile);
exit (GOOD);
}
***************
*** 1234,1240 ****
put_entries (head);
free_tree (head);
head = NULL;
! fclose (tagf);
if (update)
{
--- 1228,1235 ----
put_entries (head);
free_tree (head);
head = NULL;
! if (fclose (tagf) == EOF)
! pfatal (tagfile);
if (update)
{
***************
*** 1379,1384 ****
--- 1374,1380 ----
compressor *compr;
char *compressed_name, *uncompressed_name;
char *ext, *real_name;
+ int retval;
canonicalize_filename (file);
***************
*** 1486,1519 ****
goto exit;
}
find_entries (uncompressed_name, inf);
if (real_name == compressed_name)
! pclose (inf);
else
! fclose (inf);
!
! if (!CTAGS)
! {
! char *filename;
!
! if (filename_is_absolute (uncompressed_name))
! {
! /* file is an absolute file name. Canonicalise it. */
! filename = absolute_filename (uncompressed_name, cwd);
! }
! else
! {
! /* file is a file name relative to cwd. Make it relative
! to the directory of the tags file. */
! filename = relative_filename (uncompressed_name, tagfiledir);
! }
! fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head));
! free (filename);
! put_entries (head);
! free_tree (head);
! head = NULL;
! }
exit:
if (compressed_name) free(compressed_name);
--- 1482,1507 ----
goto exit;
}
+ if (filename_is_absolute (uncompressed_name))
+ {
+ /* file is an absolute file name. Canonicalise it. */
+ curfile = absolute_filename (uncompressed_name, cwd);
+ }
+ else
+ {
+ /* file is a file name relative to cwd. Make it relative
+ to the directory of the tags file. */
+ curfile = relative_filename (uncompressed_name, tagfiledir);
+ }
+ nocharno = FALSE; /* use char position when making tags */
find_entries (uncompressed_name, inf);
if (real_name == compressed_name)
! retval = pclose (inf);
else
! retval = fclose (inf);
! if (retval < 0)
! pfatal (file);
exit:
if (compressed_name) free(compressed_name);
***************
*** 1552,1558 ****
* This routine opens the specified file and calls the function
* which finds the function and type definitions.
*/
! node *last_node = NULL;
static void
find_entries (file, inf)
--- 1540,1546 ----
* This routine opens the specified file and calls the function
* which finds the function and type definitions.
*/
! static node *last_node = NULL;
static void
find_entries (file, inf)
***************
*** 1563,1575 ****
language *lang;
node *old_last_node;
- /* Memory leakage here: the string pointed by curfile is
- never released, because curfile is copied into np->file
- for each node, to be used in CTAGS mode. The amount of
- memory leaked here is the sum of the lengths of the
- file names. */
- curfile = savestr (file);
-
/* If user specified a language, use it. */
lang = forced_lang;
if (lang != NULL && lang->function != NULL)
--- 1551,1556 ----
***************
*** 1673,1684 ****
np->file = curfile;
np->is_func = is_func;
np->lno = lno;
! /* Our char numbers are 0-base, because of C language tradition?
! ctags compatibility? old versions compatibility? I don't know.
! Anyway, since emacs's are 1-base we expect etags.el to take care
! of the difference. If we wanted to have 1-based numbers, we would
! uncomment the +1 below. */
! np->cno = cno /* + 1 */ ;
np->left = np->right = NULL;
if (CTAGS && !cxref_style)
{
--- 1654,1668 ----
np->file = curfile;
np->is_func = is_func;
np->lno = lno;
! if (nocharno)
! np->cno = invalidcharno;
! else
! /* Our char numbers are 0-base, because of C language tradition?
! ctags compatibility? old versions compatibility? I don't know.
! Anyway, since emacs's are 1-base we expect etags.el to take care
! of the difference. If we wanted to have 1-based numbers, we would
! uncomment the +1 below. */
! np->cno = cno /* + 1 */ ;
np->left = np->right = NULL;
if (CTAGS && !cxref_style)
{
***************
*** 1771,1779 ****
/*
* add_node ()
! * Adds a node to the tree of nodes. In etags mode, we don't keep
! * it sorted; we just keep a linear list. In ctags mode, maintain
! * an ordered tree, with no attempt at balancing.
*
* add_node is the only function allowed to add nodes, so it can
* maintain state.
--- 1755,1763 ----
/*
* add_node ()
! * Adds a node to the tree of nodes. In etags mode, sort by file
! * name. In ctags mode, sort by tag name. Make no attempt at
! * balancing.
*
* add_node is the only function allowed to add nodes, so it can
* maintain state.
***************
*** 1795,1804 ****
if (!CTAGS)
{
/* Etags Mode */
! if (last_node == NULL)
! fatal ("internal error in add_node", (char *)NULL);
! last_node->right = np;
! last_node = np;
}
else
{
--- 1779,1805 ----
if (!CTAGS)
{
/* Etags Mode */
! assert (last_node != NULL);
! /* For each file name, tags are in a linked sublist on the right
! pointer. The first tags of different files are a linked list
! on the left pointer. last_node points to the end of the last
! used sublist. */
! if (last_node->file == np->file)
! {
! /* Let's use the same sublist as the last added node. */
! last_node->right = np;
! last_node = np;
! }
! else if (streq (cur_node->file, np->file))
! {
! /* Scanning the list we found the head of a sublist which is
! good for us. Let's scan this sublist. */
! add_node (np, &cur_node->right);
! }
! else
! /* The head of this sublist is not good for us. Let's try the
! next one. */
! add_node (np, &cur_node->left);
}
else
{
***************
*** 1837,1867 ****
}
static void
put_entries (np)
register node *np;
{
register char *sp;
if (np == NULL)
return;
/* Output subentries that precede this one */
! put_entries (np->left);
/* Output this entry */
-
if (!CTAGS)
{
if (np->name != NULL)
! fprintf (tagf, "%s\177%s\001%d,%ld\n",
! np->pat, np->name, np->lno, np->cno);
else
! fprintf (tagf, "%s\177%d,%ld\n",
! np->pat, np->lno, np->cno);
}
else
{
if (np->name == NULL)
error ("internal error: NULL name in ctags mode.", (char *)NULL);
--- 1838,1926 ----
}
+ #if !CTAGS
+ static int total_size_of_entries __P((node *));
+ static int number_len __P((long));
+
+ /* Length of a number's decimal representation. */
+ static int
+ number_len (num)
+ long num;
+ {
+ int len = 1;
+ while ((num /= 10) > 0)
+ len += 1;
+ return len;
+ }
+
+ /*
+ * Return total number of characters that put_entries will output for
+ * the nodes in the linked list at the right of the specified node.
+ * This count is irrelevant with etags.el since emacs 19.34 at least,
+ * but is still supplied for backward compatibility.
+ */
+ static int
+ total_size_of_entries (np)
+ register node *np;
+ {
+ register int total = 0;
+
+ for (; np != NULL; np = np->right)
+ {
+ total += strlen (np->pat) + 1; /* pat\177 */
+ if (np->name != NULL)
+ total += strlen (np->name) + 1; /* name\001 */
+ total += number_len ((long) np->lno) + 1; /* lno, */
+ if (np->cno != invalidcharno) /* cno */
+ total += number_len (np->cno);
+ total += 1; /* newline */
+ }
+
+ return total;
+ }
+ #endif
+
static void
put_entries (np)
register node *np;
{
register char *sp;
+ static char *file = NULL;
if (np == NULL)
return;
/* Output subentries that precede this one */
! if (CTAGS)
! put_entries (np->left);
/* Output this entry */
if (!CTAGS)
{
+ /* Etags mode */
+ if (file != np->file
+ && (file == NULL || !streq (file, np->file)))
+ {
+ file = np->file;
+ fprintf (tagf, "\f\n%s,%d\n",
+ file, total_size_of_entries (np));
+ }
+ fputs (np->pat, tagf);
+ fputc ('\177', tagf);
if (np->name != NULL)
! {
! fputs (np->name, tagf);
! fputc ('\001', tagf);
! }
! fprintf (tagf, "%d,", np->lno);
! if (np->cno == invalidcharno)
! fputc ('\n', tagf);
else
! fprintf (tagf, "%ld\n", np->cno);
}
else
{
+ /* Ctags mode */
if (np->name == NULL)
error ("internal error: NULL name in ctags mode.", (char *)NULL);
***************
*** 1899,1948 ****
}
}
/* Output subentries that follow this one */
put_entries (np->right);
! }
!
! /* Length of a number's decimal representation. */
! static int
! number_len (num)
! long num;
! {
! int len = 1;
! while ((num /= 10) > 0)
! len += 1;
! return len;
! }
!
! /*
! * Return total number of characters that put_entries will output for
! * the nodes in the subtree of the specified node. Works only if
! * we are not ctags, but called only in that case. This count
! * is irrelevant with the new tags.el, but is still supplied for
! * backward compatibility.
! */
! static int
! total_size_of_entries (np)
! register node *np;
! {
! register int total;
!
! if (np == NULL)
! return 0;
!
! for (total = 0; np != NULL; np = np->right)
! {
! /* Count left subentries. */
! total += total_size_of_entries (np->left);
!
! /* Count this entry */
! total += strlen (np->pat) + 1;
! total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1;
! if (np->name != NULL)
! total += 1 + strlen (np->name); /* \001name */
! }
!
! return total;
}
--- 1958,1968 ----
}
}
+
/* Output subentries that follow this one */
put_entries (np->right);
! if (!CTAGS)
! put_entries (np->left);
}
***************
*** 2033,2039 ****
#DEFVAR_, 0, st_C_gnumacro
%]
and replace lines between %< and %> with its output,
! then make in_word_set static. */
/*%<*/
/* C code produced by gperf version 2.7.1 (19981006 egcs) */
/* Command-line: gperf -c -k 1,3 -o -p -r -t */
--- 2053,2059 ----
#DEFVAR_, 0, st_C_gnumacro
%]
and replace lines between %< and %> with its output,
! then make in_word_set and C_stab_entry static. */
/*%<*/
/* C code produced by gperf version 2.7.1 (19981006 egcs) */
/* Command-line: gperf -c -k 1,3 -o -p -r -t */
***************
*** 2218,2224 ****
* C functions and variables are recognized using a simple
* finite automaton. fvdef is its state variable.
*/
! enum
{
fvnone, /* nothing seen */
fdefunkey, /* Emacs DEFUN keyword seen */
--- 2238,2244 ----
* C functions and variables are recognized using a simple
* finite automaton. fvdef is its state variable.
*/
! static enum
{
fvnone, /* nothing seen */
fdefunkey, /* Emacs DEFUN keyword seen */
***************
*** 2232,2244 ****
vignore /* var-like: ignore until ';' */
} fvdef;
! bool fvextern; /* func or var: extern keyword seen; */
/*
* typedefs are recognized using a simple finite automaton.
* typdef is its state variable.
*/
! enum
{
tnone, /* nothing seen */
tkeyseen, /* typedef keyword seen */
--- 2252,2264 ----
vignore /* var-like: ignore until ';' */
} fvdef;
! static bool fvextern; /* func or var: extern keyword seen; */
/*
* typedefs are recognized using a simple finite automaton.
* typdef is its state variable.
*/
! static enum
{
tnone, /* nothing seen */
tkeyseen, /* typedef keyword seen */
***************
*** 2253,2259 ****
* using another simple finite automaton. `structdef' is its state
* variable.
*/
! enum
{
snone, /* nothing seen yet,
or in struct body if cblev > 0 */
--- 2273,2279 ----
* using another simple finite automaton. `structdef' is its state
* variable.
*/
! static enum
{
snone, /* nothing seen yet,
or in struct body if cblev > 0 */
***************
*** 2266,2277 ****
/*
* When objdef is different from onone, objtag is the name of the class.
*/
! char *objtag = "<uninited>";
/*
* Yet another little state machine to deal with preprocessor lines.
*/
! enum
{
dnone, /* nothing seen */
dsharpseen, /* '#' seen as first char on line */
--- 2286,2297 ----
/*
* When objdef is different from onone, objtag is the name of the class.
*/
! static char *objtag = "<uninited>";
/*
* Yet another little state machine to deal with preprocessor lines.
*/
! static enum
{
dnone, /* nothing seen */
dsharpseen, /* '#' seen as first char on line */
***************
*** 2283,2289 ****
* State machine for Objective C protocols and implementations.
* Idea by Tom R.Hageman <address@hidden> (1995)
*/
! enum
{
onone, /* nothing seen */
oprotocol, /* @interface or @protocol seen */
--- 2303,2309 ----
* State machine for Objective C protocols and implementations.
* Idea by Tom R.Hageman <address@hidden> (1995)
*/
! static enum
{
onone, /* nothing seen */
oprotocol, /* @interface or @protocol seen */
***************
*** 2304,2310 ****
* Use this structure to keep info about the token read, and how it
* should be tagged. Used by the make_C_tag function to build a tag.
*/
! struct tok
{
bool valid;
bool named;
--- 2324,2330 ----
* Use this structure to keep info about the token read, and how it
* should be tagged. Used by the make_C_tag function to build a tag.
*/
! static struct tok
{
bool valid;
bool named;
***************
*** 2314,2320 ****
long linepos;
char *line;
} token; /* latest token read */
! linebuffer token_name; /* its name */
/*
* Variables and functions for dealing with nested structures.
--- 2334,2340 ----
long linepos;
char *line;
} token; /* latest token read */
! static linebuffer token_name; /* its name */
/*
* Variables and functions for dealing with nested structures.
***************
*** 2324,2330 ****
static void popclass_above __P((int));
static void write_classname __P((linebuffer *, char *qualifier));
! struct {
char **cname; /* nested class names */
int *cblev; /* nested class curly brace level */
int nl; /* class nesting level (elements used) */
--- 2344,2350 ----
static void popclass_above __P((int));
static void write_classname __P((linebuffer *, char *qualifier));
! static struct {
char **cname; /* nested class names */
int *cblev; /* nested class curly brace level */
int nl; /* class nesting level (elements used) */
***************
*** 2711,2717 ****
* the line currently read. By keeping two line buffers, and switching
* them at end of line, it is possible to use those pointers.
*/
! struct
{
long linepos;
linebuffer lb;
--- 2731,2737 ----
* the line currently read. By keeping two line buffers, and switching
* them at end of line, it is possible to use those pointers.
*/
! static struct
{
long linepos;
linebuffer lb;
***************
*** 4027,4034 ****
/* Perhaps I should back cp up one character, so the TAGS table
doesn't mention (and so depend upon) the following char. */
! pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
! FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
}
}
}
--- 4047,4054 ----
/* Perhaps I should back cp up one character, so the TAGS table
doesn't mention (and so depend upon) the following char. */
! pfnote (varname, FALSE,
! lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
}
}
}
***************
*** 4507,4518 ****
int len;
};
! struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
/* Default set of control sequences to put into TEX_toktab.
The value of environment var TEXTAGS is prepended to this. */
! char *TEX_defenv = "\
:chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
:part:appendix:entry:index";
--- 4527,4538 ----
int len;
};
! static struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
/* Default set of control sequences to put into TEX_toktab.
The value of environment var TEXTAGS is prepended to this. */
! static char *TEX_defenv = "\
:chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
:part:appendix:entry:index";
***************
*** 4520,4528 ****
static struct TEX_tabent *TEX_decode_env __P((char *, char *));
static int TEX_Token __P((char *));
! char TEX_esc = '\\';
! char TEX_opgrp = '{';
! char TEX_clgrp = '}';
/*
* TeX/LaTeX scanning loop.
--- 4540,4548 ----
static struct TEX_tabent *TEX_decode_env __P((char *, char *));
static int TEX_Token __P((char *));
! static char TEX_esc = '\\';
! static char TEX_opgrp = '{';
! static char TEX_clgrp = '}';
/*
* TeX/LaTeX scanning loop.
***************
*** 5406,5456 ****
{
/* Read new line. */
long result = readline_internal (lbp, stream);
#ifdef ETAGS_REGEXPS
! int match;
! pattern *pp;
! /* Match against relevant patterns. */
! if (lbp->len > 0)
! for (pp = p_head; pp != NULL; pp = pp->p_next)
! {
! /* Only use generic regexps or those for the current language. */
! if (pp->lang != NULL && pp->lang != curlang)
! continue;
! match = re_match (pp->pat, lbp->buffer, lbp->len, 0, &pp->regs);
! switch (match)
! {
! case -2:
! /* Some error. */
! if (!pp->error_signaled)
! {
! error ("error while matching \"%s\"", pp->regex);
! pp->error_signaled = TRUE;
! }
! break;
! case -1:
! /* No match. */
! break;
! default:
! /* Match occurred. Construct a tag. */
! if (pp->name_pattern[0] != '\0')
! {
! /* Make a named tag. */
! char *name = substitute (lbp->buffer,
! pp->name_pattern, &pp->regs);
! if (name != NULL)
! pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
! }
! else
! {
! /* Make an unnamed tag. */
! pfnote ((char *)NULL, TRUE,
! lbp->buffer, match, lineno, linecharno);
! }
! break;
! }
! }
#endif /* ETAGS_REGEXPS */
return result;
--- 5426,5503 ----
{
/* Read new line. */
long result = readline_internal (lbp, stream);
+
+ if (!no_line_directive
+ && result > 12 && strneq (lbp->buffer, "#line ", 6))
+ {
+ int start, lno;
+
+ if (sscanf (lbp->buffer, "#line %d \"%n", &lno, &start) == 1)
+ {
+ char *endp = lbp->buffer + start;
+
+ while ((endp = etags_strchr (endp, '"')) != NULL
+ && endp[-1] == '\\')
+ endp++;
+ if (endp != NULL)
+ {
+ int len = endp - (lbp->buffer + start);
+
+ if (!strneq (curfile, lbp->buffer + start, len))
+ curfile = savenstr (lbp->buffer + start, len);
+ lineno = lno;
+ nocharno = TRUE; /* do not use char position for tags */
+ return readline (lbp, stream);
+ }
+ }
+ }
#ifdef ETAGS_REGEXPS
! {
! int match;
! pattern *pp;
! /* Match against relevant patterns. */
! if (lbp->len > 0)
! for (pp = p_head; pp != NULL; pp = pp->p_next)
! {
! /* Only use generic regexps or those for the current language. */
! if (pp->lang != NULL && pp->lang != curlang)
! continue;
! match = re_match (pp->pat, lbp->buffer, lbp->len, 0, &pp->regs);
! switch (match)
! {
! case -2:
! /* Some error. */
! if (!pp->error_signaled)
! {
! error ("error while matching \"%s\"", pp->regex);
! pp->error_signaled = TRUE;
! }
! break;
! case -1:
! /* No match. */
! break;
! default:
! /* Match occurred. Construct a tag. */
! if (pp->name_pattern[0] != '\0')
! {
! /* Make a named tag. */
! char *name = substitute (lbp->buffer,
! pp->name_pattern, &pp->regs);
! if (name != NULL)
! pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
! }
! else
! {
! /* Make an unnamed tag. */
! pfnote ((char *)NULL, TRUE,
! lbp->buffer, match, lineno, linecharno);
! }
! break;
! }
! }
! }
#endif /* ETAGS_REGEXPS */
return result;
***************
*** 5826,5832 ****
}
/* Like malloc but get fatal error if memory is exhausted. */
! PTR
xmalloc (size)
unsigned int size;
{
--- 5873,5879 ----
}
/* Like malloc but get fatal error if memory is exhausted. */
! static PTR
xmalloc (size)
unsigned int size;
{
***************
*** 5836,5842 ****
return result;
}
! PTR
xrealloc (ptr, size)
char *ptr;
unsigned int size;
--- 5883,5889 ----
return result;
}
! static PTR
xrealloc (ptr, size)
char *ptr;
unsigned int size;
- [Emacs-diffs] Changes to emacs/lib-src/etags.c,
Francesco Potortì <=