diff options
| author | Francesco Potortì | 2002-04-15 15:55:07 +0000 |
|---|---|---|
| committer | Francesco Potortì | 2002-04-15 15:55:07 +0000 |
| commit | a53638904d382de24eef76bf4278b7f88c84ca32 (patch) | |
| tree | 3410e29fef7e98a83cc23cb2010ccbeff773e5f5 /lib-src | |
| parent | 9e0a3f98766d3828cb08374e474fdfd5d7ec2188 (diff) | |
| download | emacs-a53638904d382de24eef76bf4278b7f88c84ca32.tar.gz emacs-a53638904d382de24eef76bf4278b7f88c84ca32.zip | |
Bug fix. New version to come soon.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 5fd45e21fab..48989426641 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -346,7 +346,7 @@ int main __P((int, char **)); | |||
| 346 | static compressor *get_compressor_from_suffix __P((char *, char **)); | 346 | static compressor *get_compressor_from_suffix __P((char *, char **)); |
| 347 | static language *get_language_from_langname __P((const char *)); | 347 | static language *get_language_from_langname __P((const char *)); |
| 348 | static language *get_language_from_interpreter __P((char *)); | 348 | static language *get_language_from_interpreter __P((char *)); |
| 349 | static language *get_language_from_filename __P((char *)); | 349 | static language *get_language_from_filename __P((char *, bool)); |
| 350 | static long readline __P((linebuffer *, FILE *)); | 350 | static long readline __P((linebuffer *, FILE *)); |
| 351 | static long readline_internal __P((linebuffer *, FILE *)); | 351 | static long readline_internal __P((linebuffer *, FILE *)); |
| 352 | static bool nocase_tail __P((char *)); | 352 | static bool nocase_tail __P((char *)); |
| @@ -380,6 +380,7 @@ static char *savenstr __P((char *, int)); | |||
| 380 | static char *savestr __P((char *)); | 380 | static char *savestr __P((char *)); |
| 381 | static char *etags_strchr __P((const char *, int)); | 381 | static char *etags_strchr __P((const char *, int)); |
| 382 | static char *etags_strrchr __P((const char *, int)); | 382 | static char *etags_strrchr __P((const char *, int)); |
| 383 | static bool strcaseeq __P((const char *, const char *)); | ||
| 383 | static char *etags_getcwd __P((void)); | 384 | static char *etags_getcwd __P((void)); |
| 384 | static char *relative_filename __P((char *, char *)); | 385 | static char *relative_filename __P((char *, char *)); |
| 385 | static char *absolute_filename __P((char *, char *)); | 386 | static char *absolute_filename __P((char *, char *)); |
| @@ -1351,8 +1352,9 @@ get_language_from_interpreter (interpreter) | |||
| 1351 | * Return a language given the file name. | 1352 | * Return a language given the file name. |
| 1352 | */ | 1353 | */ |
| 1353 | static language * | 1354 | static language * |
| 1354 | get_language_from_filename (file) | 1355 | get_language_from_filename (file, case_sensitive) |
| 1355 | char *file; | 1356 | char *file; |
| 1357 | bool case_sensitive; | ||
| 1356 | { | 1358 | { |
| 1357 | language *lang; | 1359 | language *lang; |
| 1358 | char **name, **ext, *suffix; | 1360 | char **name, **ext, *suffix; |
| @@ -1361,7 +1363,9 @@ get_language_from_filename (file) | |||
| 1361 | for (lang = lang_names; lang->name != NULL; lang++) | 1363 | for (lang = lang_names; lang->name != NULL; lang++) |
| 1362 | if (lang->filenames != NULL) | 1364 | if (lang->filenames != NULL) |
| 1363 | for (name = lang->filenames; *name != NULL; name++) | 1365 | for (name = lang->filenames; *name != NULL; name++) |
| 1364 | if (streq (*name, file)) | 1366 | if ((case_sensitive) |
| 1367 | ? streq (*name, file) | ||
| 1368 | : strcaseeq (*name, file)) | ||
| 1365 | return lang; | 1369 | return lang; |
| 1366 | 1370 | ||
| 1367 | /* If not found, try suffix after last dot. */ | 1371 | /* If not found, try suffix after last dot. */ |
| @@ -1372,7 +1376,9 @@ get_language_from_filename (file) | |||
| 1372 | for (lang = lang_names; lang->name != NULL; lang++) | 1376 | for (lang = lang_names; lang->name != NULL; lang++) |
| 1373 | if (lang->suffixes != NULL) | 1377 | if (lang->suffixes != NULL) |
| 1374 | for (ext = lang->suffixes; *ext != NULL; ext++) | 1378 | for (ext = lang->suffixes; *ext != NULL; ext++) |
| 1375 | if (streq (*ext, suffix)) | 1379 | if ((case_sensitive) |
| 1380 | ? streq (*ext, suffix) | ||
| 1381 | : strcaseeq (*ext, suffix)) | ||
| 1376 | return lang; | 1382 | return lang; |
| 1377 | return NULL; | 1383 | return NULL; |
| 1378 | } | 1384 | } |
| @@ -1422,12 +1428,6 @@ process_file (file, lang) | |||
| 1422 | goto cleanup; | 1428 | goto cleanup; |
| 1423 | } | 1429 | } |
| 1424 | 1430 | ||
| 1425 | /* Create a new input file description entry. */ | ||
| 1426 | fdp = fdhead; | ||
| 1427 | fdhead = xnew (1, fdesc); | ||
| 1428 | *fdhead = emptyfdesc; | ||
| 1429 | fdhead->next = fdp; | ||
| 1430 | |||
| 1431 | if (stat (real_name, &stat_buf) != 0) | 1431 | if (stat (real_name, &stat_buf) != 0) |
| 1432 | { | 1432 | { |
| 1433 | /* Reset real_name and try with a different name. */ | 1433 | /* Reset real_name and try with a different name. */ |
| @@ -1496,24 +1496,29 @@ process_file (file, lang) | |||
| 1496 | goto cleanup; | 1496 | goto cleanup; |
| 1497 | } | 1497 | } |
| 1498 | 1498 | ||
| 1499 | fdhead->infname = savestr (uncompressed_name); | 1499 | /* Create a new input file description entry. */ |
| 1500 | fdhead->lang = lang; | 1500 | fdp = xnew (1, fdesc); |
| 1501 | fdhead->infabsname = absolute_filename (uncompressed_name, cwd); | 1501 | *fdp = emptyfdesc; |
| 1502 | fdhead->infabsdir = absolute_dirname (uncompressed_name, cwd); | 1502 | fdp->next = fdhead; |
| 1503 | fdp->infname = savestr (uncompressed_name); | ||
| 1504 | fdp->lang = lang; | ||
| 1505 | fdp->infabsname = absolute_filename (uncompressed_name, cwd); | ||
| 1506 | fdp->infabsdir = absolute_dirname (uncompressed_name, cwd); | ||
| 1503 | if (filename_is_absolute (uncompressed_name)) | 1507 | if (filename_is_absolute (uncompressed_name)) |
| 1504 | { | 1508 | { |
| 1505 | /* file is an absolute file name. Canonicalize it. */ | 1509 | /* file is an absolute file name. Canonicalize it. */ |
| 1506 | fdhead->taggedfname = absolute_filename (uncompressed_name, NULL); | 1510 | fdp->taggedfname = absolute_filename (uncompressed_name, NULL); |
| 1507 | } | 1511 | } |
| 1508 | else | 1512 | else |
| 1509 | { | 1513 | { |
| 1510 | /* file is a file name relative to cwd. Make it relative | 1514 | /* file is a file name relative to cwd. Make it relative |
| 1511 | to the directory of the tags file. */ | 1515 | to the directory of the tags file. */ |
| 1512 | fdhead->taggedfname = relative_filename (uncompressed_name, tagfiledir); | 1516 | fdp->taggedfname = relative_filename (uncompressed_name, tagfiledir); |
| 1513 | } | 1517 | } |
| 1514 | fdhead->usecharno = TRUE; /* use char position when making tags */ | 1518 | fdp->usecharno = TRUE; /* use char position when making tags */ |
| 1515 | fdhead->prop = NULL; | 1519 | fdp->prop = NULL; |
| 1516 | 1520 | ||
| 1521 | fdhead = fdp; | ||
| 1517 | curfdp = fdhead; /* the current file description */ | 1522 | curfdp = fdhead; /* the current file description */ |
| 1518 | 1523 | ||
| 1519 | find_entries (inf); | 1524 | find_entries (inf); |
| @@ -1526,7 +1531,9 @@ process_file (file, lang) | |||
| 1526 | pfatal (file); | 1531 | pfatal (file); |
| 1527 | 1532 | ||
| 1528 | cleanup: | 1533 | cleanup: |
| 1529 | /* XXX if no more useful, delete head of file description list */ | 1534 | /* Memory leak here: if this is not metasource and if it contained no #line |
| 1535 | directives, curfdp could be freed, and so could all nodes pointing to it | ||
| 1536 | if not CTAGS. */ | ||
| 1530 | if (compressed_name) free (compressed_name); | 1537 | if (compressed_name) free (compressed_name); |
| 1531 | if (uncompressed_name) free (uncompressed_name); | 1538 | if (uncompressed_name) free (uncompressed_name); |
| 1532 | return; | 1539 | return; |
| @@ -1583,7 +1590,7 @@ find_entries (inf) | |||
| 1583 | /* Else try to guess the language given the file name. */ | 1590 | /* Else try to guess the language given the file name. */ |
| 1584 | if (parser == NULL) | 1591 | if (parser == NULL) |
| 1585 | { | 1592 | { |
| 1586 | lang = get_language_from_filename (curfdp->infname); | 1593 | lang = get_language_from_filename (curfdp->infname, TRUE); |
| 1587 | if (lang != NULL && lang->function != NULL) | 1594 | if (lang != NULL && lang->function != NULL) |
| 1588 | { | 1595 | { |
| 1589 | curfdp->lang = lang; | 1596 | curfdp->lang = lang; |
| @@ -1622,11 +1629,28 @@ find_entries (inf) | |||
| 1622 | } | 1629 | } |
| 1623 | } | 1630 | } |
| 1624 | 1631 | ||
| 1632 | /* We rewind here, even if inf may be a pipe. We fail if the | ||
| 1633 | length of the first line is longer than the pipe block size, | ||
| 1634 | which is unlikely. */ | ||
| 1635 | if (parser == NULL) | ||
| 1636 | rewind (inf); | ||
| 1637 | #if 0 | ||
| 1638 | /* Else try to guess the language given the case insensitive file name. */ | ||
| 1639 | if (parser == NULL) | ||
| 1640 | { | ||
| 1641 | lang = get_language_from_filename (curfdp->infname, FALSE); | ||
| 1642 | if (lang != NULL && lang->function != NULL) | ||
| 1643 | { | ||
| 1644 | curfdp->lang = lang; | ||
| 1645 | parser = lang->function; | ||
| 1646 | } | ||
| 1647 | } | ||
| 1648 | #endif | ||
| 1625 | if (!no_line_directive | 1649 | if (!no_line_directive |
| 1626 | && curfdp->lang != NULL && curfdp->lang->metasource) | 1650 | && curfdp->lang != NULL && curfdp->lang->metasource) |
| 1627 | /* It may be that this is an xxx.y file, and we already parsed an xxx.c | 1651 | /* It may be that this is a bingo.y file, and we already parsed a bingo.c |
| 1628 | file, or anyway we parsed a file that is automatically generated from | 1652 | file, or anyway we parsed a file that is automatically generated from |
| 1629 | this one. If this is the case, the xxx.c file contained #line | 1653 | this one. If this is the case, the bingo.c file contained #line |
| 1630 | directives that generated tags pointing to this file. Let's delete | 1654 | directives that generated tags pointing to this file. Let's delete |
| 1631 | them all before parsing this file, which is the real source. */ | 1655 | them all before parsing this file, which is the real source. */ |
| 1632 | { | 1656 | { |
| @@ -1642,8 +1666,11 @@ find_entries (inf) | |||
| 1642 | *fdpp = badfdp->next; /* remove the bad description from the list */ | 1666 | *fdpp = badfdp->next; /* remove the bad description from the list */ |
| 1643 | fdpp = &badfdp->next; /* advance the list pointer */ | 1667 | fdpp = &badfdp->next; /* advance the list pointer */ |
| 1644 | 1668 | ||
| 1645 | fprintf (stderr, "Removing references to \"%s\" obtained from \"%s\"\n", | 1669 | if (DEBUG) |
| 1646 | badfdp->taggedfname, badfdp->infname); | 1670 | fprintf (stderr, |
| 1671 | "Removing references to \"%s\" obtained from \"%s\"\n", | ||
| 1672 | badfdp->taggedfname, badfdp->infname); | ||
| 1673 | |||
| 1647 | /* Delete the tags referring to badfdp. */ | 1674 | /* Delete the tags referring to badfdp. */ |
| 1648 | invalidate_nodes (badfdp, nodehead); | 1675 | invalidate_nodes (badfdp, nodehead); |
| 1649 | 1676 | ||
| @@ -1665,11 +1692,6 @@ find_entries (inf) | |||
| 1665 | return; | 1692 | return; |
| 1666 | } | 1693 | } |
| 1667 | 1694 | ||
| 1668 | /* We rewind here, even if inf may be a pipe. We fail if the | ||
| 1669 | length of the first line is longer than the pipe block size, | ||
| 1670 | which is unlikely. */ | ||
| 1671 | rewind (inf); | ||
| 1672 | |||
| 1673 | /* Else try Fortran. */ | 1695 | /* Else try Fortran. */ |
| 1674 | old_last_node = last_node; | 1696 | old_last_node = last_node; |
| 1675 | curfdp->lang = get_language_from_langname ("fortran"); | 1697 | curfdp->lang = get_language_from_langname ("fortran"); |
| @@ -1916,6 +1938,9 @@ invalidate_nodes (badfdp, np) | |||
| 1916 | { | 1938 | { |
| 1917 | if (np->left != NULL) | 1939 | if (np->left != NULL) |
| 1918 | invalidate_nodes (badfdp, np->left); | 1940 | invalidate_nodes (badfdp, np->left); |
| 1941 | /* Memory leak here: if not CTAGS, in which case it would be quite | ||
| 1942 | difficult, the node could be freed. If CTAGS the node is part of a | ||
| 1943 | binary tree, if not it is part of a list of lists. */ | ||
| 1919 | if (np->fdp == badfdp) | 1944 | if (np->fdp == badfdp) |
| 1920 | np-> valid = FALSE; | 1945 | np-> valid = FALSE; |
| 1921 | if (np->right != NULL) | 1946 | if (np->right != NULL) |
| @@ -5741,7 +5766,6 @@ etags_strrchr (sp, c) | |||
| 5741 | return (char *)r; | 5766 | return (char *)r; |
| 5742 | } | 5767 | } |
| 5743 | 5768 | ||
| 5744 | |||
| 5745 | /* | 5769 | /* |
| 5746 | * Return the ptr in sp at which the character c first | 5770 | * Return the ptr in sp at which the character c first |
| 5747 | * appears; NULL if not found | 5771 | * appears; NULL if not found |
| @@ -5761,6 +5785,26 @@ etags_strchr (sp, c) | |||
| 5761 | return NULL; | 5785 | return NULL; |
| 5762 | } | 5786 | } |
| 5763 | 5787 | ||
| 5788 | /* | ||
| 5789 | * Return TRUE if the two strings are equal, ignoring case for alphabetic | ||
| 5790 | * characters. | ||
| 5791 | * | ||
| 5792 | * Analogous to BSD's strcasecmp, included for portability. | ||
| 5793 | */ | ||
| 5794 | static bool | ||
| 5795 | strcaseeq (s1, s2) | ||
| 5796 | register const char *s1; | ||
| 5797 | register const char *s2; | ||
| 5798 | { | ||
| 5799 | while (*s1 != '\0' | ||
| 5800 | && (ISALPHA (*s1) && ISALPHA (*s2) | ||
| 5801 | ? lowcase (*s1) == lowcase (*s2) | ||
| 5802 | : *s1 == *s2)) | ||
| 5803 | s1++, s2++; | ||
| 5804 | |||
| 5805 | return (*s1 == *s2); | ||
| 5806 | } | ||
| 5807 | |||
| 5764 | /* Skip spaces, return new pointer. */ | 5808 | /* Skip spaces, return new pointer. */ |
| 5765 | static char * | 5809 | static char * |
| 5766 | skip_spaces (cp) | 5810 | skip_spaces (cp) |