diff options
| author | Francesco Potortì | 2002-03-05 11:28:26 +0000 |
|---|---|---|
| committer | Francesco Potortì | 2002-03-05 11:28:26 +0000 |
| commit | db59058201446a651dd28697590ad5fbc25383ea (patch) | |
| tree | 01ab3cc8f038ed9e2be1be7e7f9c1be359607f6e /lib-src | |
| parent | 51aeded3e698e7908c47977152f80f87a0765e38 (diff) | |
| download | emacs-db59058201446a651dd28697590ad5fbc25383ea.tar.gz emacs-db59058201446a651dd28697590ad5fbc25383ea.zip | |
* etags.c: Honour #line directives.
(no_line_directive): New global var; set it for old behaviour.
(main): Remove some #ifdef in the getopt switch.
(add_node, put_entries): Code added to merge different chunks of
nodes referring to the same file. Currently the tags are just
appended, without any check for duplicates.
(Perl_functions): Do not special case ctags.
(readline): Identify #line directives and do the right thing.
(nocharno, invalidcharno): New global vars.
(process_file): Reset nocharno.
(readline): Set nocharno.
(pfnote): Read nocharno and maybe put invalidcharno in node.
(total_size_of_entries, put_entries): Use invalidcharno.
* etags.c: Keep the whole tag table in memory, even in etags mode.
(main): Call put_entries here even in CTAGS mode.
(main, process_file): Check the return values of fclose and pclose.
(process_file): Do not call put_entries after parsing each file.
(process_file): Canonicalise file names even for ctags.
(process_file): Set curfile here...
(find_entries): ... not here any more.
(add_node): In etags mode, build a linked list of entries (on
right pointer) for each file, and link the first entry of each
file on left nodes.
(put_entries): Print here the name of the file.
(put_entries): Print the entries starting from the first file.
(number_len, total_size_of_entries): Define these only iin etags
mode, make the second work only on the right nodes.
* etags.c: Make all global variables static.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 595 |
1 files changed, 321 insertions, 274 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 950389545ac..52e9d291d0e 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -33,7 +33,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
| 33 | * Francesco Potortì <pot@gnu.org> has maintained it since 1993. | 33 | * Francesco Potortì <pot@gnu.org> has maintained it since 1993. |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | char pot_etags_version[] = "@(#) pot revision number is 14.35"; | 36 | char pot_etags_version[] = "@(#) pot revision number is 14.39"; |
| 37 | 37 | ||
| 38 | #define TRUE 1 | 38 | #define TRUE 1 |
| 39 | #define FALSE 0 | 39 | #define FALSE 0 |
| @@ -299,13 +299,11 @@ static void print_language_names __P((void)); | |||
| 299 | static void print_version __P((void)); | 299 | static void print_version __P((void)); |
| 300 | static void print_help __P((void)); | 300 | static void print_help __P((void)); |
| 301 | int main __P((int, char **)); | 301 | int main __P((int, char **)); |
| 302 | static int number_len __P((long)); | ||
| 303 | 302 | ||
| 304 | static compressor *get_compressor_from_suffix __P((char *, char **)); | 303 | static compressor *get_compressor_from_suffix __P((char *, char **)); |
| 305 | static language *get_language_from_langname __P((const char *)); | 304 | static language *get_language_from_langname __P((const char *)); |
| 306 | static language *get_language_from_interpreter __P((char *)); | 305 | static language *get_language_from_interpreter __P((char *)); |
| 307 | static language *get_language_from_filename __P((char *)); | 306 | static language *get_language_from_filename __P((char *)); |
| 308 | static int total_size_of_entries __P((node *)); | ||
| 309 | static long readline __P((linebuffer *, FILE *)); | 307 | static long readline __P((linebuffer *, FILE *)); |
| 310 | static long readline_internal __P((linebuffer *, FILE *)); | 308 | static long readline_internal __P((linebuffer *, FILE *)); |
| 311 | static bool nocase_tail __P((char *)); | 309 | static bool nocase_tail __P((char *)); |
| @@ -345,33 +343,35 @@ static char *absolute_dirname __P((char *, char *)); | |||
| 345 | static bool filename_is_absolute __P((char *f)); | 343 | static bool filename_is_absolute __P((char *f)); |
| 346 | static void canonicalize_filename __P((char *)); | 344 | static void canonicalize_filename __P((char *)); |
| 347 | static void linebuffer_setlen __P((linebuffer *, int)); | 345 | static void linebuffer_setlen __P((linebuffer *, int)); |
| 348 | PTR xmalloc __P((unsigned int)); | 346 | static PTR xmalloc __P((unsigned int)); |
| 349 | PTR xrealloc __P((char *, unsigned int)); | 347 | static PTR xrealloc __P((char *, unsigned int)); |
| 350 | 348 | ||
| 351 | 349 | ||
| 352 | char searchar = '/'; /* use /.../ searches */ | 350 | static char searchar = '/'; /* use /.../ searches */ |
| 353 | 351 | ||
| 354 | char *tagfile; /* output file */ | 352 | static char *tagfile; /* output file */ |
| 355 | char *progname; /* name this program was invoked with */ | 353 | static char *progname; /* name this program was invoked with */ |
| 356 | char *cwd; /* current working directory */ | 354 | static char *cwd; /* current working directory */ |
| 357 | char *tagfiledir; /* directory of tagfile */ | 355 | static char *tagfiledir; /* directory of tagfile */ |
| 358 | FILE *tagf; /* ioptr for tags file */ | 356 | static FILE *tagf; /* ioptr for tags file */ |
| 359 | 357 | ||
| 360 | char *curfile; /* current input file name */ | 358 | static char *curfile; /* current input file name */ |
| 361 | language *curlang; /* current language */ | 359 | static language *curlang; /* current language */ |
| 362 | 360 | ||
| 363 | int lineno; /* line number of current line */ | 361 | static int lineno; /* line number of current line */ |
| 364 | long charno; /* current character number */ | 362 | static long charno; /* current character number */ |
| 365 | long linecharno; /* charno of start of current line */ | 363 | static long linecharno; /* charno of start of current line */ |
| 366 | char *dbp; /* pointer to start of current tag */ | 364 | static char *dbp; /* pointer to start of current tag */ |
| 365 | static bool nocharno; /* only use line number when making tag */ | ||
| 366 | static const int invalidcharno = -1; | ||
| 367 | 367 | ||
| 368 | node *head; /* the head of the binary tree of tags */ | 368 | static node *head; /* the head of the binary tree of tags */ |
| 369 | 369 | ||
| 370 | linebuffer lb; /* the current line */ | 370 | static linebuffer lb; /* the current line */ |
| 371 | 371 | ||
| 372 | /* boolean "functions" (see init) */ | 372 | /* boolean "functions" (see init) */ |
| 373 | bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; | 373 | static bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; |
| 374 | char | 374 | static char |
| 375 | /* white chars */ | 375 | /* white chars */ |
| 376 | *white = " \f\t\n\r\v", | 376 | *white = " \f\t\n\r\v", |
| 377 | /* not in a name */ | 377 | /* not in a name */ |
| @@ -383,58 +383,60 @@ char | |||
| 383 | /* valid in-token chars */ | 383 | /* valid in-token chars */ |
| 384 | *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; | 384 | *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; |
| 385 | 385 | ||
| 386 | bool append_to_tagfile; /* -a: append to tags */ | 386 | static bool append_to_tagfile; /* -a: append to tags */ |
| 387 | /* The following four default to TRUE for etags, but to FALSE for ctags. */ | 387 | /* The following four default to TRUE for etags, but to FALSE for ctags. */ |
| 388 | bool typedefs; /* -t: create tags for C and Ada typedefs */ | 388 | static bool typedefs; /* -t: create tags for C and Ada typedefs */ |
| 389 | bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */ | 389 | static bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */ |
| 390 | /* 0 struct/enum/union decls, and C++ */ | 390 | /* 0 struct/enum/union decls, and C++ */ |
| 391 | /* member functions. */ | 391 | /* member functions. */ |
| 392 | bool constantypedefs; /* -d: create tags for C #define, enum */ | 392 | static bool constantypedefs; /* -d: create tags for C #define, enum */ |
| 393 | /* constants and variables. */ | 393 | /* constants and variables. */ |
| 394 | /* -D: opposite of -d. Default under ctags. */ | 394 | /* -D: opposite of -d. Default under ctags. */ |
| 395 | bool declarations; /* --declarations: tag them and extern in C&Co*/ | 395 | static bool declarations; /* --declarations: tag them and extern in C&Co*/ |
| 396 | bool globals; /* create tags for global variables */ | 396 | static bool globals; /* create tags for global variables */ |
| 397 | bool members; /* create tags for C member variables */ | 397 | static bool no_line_directive; /* ignore #line directives */ |
| 398 | bool update; /* -u: update tags */ | 398 | static bool members; /* create tags for C member variables */ |
| 399 | bool vgrind_style; /* -v: create vgrind style index output */ | 399 | static bool update; /* -u: update tags */ |
| 400 | bool no_warnings; /* -w: suppress warnings */ | 400 | static bool vgrind_style; /* -v: create vgrind style index output */ |
| 401 | bool cxref_style; /* -x: create cxref style output */ | 401 | static bool no_warnings; /* -w: suppress warnings */ |
| 402 | bool cplusplus; /* .[hc] means C++, not C */ | 402 | static bool cxref_style; /* -x: create cxref style output */ |
| 403 | bool noindentypedefs; /* -I: ignore indentation in C */ | 403 | static bool cplusplus; /* .[hc] means C++, not C */ |
| 404 | bool packages_only; /* --packages-only: in Ada, only tag packages*/ | 404 | static bool noindentypedefs; /* -I: ignore indentation in C */ |
| 405 | static bool packages_only; /* --packages-only: in Ada, only tag packages*/ | ||
| 405 | 406 | ||
| 406 | #ifdef LONG_OPTIONS | 407 | #ifdef LONG_OPTIONS |
| 407 | struct option longopts[] = | 408 | static struct option longopts[] = |
| 408 | { | 409 | { |
| 409 | { "packages-only", no_argument, &packages_only, TRUE }, | 410 | { "packages-only", no_argument, &packages_only, TRUE }, |
| 410 | { "append", no_argument, NULL, 'a' }, | 411 | { "append", no_argument, NULL, 'a' }, |
| 411 | { "backward-search", no_argument, NULL, 'B' }, | 412 | { "backward-search", no_argument, NULL, 'B' }, |
| 412 | { "c++", no_argument, NULL, 'C' }, | 413 | { "c++", no_argument, NULL, 'C' }, |
| 413 | { "cxref", no_argument, NULL, 'x' }, | 414 | { "cxref", no_argument, NULL, 'x' }, |
| 414 | { "defines", no_argument, NULL, 'd' }, | 415 | { "defines", no_argument, NULL, 'd' }, |
| 415 | { "declarations", no_argument, &declarations, TRUE }, | 416 | { "declarations", no_argument, &declarations, TRUE }, |
| 416 | { "no-defines", no_argument, NULL, 'D' }, | 417 | { "no-defines", no_argument, NULL, 'D' }, |
| 417 | { "globals", no_argument, &globals, TRUE }, | 418 | { "globals", no_argument, &globals, TRUE }, |
| 418 | { "no-globals", no_argument, &globals, FALSE }, | 419 | { "no-globals", no_argument, &globals, FALSE }, |
| 419 | { "help", no_argument, NULL, 'h' }, | 420 | { "no-line-directive", no_argument, &no_line_directive, TRUE }, |
| 420 | { "help", no_argument, NULL, 'H' }, | 421 | { "help", no_argument, NULL, 'h' }, |
| 421 | { "ignore-indentation", no_argument, NULL, 'I' }, | 422 | { "help", no_argument, NULL, 'H' }, |
| 422 | { "include", required_argument, NULL, 'i' }, | 423 | { "ignore-indentation", no_argument, NULL, 'I' }, |
| 423 | { "language", required_argument, NULL, 'l' }, | 424 | { "include", required_argument, NULL, 'i' }, |
| 424 | { "members", no_argument, &members, TRUE }, | 425 | { "language", required_argument, NULL, 'l' }, |
| 425 | { "no-members", no_argument, &members, FALSE }, | 426 | { "members", no_argument, &members, TRUE }, |
| 426 | { "no-warn", no_argument, NULL, 'w' }, | 427 | { "no-members", no_argument, &members, FALSE }, |
| 427 | { "output", required_argument, NULL, 'o' }, | 428 | { "no-warn", no_argument, NULL, 'w' }, |
| 429 | { "output", required_argument, NULL, 'o' }, | ||
| 428 | #ifdef ETAGS_REGEXPS | 430 | #ifdef ETAGS_REGEXPS |
| 429 | { "regex", required_argument, NULL, 'r' }, | 431 | { "regex", required_argument, NULL, 'r' }, |
| 430 | { "no-regex", no_argument, NULL, 'R' }, | 432 | { "no-regex", no_argument, NULL, 'R' }, |
| 431 | { "ignore-case-regex", required_argument, NULL, 'c' }, | 433 | { "ignore-case-regex", required_argument, NULL, 'c' }, |
| 432 | #endif /* ETAGS_REGEXPS */ | 434 | #endif /* ETAGS_REGEXPS */ |
| 433 | { "typedefs", no_argument, NULL, 't' }, | 435 | { "typedefs", no_argument, NULL, 't' }, |
| 434 | { "typedefs-and-c++", no_argument, NULL, 'T' }, | 436 | { "typedefs-and-c++", no_argument, NULL, 'T' }, |
| 435 | { "update", no_argument, NULL, 'u' }, | 437 | { "update", no_argument, NULL, 'u' }, |
| 436 | { "version", no_argument, NULL, 'V' }, | 438 | { "version", no_argument, NULL, 'V' }, |
| 437 | { "vgrind", no_argument, NULL, 'v' }, | 439 | { "vgrind", no_argument, NULL, 'v' }, |
| 438 | { NULL } | 440 | { NULL } |
| 439 | }; | 441 | }; |
| 440 | #endif /* LONG_OPTIONS */ | 442 | #endif /* LONG_OPTIONS */ |
| @@ -454,15 +456,15 @@ typedef struct pattern | |||
| 454 | } pattern; | 456 | } pattern; |
| 455 | 457 | ||
| 456 | /* List of all regexps. */ | 458 | /* List of all regexps. */ |
| 457 | pattern *p_head = NULL; | 459 | static pattern *p_head = NULL; |
| 458 | 460 | ||
| 459 | /* How many characters in the character set. (From regex.c.) */ | 461 | /* How many characters in the character set. (From regex.c.) */ |
| 460 | #define CHAR_SET_SIZE 256 | 462 | #define CHAR_SET_SIZE 256 |
| 461 | /* Translation table for case-insensitive matching. */ | 463 | /* Translation table for case-insensitive matching. */ |
| 462 | char lc_trans[CHAR_SET_SIZE]; | 464 | static char lc_trans[CHAR_SET_SIZE]; |
| 463 | #endif /* ETAGS_REGEXPS */ | 465 | #endif /* ETAGS_REGEXPS */ |
| 464 | 466 | ||
| 465 | compressor compressors[] = | 467 | static compressor compressors[] = |
| 466 | { | 468 | { |
| 467 | { "z", "gzip -d -c"}, | 469 | { "z", "gzip -d -c"}, |
| 468 | { "Z", "gzip -d -c"}, | 470 | { "Z", "gzip -d -c"}, |
| @@ -477,94 +479,96 @@ compressor compressors[] = | |||
| 477 | */ | 479 | */ |
| 478 | 480 | ||
| 479 | /* Non-NULL if language fixed. */ | 481 | /* Non-NULL if language fixed. */ |
| 480 | language *forced_lang = NULL; | 482 | static language *forced_lang = NULL; |
| 481 | 483 | ||
| 482 | /* Ada code */ | 484 | /* Ada code */ |
| 483 | char *Ada_suffixes [] = | 485 | static char *Ada_suffixes [] = |
| 484 | { "ads", "adb", "ada", NULL }; | 486 | { "ads", "adb", "ada", NULL }; |
| 485 | 487 | ||
| 486 | /* Assembly code */ | 488 | /* Assembly code */ |
| 487 | char *Asm_suffixes [] = { "a", /* Unix assembler */ | 489 | static char *Asm_suffixes [] = |
| 488 | "asm", /* Microcontroller assembly */ | 490 | { "a", /* Unix assembler */ |
| 489 | "def", /* BSO/Tasking definition includes */ | 491 | "asm", /* Microcontroller assembly */ |
| 490 | "inc", /* Microcontroller include files */ | 492 | "def", /* BSO/Tasking definition includes */ |
| 491 | "ins", /* Microcontroller include files */ | 493 | "inc", /* Microcontroller include files */ |
| 492 | "s", "sa", /* Unix assembler */ | 494 | "ins", /* Microcontroller include files */ |
| 493 | "S", /* cpp-processed Unix assembler */ | 495 | "s", "sa", /* Unix assembler */ |
| 494 | "src", /* BSO/Tasking C compiler output */ | 496 | "S", /* cpp-processed Unix assembler */ |
| 495 | NULL | 497 | "src", /* BSO/Tasking C compiler output */ |
| 496 | }; | 498 | NULL |
| 499 | }; | ||
| 497 | 500 | ||
| 498 | /* Note that .c and .h can be considered C++, if the --c++ flag was | 501 | /* Note that .c and .h can be considered C++, if the --c++ flag was |
| 499 | given, or if the `class' keyowrd is met inside the file. | 502 | given, or if the `class' keyowrd is met inside the file. |
| 500 | That is why default_C_entries is called for these. */ | 503 | That is why default_C_entries is called for these. */ |
| 501 | char *default_C_suffixes [] = | 504 | static char *default_C_suffixes [] = |
| 502 | { "c", "h", NULL }; | 505 | { "c", "h", NULL }; |
| 503 | 506 | ||
| 504 | char *Cplusplus_suffixes [] = | 507 | static char *Cplusplus_suffixes [] = |
| 505 | { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx", | 508 | { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx", |
| 506 | "M", /* Objective C++ */ | 509 | "M", /* Objective C++ */ |
| 507 | "pdb", /* Postscript with C syntax */ | 510 | "pdb", /* Postscript with C syntax */ |
| 508 | NULL }; | 511 | NULL }; |
| 509 | 512 | ||
| 510 | char *Cjava_suffixes [] = | 513 | static char *Cjava_suffixes [] = |
| 511 | { "java", NULL }; | 514 | { "java", NULL }; |
| 512 | 515 | ||
| 513 | char *Cobol_suffixes [] = | 516 | static char *Cobol_suffixes [] = |
| 514 | { "COB", "cob", NULL }; | 517 | { "COB", "cob", NULL }; |
| 515 | 518 | ||
| 516 | char *Cstar_suffixes [] = | 519 | static char *Cstar_suffixes [] = |
| 517 | { "cs", "hs", NULL }; | 520 | { "cs", "hs", NULL }; |
| 518 | 521 | ||
| 519 | char *Erlang_suffixes [] = | 522 | static char *Erlang_suffixes [] = |
| 520 | { "erl", "hrl", NULL }; | 523 | { "erl", "hrl", NULL }; |
| 521 | 524 | ||
| 522 | char *Fortran_suffixes [] = | 525 | static char *Fortran_suffixes [] = |
| 523 | { "F", "f", "f90", "for", NULL }; | 526 | { "F", "f", "f90", "for", NULL }; |
| 524 | 527 | ||
| 525 | char *Lisp_suffixes [] = | 528 | static char *Lisp_suffixes [] = |
| 526 | { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL }; | 529 | { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL }; |
| 527 | 530 | ||
| 528 | char *Makefile_filenames [] = | 531 | static char *Makefile_filenames [] = |
| 529 | { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL}; | 532 | { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL}; |
| 530 | 533 | ||
| 531 | char *Pascal_suffixes [] = | 534 | static char *Pascal_suffixes [] = |
| 532 | { "p", "pas", NULL }; | 535 | { "p", "pas", NULL }; |
| 533 | 536 | ||
| 534 | char *Perl_suffixes [] = | 537 | static char *Perl_suffixes [] = |
| 535 | { "pl", "pm", NULL }; | 538 | { "pl", "pm", NULL }; |
| 536 | char *Perl_interpreters [] = | 539 | |
| 540 | static char *Perl_interpreters [] = | ||
| 537 | { "perl", "@PERL@", NULL }; | 541 | { "perl", "@PERL@", NULL }; |
| 538 | 542 | ||
| 539 | char *PHP_suffixes [] = | 543 | static char *PHP_suffixes [] = |
| 540 | { "php", "php3", "php4", NULL }; | 544 | { "php", "php3", "php4", NULL }; |
| 541 | 545 | ||
| 542 | char *plain_C_suffixes [] = | 546 | static char *plain_C_suffixes [] = |
| 543 | { "lm", /* Objective lex file */ | 547 | { "lm", /* Objective lex file */ |
| 544 | "m", /* Objective C file */ | 548 | "m", /* Objective C file */ |
| 545 | "pc", /* Pro*C file */ | 549 | "pc", /* Pro*C file */ |
| 546 | NULL }; | 550 | NULL }; |
| 547 | 551 | ||
| 548 | char *Postscript_suffixes [] = | 552 | static char *Postscript_suffixes [] = |
| 549 | { "ps", "psw", NULL }; /* .psw is for PSWrap */ | 553 | { "ps", "psw", NULL }; /* .psw is for PSWrap */ |
| 550 | 554 | ||
| 551 | char *Prolog_suffixes [] = | 555 | static char *Prolog_suffixes [] = |
| 552 | { "prolog", NULL }; | 556 | { "prolog", NULL }; |
| 553 | 557 | ||
| 554 | char *Python_suffixes [] = | 558 | static char *Python_suffixes [] = |
| 555 | { "py", NULL }; | 559 | { "py", NULL }; |
| 556 | 560 | ||
| 557 | /* Can't do the `SCM' or `scm' prefix with a version number. */ | 561 | /* Can't do the `SCM' or `scm' prefix with a version number. */ |
| 558 | char *Scheme_suffixes [] = | 562 | static char *Scheme_suffixes [] = |
| 559 | { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL }; | 563 | { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL }; |
| 560 | 564 | ||
| 561 | char *TeX_suffixes [] = | 565 | static char *TeX_suffixes [] = |
| 562 | { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL }; | 566 | { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL }; |
| 563 | 567 | ||
| 564 | char *Texinfo_suffixes [] = | 568 | static char *Texinfo_suffixes [] = |
| 565 | { "texi", "texinfo", "txi", NULL }; | 569 | { "texi", "texinfo", "txi", NULL }; |
| 566 | 570 | ||
| 567 | char *Yacc_suffixes [] = | 571 | static char *Yacc_suffixes [] = |
| 568 | { "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */ | 572 | { "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */ |
| 569 | 573 | ||
| 570 | /* | 574 | /* |
| @@ -574,7 +578,7 @@ char *Yacc_suffixes [] = | |||
| 574 | * name. I just didn't. | 578 | * name. I just didn't. |
| 575 | */ | 579 | */ |
| 576 | 580 | ||
| 577 | language lang_names [] = | 581 | static language lang_names [] = |
| 578 | { | 582 | { |
| 579 | { "ada", Ada_funcs, NULL, Ada_suffixes, NULL }, | 583 | { "ada", Ada_funcs, NULL, Ada_suffixes, NULL }, |
| 580 | { "asm", Asm_labels, NULL, Asm_suffixes, NULL }, | 584 | { "asm", Asm_labels, NULL, Asm_suffixes, NULL }, |
| @@ -1042,7 +1046,6 @@ main (argc, argv) | |||
| 1042 | } | 1046 | } |
| 1043 | } | 1047 | } |
| 1044 | break; | 1048 | break; |
| 1045 | #ifdef ETAGS_REGEXPS | ||
| 1046 | case 'r': | 1049 | case 'r': |
| 1047 | argbuffer[current_arg].arg_type = at_regexp; | 1050 | argbuffer[current_arg].arg_type = at_regexp; |
| 1048 | argbuffer[current_arg].what = optarg; | 1051 | argbuffer[current_arg].what = optarg; |
| @@ -1058,7 +1061,6 @@ main (argc, argv) | |||
| 1058 | argbuffer[current_arg].what = optarg; | 1061 | argbuffer[current_arg].what = optarg; |
| 1059 | ++current_arg; | 1062 | ++current_arg; |
| 1060 | break; | 1063 | break; |
| 1061 | #endif /* ETAGS_REGEXPS */ | ||
| 1062 | case 'V': | 1064 | case 'V': |
| 1063 | print_version (); | 1065 | print_version (); |
| 1064 | break; | 1066 | break; |
| @@ -1072,19 +1074,16 @@ main (argc, argv) | |||
| 1072 | case 'T': | 1074 | case 'T': |
| 1073 | typedefs = typedefs_or_cplusplus = TRUE; | 1075 | typedefs = typedefs_or_cplusplus = TRUE; |
| 1074 | break; | 1076 | break; |
| 1075 | #if (!CTAGS) | ||
| 1076 | /* Etags options */ | 1077 | /* Etags options */ |
| 1077 | case 'i': | 1078 | case 'i': |
| 1078 | included_files[nincluded_files++] = optarg; | 1079 | included_files[nincluded_files++] = optarg; |
| 1079 | break; | 1080 | break; |
| 1080 | #else /* CTAGS */ | ||
| 1081 | /* Ctags options. */ | 1081 | /* Ctags options. */ |
| 1082 | case 'B': searchar = '?'; break; | 1082 | case 'B': searchar = '?'; break; |
| 1083 | case 'u': update = TRUE; break; | 1083 | case 'u': update = TRUE; break; |
| 1084 | case 'v': vgrind_style = TRUE; /*FALLTHRU*/ | 1084 | case 'v': vgrind_style = TRUE; /*FALLTHRU*/ |
| 1085 | case 'x': cxref_style = TRUE; break; | 1085 | case 'x': cxref_style = TRUE; break; |
| 1086 | case 'w': no_warnings = TRUE; break; | 1086 | case 'w': no_warnings = TRUE; break; |
| 1087 | #endif /* CTAGS */ | ||
| 1088 | default: | 1087 | default: |
| 1089 | suggest_asking_for_help (); | 1088 | suggest_asking_for_help (); |
| 1090 | } | 1089 | } |
| @@ -1193,22 +1192,17 @@ main (argc, argv) | |||
| 1193 | free_patterns (); | 1192 | free_patterns (); |
| 1194 | #endif /* ETAGS_REGEXPS */ | 1193 | #endif /* ETAGS_REGEXPS */ |
| 1195 | 1194 | ||
| 1196 | if (!CTAGS) | 1195 | if (!CTAGS || cxref_style) |
| 1197 | { | ||
| 1198 | while (nincluded_files-- > 0) | ||
| 1199 | fprintf (tagf, "\f\n%s,include\n", *included_files++); | ||
| 1200 | |||
| 1201 | fclose (tagf); | ||
| 1202 | exit (GOOD); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | /* If CTAGS, we are here. process_file did not write the tags yet, | ||
| 1206 | because we want them ordered. Let's do it now. */ | ||
| 1207 | if (cxref_style) | ||
| 1208 | { | 1196 | { |
| 1209 | put_entries (head); | 1197 | put_entries (head); |
| 1210 | free_tree (head); | 1198 | free_tree (head); |
| 1211 | head = NULL; | 1199 | head = NULL; |
| 1200 | if (!CTAGS) | ||
| 1201 | while (nincluded_files-- > 0) | ||
| 1202 | fprintf (tagf, "\f\n%s,include\n", *included_files++); | ||
| 1203 | |||
| 1204 | if (fclose (tagf) == EOF) | ||
| 1205 | pfatal (tagfile); | ||
| 1212 | exit (GOOD); | 1206 | exit (GOOD); |
| 1213 | } | 1207 | } |
| 1214 | 1208 | ||
| @@ -1234,7 +1228,8 @@ main (argc, argv) | |||
| 1234 | put_entries (head); | 1228 | put_entries (head); |
| 1235 | free_tree (head); | 1229 | free_tree (head); |
| 1236 | head = NULL; | 1230 | head = NULL; |
| 1237 | fclose (tagf); | 1231 | if (fclose (tagf) == EOF) |
| 1232 | pfatal (tagfile); | ||
| 1238 | 1233 | ||
| 1239 | if (update) | 1234 | if (update) |
| 1240 | { | 1235 | { |
| @@ -1379,6 +1374,7 @@ process_file (file) | |||
| 1379 | compressor *compr; | 1374 | compressor *compr; |
| 1380 | char *compressed_name, *uncompressed_name; | 1375 | char *compressed_name, *uncompressed_name; |
| 1381 | char *ext, *real_name; | 1376 | char *ext, *real_name; |
| 1377 | int retval; | ||
| 1382 | 1378 | ||
| 1383 | 1379 | ||
| 1384 | canonicalize_filename (file); | 1380 | canonicalize_filename (file); |
| @@ -1486,34 +1482,26 @@ process_file (file) | |||
| 1486 | goto exit; | 1482 | goto exit; |
| 1487 | } | 1483 | } |
| 1488 | 1484 | ||
| 1485 | if (filename_is_absolute (uncompressed_name)) | ||
| 1486 | { | ||
| 1487 | /* file is an absolute file name. Canonicalise it. */ | ||
| 1488 | curfile = absolute_filename (uncompressed_name, cwd); | ||
| 1489 | } | ||
| 1490 | else | ||
| 1491 | { | ||
| 1492 | /* file is a file name relative to cwd. Make it relative | ||
| 1493 | to the directory of the tags file. */ | ||
| 1494 | curfile = relative_filename (uncompressed_name, tagfiledir); | ||
| 1495 | } | ||
| 1496 | nocharno = FALSE; /* use char position when making tags */ | ||
| 1489 | find_entries (uncompressed_name, inf); | 1497 | find_entries (uncompressed_name, inf); |
| 1490 | 1498 | ||
| 1491 | if (real_name == compressed_name) | 1499 | if (real_name == compressed_name) |
| 1492 | pclose (inf); | 1500 | retval = pclose (inf); |
| 1493 | else | 1501 | else |
| 1494 | fclose (inf); | 1502 | retval = fclose (inf); |
| 1495 | 1503 | if (retval < 0) | |
| 1496 | if (!CTAGS) | 1504 | pfatal (file); |
| 1497 | { | ||
| 1498 | char *filename; | ||
| 1499 | |||
| 1500 | if (filename_is_absolute (uncompressed_name)) | ||
| 1501 | { | ||
| 1502 | /* file is an absolute file name. Canonicalise it. */ | ||
| 1503 | filename = absolute_filename (uncompressed_name, cwd); | ||
| 1504 | } | ||
| 1505 | else | ||
| 1506 | { | ||
| 1507 | /* file is a file name relative to cwd. Make it relative | ||
| 1508 | to the directory of the tags file. */ | ||
| 1509 | filename = relative_filename (uncompressed_name, tagfiledir); | ||
| 1510 | } | ||
| 1511 | fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head)); | ||
| 1512 | free (filename); | ||
| 1513 | put_entries (head); | ||
| 1514 | free_tree (head); | ||
| 1515 | head = NULL; | ||
| 1516 | } | ||
| 1517 | 1505 | ||
| 1518 | exit: | 1506 | exit: |
| 1519 | if (compressed_name) free(compressed_name); | 1507 | if (compressed_name) free(compressed_name); |
| @@ -1552,7 +1540,7 @@ init () | |||
| 1552 | * This routine opens the specified file and calls the function | 1540 | * This routine opens the specified file and calls the function |
| 1553 | * which finds the function and type definitions. | 1541 | * which finds the function and type definitions. |
| 1554 | */ | 1542 | */ |
| 1555 | node *last_node = NULL; | 1543 | static node *last_node = NULL; |
| 1556 | 1544 | ||
| 1557 | static void | 1545 | static void |
| 1558 | find_entries (file, inf) | 1546 | find_entries (file, inf) |
| @@ -1563,13 +1551,6 @@ find_entries (file, inf) | |||
| 1563 | language *lang; | 1551 | language *lang; |
| 1564 | node *old_last_node; | 1552 | node *old_last_node; |
| 1565 | 1553 | ||
| 1566 | /* Memory leakage here: the string pointed by curfile is | ||
| 1567 | never released, because curfile is copied into np->file | ||
| 1568 | for each node, to be used in CTAGS mode. The amount of | ||
| 1569 | memory leaked here is the sum of the lengths of the | ||
| 1570 | file names. */ | ||
| 1571 | curfile = savestr (file); | ||
| 1572 | |||
| 1573 | /* If user specified a language, use it. */ | 1554 | /* If user specified a language, use it. */ |
| 1574 | lang = forced_lang; | 1555 | lang = forced_lang; |
| 1575 | if (lang != NULL && lang->function != NULL) | 1556 | if (lang != NULL && lang->function != NULL) |
| @@ -1673,12 +1654,15 @@ pfnote (name, is_func, linestart, linelen, lno, cno) | |||
| 1673 | np->file = curfile; | 1654 | np->file = curfile; |
| 1674 | np->is_func = is_func; | 1655 | np->is_func = is_func; |
| 1675 | np->lno = lno; | 1656 | np->lno = lno; |
| 1676 | /* Our char numbers are 0-base, because of C language tradition? | 1657 | if (nocharno) |
| 1677 | ctags compatibility? old versions compatibility? I don't know. | 1658 | np->cno = invalidcharno; |
| 1678 | Anyway, since emacs's are 1-base we expect etags.el to take care | 1659 | else |
| 1679 | of the difference. If we wanted to have 1-based numbers, we would | 1660 | /* Our char numbers are 0-base, because of C language tradition? |
| 1680 | uncomment the +1 below. */ | 1661 | ctags compatibility? old versions compatibility? I don't know. |
| 1681 | np->cno = cno /* + 1 */ ; | 1662 | Anyway, since emacs's are 1-base we expect etags.el to take care |
| 1663 | of the difference. If we wanted to have 1-based numbers, we would | ||
| 1664 | uncomment the +1 below. */ | ||
| 1665 | np->cno = cno /* + 1 */ ; | ||
| 1682 | np->left = np->right = NULL; | 1666 | np->left = np->right = NULL; |
| 1683 | if (CTAGS && !cxref_style) | 1667 | if (CTAGS && !cxref_style) |
| 1684 | { | 1668 | { |
| @@ -1771,9 +1755,9 @@ free_tree (np) | |||
| 1771 | 1755 | ||
| 1772 | /* | 1756 | /* |
| 1773 | * add_node () | 1757 | * add_node () |
| 1774 | * Adds a node to the tree of nodes. In etags mode, we don't keep | 1758 | * Adds a node to the tree of nodes. In etags mode, sort by file |
| 1775 | * it sorted; we just keep a linear list. In ctags mode, maintain | 1759 | * name. In ctags mode, sort by tag name. Make no attempt at |
| 1776 | * an ordered tree, with no attempt at balancing. | 1760 | * balancing. |
| 1777 | * | 1761 | * |
| 1778 | * add_node is the only function allowed to add nodes, so it can | 1762 | * add_node is the only function allowed to add nodes, so it can |
| 1779 | * maintain state. | 1763 | * maintain state. |
| @@ -1795,10 +1779,27 @@ add_node (np, cur_node_p) | |||
| 1795 | if (!CTAGS) | 1779 | if (!CTAGS) |
| 1796 | { | 1780 | { |
| 1797 | /* Etags Mode */ | 1781 | /* Etags Mode */ |
| 1798 | if (last_node == NULL) | 1782 | assert (last_node != NULL); |
| 1799 | fatal ("internal error in add_node", (char *)NULL); | 1783 | /* For each file name, tags are in a linked sublist on the right |
| 1800 | last_node->right = np; | 1784 | pointer. The first tags of different files are a linked list |
| 1801 | last_node = np; | 1785 | on the left pointer. last_node points to the end of the last |
| 1786 | used sublist. */ | ||
| 1787 | if (last_node->file == np->file) | ||
| 1788 | { | ||
| 1789 | /* Let's use the same sublist as the last added node. */ | ||
| 1790 | last_node->right = np; | ||
| 1791 | last_node = np; | ||
| 1792 | } | ||
| 1793 | else if (streq (cur_node->file, np->file)) | ||
| 1794 | { | ||
| 1795 | /* Scanning the list we found the head of a sublist which is | ||
| 1796 | good for us. Let's scan this sublist. */ | ||
| 1797 | add_node (np, &cur_node->right); | ||
| 1798 | } | ||
| 1799 | else | ||
| 1800 | /* The head of this sublist is not good for us. Let's try the | ||
| 1801 | next one. */ | ||
| 1802 | add_node (np, &cur_node->left); | ||
| 1802 | } | 1803 | } |
| 1803 | else | 1804 | else |
| 1804 | { | 1805 | { |
| @@ -1837,31 +1838,89 @@ add_node (np, cur_node_p) | |||
| 1837 | } | 1838 | } |
| 1838 | 1839 | ||
| 1839 | 1840 | ||
| 1841 | #if !CTAGS | ||
| 1842 | static int total_size_of_entries __P((node *)); | ||
| 1843 | static int number_len __P((long)); | ||
| 1844 | |||
| 1845 | /* Length of a number's decimal representation. */ | ||
| 1846 | static int | ||
| 1847 | number_len (num) | ||
| 1848 | long num; | ||
| 1849 | { | ||
| 1850 | int len = 1; | ||
| 1851 | while ((num /= 10) > 0) | ||
| 1852 | len += 1; | ||
| 1853 | return len; | ||
| 1854 | } | ||
| 1855 | |||
| 1856 | /* | ||
| 1857 | * Return total number of characters that put_entries will output for | ||
| 1858 | * the nodes in the linked list at the right of the specified node. | ||
| 1859 | * This count is irrelevant with etags.el since emacs 19.34 at least, | ||
| 1860 | * but is still supplied for backward compatibility. | ||
| 1861 | */ | ||
| 1862 | static int | ||
| 1863 | total_size_of_entries (np) | ||
| 1864 | register node *np; | ||
| 1865 | { | ||
| 1866 | register int total = 0; | ||
| 1867 | |||
| 1868 | for (; np != NULL; np = np->right) | ||
| 1869 | { | ||
| 1870 | total += strlen (np->pat) + 1; /* pat\177 */ | ||
| 1871 | if (np->name != NULL) | ||
| 1872 | total += strlen (np->name) + 1; /* name\001 */ | ||
| 1873 | total += number_len ((long) np->lno) + 1; /* lno, */ | ||
| 1874 | if (np->cno != invalidcharno) /* cno */ | ||
| 1875 | total += number_len (np->cno); | ||
| 1876 | total += 1; /* newline */ | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | return total; | ||
| 1880 | } | ||
| 1881 | #endif | ||
| 1882 | |||
| 1840 | static void | 1883 | static void |
| 1841 | put_entries (np) | 1884 | put_entries (np) |
| 1842 | register node *np; | 1885 | register node *np; |
| 1843 | { | 1886 | { |
| 1844 | register char *sp; | 1887 | register char *sp; |
| 1888 | static char *file = NULL; | ||
| 1845 | 1889 | ||
| 1846 | if (np == NULL) | 1890 | if (np == NULL) |
| 1847 | return; | 1891 | return; |
| 1848 | 1892 | ||
| 1849 | /* Output subentries that precede this one */ | 1893 | /* Output subentries that precede this one */ |
| 1850 | put_entries (np->left); | 1894 | if (CTAGS) |
| 1895 | put_entries (np->left); | ||
| 1851 | 1896 | ||
| 1852 | /* Output this entry */ | 1897 | /* Output this entry */ |
| 1853 | |||
| 1854 | if (!CTAGS) | 1898 | if (!CTAGS) |
| 1855 | { | 1899 | { |
| 1900 | /* Etags mode */ | ||
| 1901 | if (file != np->file | ||
| 1902 | && (file == NULL || !streq (file, np->file))) | ||
| 1903 | { | ||
| 1904 | file = np->file; | ||
| 1905 | fprintf (tagf, "\f\n%s,%d\n", | ||
| 1906 | file, total_size_of_entries (np)); | ||
| 1907 | } | ||
| 1908 | fputs (np->pat, tagf); | ||
| 1909 | fputc ('\177', tagf); | ||
| 1856 | if (np->name != NULL) | 1910 | if (np->name != NULL) |
| 1857 | fprintf (tagf, "%s\177%s\001%d,%ld\n", | 1911 | { |
| 1858 | np->pat, np->name, np->lno, np->cno); | 1912 | fputs (np->name, tagf); |
| 1913 | fputc ('\001', tagf); | ||
| 1914 | } | ||
| 1915 | fprintf (tagf, "%d,", np->lno); | ||
| 1916 | if (np->cno == invalidcharno) | ||
| 1917 | fputc ('\n', tagf); | ||
| 1859 | else | 1918 | else |
| 1860 | fprintf (tagf, "%s\177%d,%ld\n", | 1919 | fprintf (tagf, "%ld\n", np->cno); |
| 1861 | np->pat, np->lno, np->cno); | ||
| 1862 | } | 1920 | } |
| 1863 | else | 1921 | else |
| 1864 | { | 1922 | { |
| 1923 | /* Ctags mode */ | ||
| 1865 | if (np->name == NULL) | 1924 | if (np->name == NULL) |
| 1866 | error ("internal error: NULL name in ctags mode.", (char *)NULL); | 1925 | error ("internal error: NULL name in ctags mode.", (char *)NULL); |
| 1867 | 1926 | ||
| @@ -1899,50 +1958,11 @@ put_entries (np) | |||
| 1899 | } | 1958 | } |
| 1900 | } | 1959 | } |
| 1901 | 1960 | ||
| 1961 | |||
| 1902 | /* Output subentries that follow this one */ | 1962 | /* Output subentries that follow this one */ |
| 1903 | put_entries (np->right); | 1963 | put_entries (np->right); |
| 1904 | } | 1964 | if (!CTAGS) |
| 1905 | 1965 | put_entries (np->left); | |
| 1906 | /* Length of a number's decimal representation. */ | ||
| 1907 | static int | ||
| 1908 | number_len (num) | ||
| 1909 | long num; | ||
| 1910 | { | ||
| 1911 | int len = 1; | ||
| 1912 | while ((num /= 10) > 0) | ||
| 1913 | len += 1; | ||
| 1914 | return len; | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | /* | ||
| 1918 | * Return total number of characters that put_entries will output for | ||
| 1919 | * the nodes in the subtree of the specified node. Works only if | ||
| 1920 | * we are not ctags, but called only in that case. This count | ||
| 1921 | * is irrelevant with the new tags.el, but is still supplied for | ||
| 1922 | * backward compatibility. | ||
| 1923 | */ | ||
| 1924 | static int | ||
| 1925 | total_size_of_entries (np) | ||
| 1926 | register node *np; | ||
| 1927 | { | ||
| 1928 | register int total; | ||
| 1929 | |||
| 1930 | if (np == NULL) | ||
| 1931 | return 0; | ||
| 1932 | |||
| 1933 | for (total = 0; np != NULL; np = np->right) | ||
| 1934 | { | ||
| 1935 | /* Count left subentries. */ | ||
| 1936 | total += total_size_of_entries (np->left); | ||
| 1937 | |||
| 1938 | /* Count this entry */ | ||
| 1939 | total += strlen (np->pat) + 1; | ||
| 1940 | total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1; | ||
| 1941 | if (np->name != NULL) | ||
| 1942 | total += 1 + strlen (np->name); /* \001name */ | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | return total; | ||
| 1946 | } | 1966 | } |
| 1947 | 1967 | ||
| 1948 | 1968 | ||
| @@ -2033,7 +2053,7 @@ PSEUDO, 0, st_C_gnumacro | |||
| 2033 | #DEFVAR_, 0, st_C_gnumacro | 2053 | #DEFVAR_, 0, st_C_gnumacro |
| 2034 | %] | 2054 | %] |
| 2035 | and replace lines between %< and %> with its output, | 2055 | and replace lines between %< and %> with its output, |
| 2036 | then make in_word_set static. */ | 2056 | then make in_word_set and C_stab_entry static. */ |
| 2037 | /*%<*/ | 2057 | /*%<*/ |
| 2038 | /* C code produced by gperf version 2.7.1 (19981006 egcs) */ | 2058 | /* C code produced by gperf version 2.7.1 (19981006 egcs) */ |
| 2039 | /* Command-line: gperf -c -k 1,3 -o -p -r -t */ | 2059 | /* Command-line: gperf -c -k 1,3 -o -p -r -t */ |
| @@ -2218,7 +2238,7 @@ C_symtype (str, len, c_ext) | |||
| 2218 | * C functions and variables are recognized using a simple | 2238 | * C functions and variables are recognized using a simple |
| 2219 | * finite automaton. fvdef is its state variable. | 2239 | * finite automaton. fvdef is its state variable. |
| 2220 | */ | 2240 | */ |
| 2221 | enum | 2241 | static enum |
| 2222 | { | 2242 | { |
| 2223 | fvnone, /* nothing seen */ | 2243 | fvnone, /* nothing seen */ |
| 2224 | fdefunkey, /* Emacs DEFUN keyword seen */ | 2244 | fdefunkey, /* Emacs DEFUN keyword seen */ |
| @@ -2232,13 +2252,13 @@ enum | |||
| 2232 | vignore /* var-like: ignore until ';' */ | 2252 | vignore /* var-like: ignore until ';' */ |
| 2233 | } fvdef; | 2253 | } fvdef; |
| 2234 | 2254 | ||
| 2235 | bool fvextern; /* func or var: extern keyword seen; */ | 2255 | static bool fvextern; /* func or var: extern keyword seen; */ |
| 2236 | 2256 | ||
| 2237 | /* | 2257 | /* |
| 2238 | * typedefs are recognized using a simple finite automaton. | 2258 | * typedefs are recognized using a simple finite automaton. |
| 2239 | * typdef is its state variable. | 2259 | * typdef is its state variable. |
| 2240 | */ | 2260 | */ |
| 2241 | enum | 2261 | static enum |
| 2242 | { | 2262 | { |
| 2243 | tnone, /* nothing seen */ | 2263 | tnone, /* nothing seen */ |
| 2244 | tkeyseen, /* typedef keyword seen */ | 2264 | tkeyseen, /* typedef keyword seen */ |
| @@ -2253,7 +2273,7 @@ enum | |||
| 2253 | * using another simple finite automaton. `structdef' is its state | 2273 | * using another simple finite automaton. `structdef' is its state |
| 2254 | * variable. | 2274 | * variable. |
| 2255 | */ | 2275 | */ |
| 2256 | enum | 2276 | static enum |
| 2257 | { | 2277 | { |
| 2258 | snone, /* nothing seen yet, | 2278 | snone, /* nothing seen yet, |
| 2259 | or in struct body if cblev > 0 */ | 2279 | or in struct body if cblev > 0 */ |
| @@ -2266,12 +2286,12 @@ enum | |||
| 2266 | /* | 2286 | /* |
| 2267 | * When objdef is different from onone, objtag is the name of the class. | 2287 | * When objdef is different from onone, objtag is the name of the class. |
| 2268 | */ | 2288 | */ |
| 2269 | char *objtag = "<uninited>"; | 2289 | static char *objtag = "<uninited>"; |
| 2270 | 2290 | ||
| 2271 | /* | 2291 | /* |
| 2272 | * Yet another little state machine to deal with preprocessor lines. | 2292 | * Yet another little state machine to deal with preprocessor lines. |
| 2273 | */ | 2293 | */ |
| 2274 | enum | 2294 | static enum |
| 2275 | { | 2295 | { |
| 2276 | dnone, /* nothing seen */ | 2296 | dnone, /* nothing seen */ |
| 2277 | dsharpseen, /* '#' seen as first char on line */ | 2297 | dsharpseen, /* '#' seen as first char on line */ |
| @@ -2283,7 +2303,7 @@ enum | |||
| 2283 | * State machine for Objective C protocols and implementations. | 2303 | * State machine for Objective C protocols and implementations. |
| 2284 | * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995) | 2304 | * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995) |
| 2285 | */ | 2305 | */ |
| 2286 | enum | 2306 | static enum |
| 2287 | { | 2307 | { |
| 2288 | onone, /* nothing seen */ | 2308 | onone, /* nothing seen */ |
| 2289 | oprotocol, /* @interface or @protocol seen */ | 2309 | oprotocol, /* @interface or @protocol seen */ |
| @@ -2304,7 +2324,7 @@ enum | |||
| 2304 | * Use this structure to keep info about the token read, and how it | 2324 | * Use this structure to keep info about the token read, and how it |
| 2305 | * should be tagged. Used by the make_C_tag function to build a tag. | 2325 | * should be tagged. Used by the make_C_tag function to build a tag. |
| 2306 | */ | 2326 | */ |
| 2307 | struct tok | 2327 | static struct tok |
| 2308 | { | 2328 | { |
| 2309 | bool valid; | 2329 | bool valid; |
| 2310 | bool named; | 2330 | bool named; |
| @@ -2314,7 +2334,7 @@ struct tok | |||
| 2314 | long linepos; | 2334 | long linepos; |
| 2315 | char *line; | 2335 | char *line; |
| 2316 | } token; /* latest token read */ | 2336 | } token; /* latest token read */ |
| 2317 | linebuffer token_name; /* its name */ | 2337 | static linebuffer token_name; /* its name */ |
| 2318 | 2338 | ||
| 2319 | /* | 2339 | /* |
| 2320 | * Variables and functions for dealing with nested structures. | 2340 | * Variables and functions for dealing with nested structures. |
| @@ -2324,7 +2344,7 @@ static void pushclass_above __P((int, char *, int)); | |||
| 2324 | static void popclass_above __P((int)); | 2344 | static void popclass_above __P((int)); |
| 2325 | static void write_classname __P((linebuffer *, char *qualifier)); | 2345 | static void write_classname __P((linebuffer *, char *qualifier)); |
| 2326 | 2346 | ||
| 2327 | struct { | 2347 | static struct { |
| 2328 | char **cname; /* nested class names */ | 2348 | char **cname; /* nested class names */ |
| 2329 | int *cblev; /* nested class curly brace level */ | 2349 | int *cblev; /* nested class curly brace level */ |
| 2330 | int nl; /* class nesting level (elements used) */ | 2350 | int nl; /* class nesting level (elements used) */ |
| @@ -2711,7 +2731,7 @@ consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var) | |||
| 2711 | * the line currently read. By keeping two line buffers, and switching | 2731 | * the line currently read. By keeping two line buffers, and switching |
| 2712 | * them at end of line, it is possible to use those pointers. | 2732 | * them at end of line, it is possible to use those pointers. |
| 2713 | */ | 2733 | */ |
| 2714 | struct | 2734 | static struct |
| 2715 | { | 2735 | { |
| 2716 | long linepos; | 2736 | long linepos; |
| 2717 | linebuffer lb; | 2737 | linebuffer lb; |
| @@ -4027,8 +4047,8 @@ Perl_functions (inf) | |||
| 4027 | 4047 | ||
| 4028 | /* Perhaps I should back cp up one character, so the TAGS table | 4048 | /* Perhaps I should back cp up one character, so the TAGS table |
| 4029 | doesn't mention (and so depend upon) the following char. */ | 4049 | doesn't mention (and so depend upon) the following char. */ |
| 4030 | pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname, | 4050 | pfnote (varname, FALSE, |
| 4031 | FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 4051 | lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
| 4032 | } | 4052 | } |
| 4033 | } | 4053 | } |
| 4034 | } | 4054 | } |
| @@ -4507,12 +4527,12 @@ struct TEX_tabent | |||
| 4507 | int len; | 4527 | int len; |
| 4508 | }; | 4528 | }; |
| 4509 | 4529 | ||
| 4510 | struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */ | 4530 | static struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */ |
| 4511 | 4531 | ||
| 4512 | /* Default set of control sequences to put into TEX_toktab. | 4532 | /* Default set of control sequences to put into TEX_toktab. |
| 4513 | The value of environment var TEXTAGS is prepended to this. */ | 4533 | The value of environment var TEXTAGS is prepended to this. */ |
| 4514 | 4534 | ||
| 4515 | char *TEX_defenv = "\ | 4535 | static char *TEX_defenv = "\ |
| 4516 | :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ | 4536 | :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ |
| 4517 | :part:appendix:entry:index"; | 4537 | :part:appendix:entry:index"; |
| 4518 | 4538 | ||
| @@ -4520,9 +4540,9 @@ static void TEX_mode __P((FILE *)); | |||
| 4520 | static struct TEX_tabent *TEX_decode_env __P((char *, char *)); | 4540 | static struct TEX_tabent *TEX_decode_env __P((char *, char *)); |
| 4521 | static int TEX_Token __P((char *)); | 4541 | static int TEX_Token __P((char *)); |
| 4522 | 4542 | ||
| 4523 | char TEX_esc = '\\'; | 4543 | static char TEX_esc = '\\'; |
| 4524 | char TEX_opgrp = '{'; | 4544 | static char TEX_opgrp = '{'; |
| 4525 | char TEX_clgrp = '}'; | 4545 | static char TEX_clgrp = '}'; |
| 4526 | 4546 | ||
| 4527 | /* | 4547 | /* |
| 4528 | * TeX/LaTeX scanning loop. | 4548 | * TeX/LaTeX scanning loop. |
| @@ -5406,51 +5426,78 @@ readline (lbp, stream) | |||
| 5406 | { | 5426 | { |
| 5407 | /* Read new line. */ | 5427 | /* Read new line. */ |
| 5408 | long result = readline_internal (lbp, stream); | 5428 | long result = readline_internal (lbp, stream); |
| 5429 | |||
| 5430 | if (!no_line_directive | ||
| 5431 | && result > 12 && strneq (lbp->buffer, "#line ", 6)) | ||
| 5432 | { | ||
| 5433 | int start, lno; | ||
| 5434 | |||
| 5435 | if (sscanf (lbp->buffer, "#line %d \"%n", &lno, &start) == 1) | ||
| 5436 | { | ||
| 5437 | char *endp = lbp->buffer + start; | ||
| 5438 | |||
| 5439 | while ((endp = etags_strchr (endp, '"')) != NULL | ||
| 5440 | && endp[-1] == '\\') | ||
| 5441 | endp++; | ||
| 5442 | if (endp != NULL) | ||
| 5443 | { | ||
| 5444 | int len = endp - (lbp->buffer + start); | ||
| 5445 | |||
| 5446 | if (!strneq (curfile, lbp->buffer + start, len)) | ||
| 5447 | curfile = savenstr (lbp->buffer + start, len); | ||
| 5448 | lineno = lno; | ||
| 5449 | nocharno = TRUE; /* do not use char position for tags */ | ||
| 5450 | return readline (lbp, stream); | ||
| 5451 | } | ||
| 5452 | } | ||
| 5453 | } | ||
| 5409 | #ifdef ETAGS_REGEXPS | 5454 | #ifdef ETAGS_REGEXPS |
| 5410 | int match; | 5455 | { |
| 5411 | pattern *pp; | 5456 | int match; |
| 5457 | pattern *pp; | ||
| 5412 | 5458 | ||
| 5413 | /* Match against relevant patterns. */ | 5459 | /* Match against relevant patterns. */ |
| 5414 | if (lbp->len > 0) | 5460 | if (lbp->len > 0) |
| 5415 | for (pp = p_head; pp != NULL; pp = pp->p_next) | 5461 | for (pp = p_head; pp != NULL; pp = pp->p_next) |
| 5416 | { | 5462 | { |
| 5417 | /* Only use generic regexps or those for the current language. */ | 5463 | /* Only use generic regexps or those for the current language. */ |
| 5418 | if (pp->lang != NULL && pp->lang != curlang) | 5464 | if (pp->lang != NULL && pp->lang != curlang) |
| 5419 | continue; | 5465 | continue; |
| 5420 | 5466 | ||
| 5421 | match = re_match (pp->pat, lbp->buffer, lbp->len, 0, &pp->regs); | 5467 | match = re_match (pp->pat, lbp->buffer, lbp->len, 0, &pp->regs); |
| 5422 | switch (match) | 5468 | switch (match) |
| 5423 | { | 5469 | { |
| 5424 | case -2: | 5470 | case -2: |
| 5425 | /* Some error. */ | 5471 | /* Some error. */ |
| 5426 | if (!pp->error_signaled) | 5472 | if (!pp->error_signaled) |
| 5427 | { | 5473 | { |
| 5428 | error ("error while matching \"%s\"", pp->regex); | 5474 | error ("error while matching \"%s\"", pp->regex); |
| 5429 | pp->error_signaled = TRUE; | 5475 | pp->error_signaled = TRUE; |
| 5430 | } | 5476 | } |
| 5431 | break; | 5477 | break; |
| 5432 | case -1: | 5478 | case -1: |
| 5433 | /* No match. */ | 5479 | /* No match. */ |
| 5434 | break; | 5480 | break; |
| 5435 | default: | 5481 | default: |
| 5436 | /* Match occurred. Construct a tag. */ | 5482 | /* Match occurred. Construct a tag. */ |
| 5437 | if (pp->name_pattern[0] != '\0') | 5483 | if (pp->name_pattern[0] != '\0') |
| 5438 | { | 5484 | { |
| 5439 | /* Make a named tag. */ | 5485 | /* Make a named tag. */ |
| 5440 | char *name = substitute (lbp->buffer, | 5486 | char *name = substitute (lbp->buffer, |
| 5441 | pp->name_pattern, &pp->regs); | 5487 | pp->name_pattern, &pp->regs); |
| 5442 | if (name != NULL) | 5488 | if (name != NULL) |
| 5443 | pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno); | 5489 | pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno); |
| 5444 | } | 5490 | } |
| 5445 | else | 5491 | else |
| 5446 | { | 5492 | { |
| 5447 | /* Make an unnamed tag. */ | 5493 | /* Make an unnamed tag. */ |
| 5448 | pfnote ((char *)NULL, TRUE, | 5494 | pfnote ((char *)NULL, TRUE, |
| 5449 | lbp->buffer, match, lineno, linecharno); | 5495 | lbp->buffer, match, lineno, linecharno); |
| 5450 | } | 5496 | } |
| 5451 | break; | 5497 | break; |
| 5452 | } | 5498 | } |
| 5453 | } | 5499 | } |
| 5500 | } | ||
| 5454 | #endif /* ETAGS_REGEXPS */ | 5501 | #endif /* ETAGS_REGEXPS */ |
| 5455 | 5502 | ||
| 5456 | return result; | 5503 | return result; |
| @@ -5826,7 +5873,7 @@ linebuffer_setlen (lbp, toksize) | |||
| 5826 | } | 5873 | } |
| 5827 | 5874 | ||
| 5828 | /* Like malloc but get fatal error if memory is exhausted. */ | 5875 | /* Like malloc but get fatal error if memory is exhausted. */ |
| 5829 | PTR | 5876 | static PTR |
| 5830 | xmalloc (size) | 5877 | xmalloc (size) |
| 5831 | unsigned int size; | 5878 | unsigned int size; |
| 5832 | { | 5879 | { |
| @@ -5836,7 +5883,7 @@ xmalloc (size) | |||
| 5836 | return result; | 5883 | return result; |
| 5837 | } | 5884 | } |
| 5838 | 5885 | ||
| 5839 | PTR | 5886 | static PTR |
| 5840 | xrealloc (ptr, size) | 5887 | xrealloc (ptr, size) |
| 5841 | char *ptr; | 5888 | char *ptr; |
| 5842 | unsigned int size; | 5889 | unsigned int size; |