comparison lib-src/etags.c @ 44605:1bec0b430206

Bug fix. New version to come soon.
author Francesco Potortì <pot@gnu.org>
date Mon, 15 Apr 2002 15:55:07 +0000
parents 4702b23921b4
children 8f3420af28a8
comparison
equal deleted inserted replaced
44604:4702b23921b4 44605:1bec0b430206
344 int main __P((int, char **)); 344 int main __P((int, char **));
345 345
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 *));
353 static char *get_tag __P((char *)); 353 static char *get_tag __P((char *));
354 354
378 static char *skip_non_spaces __P((char *)); 378 static char *skip_non_spaces __P((char *));
379 static char *savenstr __P((char *, int)); 379 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 *));
386 static char *absolute_dirname __P((char *, char *)); 387 static char *absolute_dirname __P((char *, char *));
387 static bool filename_is_absolute __P((char *f)); 388 static bool filename_is_absolute __P((char *f));
1349 1350
1350 /* 1351 /*
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;
1359 1361
1360 /* Try whole file name first. */ 1362 /* Try whole file name first. */
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. */
1368 suffix = etags_strrchr (file, '.'); 1372 suffix = etags_strrchr (file, '.');
1369 if (suffix == NULL) 1373 if (suffix == NULL)
1370 return NULL; 1374 return NULL;
1371 suffix += 1; 1375 suffix += 1;
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 }
1379 1385
1380 1386
1419 { 1425 {
1420 assert (fdp->infname != NULL); 1426 assert (fdp->infname != NULL);
1421 if (streq (uncompressed_name, fdp->infname)) 1427 if (streq (uncompressed_name, fdp->infname))
1422 goto cleanup; 1428 goto cleanup;
1423 } 1429 }
1424
1425 /* Create a new input file description entry. */
1426 fdp = fdhead;
1427 fdhead = xnew (1, fdesc);
1428 *fdhead = emptyfdesc;
1429 fdhead->next = fdp;
1430 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. */
1434 real_name = NULL; 1434 real_name = NULL;
1494 { 1494 {
1495 perror (real_name); 1495 perror (real_name);
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);
1520 1525
1521 if (real_name == compressed_name) 1526 if (real_name == compressed_name)
1524 retval = fclose (inf); 1529 retval = fclose (inf);
1525 if (retval < 0) 1530 if (retval < 0)
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;
1533 } 1540 }
1534 1541
1581 } 1588 }
1582 1589
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;
1590 parser = lang->function; 1597 parser = lang->function;
1591 } 1598 }
1620 parser = lang->function; 1627 parser = lang->function;
1621 } 1628 }
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 {
1633 fdesc **fdpp = &fdhead; 1657 fdesc **fdpp = &fdhead;
1634 while (*fdpp != NULL) 1658 while (*fdpp != NULL)
1640 fdesc *badfdp = *fdpp; 1664 fdesc *badfdp = *fdpp;
1641 1665
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
1650 /* Delete badfdp. */ 1677 /* Delete badfdp. */
1651 if (badfdp->infname != NULL) free (badfdp->infname); 1678 if (badfdp->infname != NULL) free (badfdp->infname);
1662 if (parser != NULL) 1689 if (parser != NULL)
1663 { 1690 {
1664 parser (inf); 1691 parser (inf);
1665 return; 1692 return;
1666 } 1693 }
1667
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 1694
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");
1676 Fortran_functions (inf); 1698 Fortran_functions (inf);
1914 fdesc *badfdp; 1936 fdesc *badfdp;
1915 node *np; 1937 node *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)
1922 invalidate_nodes (badfdp, np->right); 1947 invalidate_nodes (badfdp, np->right);
1923 } 1948 }
5739 r = sp; 5764 r = sp;
5740 } while (*sp++); 5765 } while (*sp++);
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
5748 * 5772 *
5749 * Identical to POSIX strchr, included for portability. 5773 * Identical to POSIX strchr, included for portability.
5757 { 5781 {
5758 if (*sp == c) 5782 if (*sp == c)
5759 return (char *)sp; 5783 return (char *)sp;
5760 } while (*sp++); 5784 } while (*sp++);
5761 return NULL; 5785 return NULL;
5786 }
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);
5762 } 5806 }
5763 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)