346 |
static compressor *get_compressor_from_suffix __P((char *, char **)); |
static compressor *get_compressor_from_suffix __P((char *, char **)); |
347 |
static language *get_language_from_langname __P((const char *)); |
static language *get_language_from_langname __P((const char *)); |
348 |
static language *get_language_from_interpreter __P((char *)); |
static language *get_language_from_interpreter __P((char *)); |
349 |
static language *get_language_from_filename __P((char *)); |
static language *get_language_from_filename __P((char *, bool)); |
350 |
static long readline __P((linebuffer *, FILE *)); |
static long readline __P((linebuffer *, FILE *)); |
351 |
static long readline_internal __P((linebuffer *, FILE *)); |
static long readline_internal __P((linebuffer *, FILE *)); |
352 |
static bool nocase_tail __P((char *)); |
static bool nocase_tail __P((char *)); |
380 |
static char *savestr __P((char *)); |
static char *savestr __P((char *)); |
381 |
static char *etags_strchr __P((const char *, int)); |
static char *etags_strchr __P((const char *, int)); |
382 |
static char *etags_strrchr __P((const char *, int)); |
static char *etags_strrchr __P((const char *, int)); |
383 |
|
static bool strcaseeq __P((const char *, const char *)); |
384 |
static char *etags_getcwd __P((void)); |
static char *etags_getcwd __P((void)); |
385 |
static char *relative_filename __P((char *, char *)); |
static char *relative_filename __P((char *, char *)); |
386 |
static char *absolute_filename __P((char *, char *)); |
static char *absolute_filename __P((char *, char *)); |
1352 |
* Return a language given the file name. |
* Return a language given the file name. |
1353 |
*/ |
*/ |
1354 |
static language * |
static language * |
1355 |
get_language_from_filename (file) |
get_language_from_filename (file, case_sensitive) |
1356 |
char *file; |
char *file; |
1357 |
|
bool case_sensitive; |
1358 |
{ |
{ |
1359 |
language *lang; |
language *lang; |
1360 |
char **name, **ext, *suffix; |
char **name, **ext, *suffix; |
1363 |
for (lang = lang_names; lang->name != NULL; lang++) |
for (lang = lang_names; lang->name != NULL; lang++) |
1364 |
if (lang->filenames != NULL) |
if (lang->filenames != NULL) |
1365 |
for (name = lang->filenames; *name != NULL; name++) |
for (name = lang->filenames; *name != NULL; name++) |
1366 |
if (streq (*name, file)) |
if ((case_sensitive) |
1367 |
|
? streq (*name, file) |
1368 |
|
: strcaseeq (*name, file)) |
1369 |
return lang; |
return lang; |
1370 |
|
|
1371 |
/* If not found, try suffix after last dot. */ |
/* If not found, try suffix after last dot. */ |
1376 |
for (lang = lang_names; lang->name != NULL; lang++) |
for (lang = lang_names; lang->name != NULL; lang++) |
1377 |
if (lang->suffixes != NULL) |
if (lang->suffixes != NULL) |
1378 |
for (ext = lang->suffixes; *ext != NULL; ext++) |
for (ext = lang->suffixes; *ext != NULL; ext++) |
1379 |
if (streq (*ext, suffix)) |
if ((case_sensitive) |
1380 |
|
? streq (*ext, suffix) |
1381 |
|
: strcaseeq (*ext, suffix)) |
1382 |
return lang; |
return lang; |
1383 |
return NULL; |
return NULL; |
1384 |
} |
} |
1428 |
goto cleanup; |
goto cleanup; |
1429 |
} |
} |
1430 |
|
|
|
/* Create a new input file description entry. */ |
|
|
fdp = fdhead; |
|
|
fdhead = xnew (1, fdesc); |
|
|
*fdhead = emptyfdesc; |
|
|
fdhead->next = fdp; |
|
|
|
|
1431 |
if (stat (real_name, &stat_buf) != 0) |
if (stat (real_name, &stat_buf) != 0) |
1432 |
{ |
{ |
1433 |
/* Reset real_name and try with a different name. */ |
/* Reset real_name and try with a different name. */ |
1496 |
goto cleanup; |
goto cleanup; |
1497 |
} |
} |
1498 |
|
|
1499 |
fdhead->infname = savestr (uncompressed_name); |
/* Create a new input file description entry. */ |
1500 |
fdhead->lang = lang; |
fdp = xnew (1, fdesc); |
1501 |
fdhead->infabsname = absolute_filename (uncompressed_name, cwd); |
*fdp = emptyfdesc; |
1502 |
fdhead->infabsdir = absolute_dirname (uncompressed_name, cwd); |
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); |
1507 |
if (filename_is_absolute (uncompressed_name)) |
if (filename_is_absolute (uncompressed_name)) |
1508 |
{ |
{ |
1509 |
/* file is an absolute file name. Canonicalize it. */ |
/* file is an absolute file name. Canonicalize it. */ |
1510 |
fdhead->taggedfname = absolute_filename (uncompressed_name, NULL); |
fdp->taggedfname = absolute_filename (uncompressed_name, NULL); |
1511 |
} |
} |
1512 |
else |
else |
1513 |
{ |
{ |
1514 |
/* file is a file name relative to cwd. Make it relative |
/* file is a file name relative to cwd. Make it relative |
1515 |
to the directory of the tags file. */ |
to the directory of the tags file. */ |
1516 |
fdhead->taggedfname = relative_filename (uncompressed_name, tagfiledir); |
fdp->taggedfname = relative_filename (uncompressed_name, tagfiledir); |
1517 |
} |
} |
1518 |
fdhead->usecharno = TRUE; /* use char position when making tags */ |
fdp->usecharno = TRUE; /* use char position when making tags */ |
1519 |
fdhead->prop = NULL; |
fdp->prop = NULL; |
1520 |
|
|
1521 |
|
fdhead = fdp; |
1522 |
curfdp = fdhead; /* the current file description */ |
curfdp = fdhead; /* the current file description */ |
1523 |
|
|
1524 |
find_entries (inf); |
find_entries (inf); |
1531 |
pfatal (file); |
pfatal (file); |
1532 |
|
|
1533 |
cleanup: |
cleanup: |
1534 |
/* XXX if no more useful, delete head of file description list */ |
/* 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. */ |
1537 |
if (compressed_name) free (compressed_name); |
if (compressed_name) free (compressed_name); |
1538 |
if (uncompressed_name) free (uncompressed_name); |
if (uncompressed_name) free (uncompressed_name); |
1539 |
return; |
return; |
1590 |
/* Else try to guess the language given the file name. */ |
/* Else try to guess the language given the file name. */ |
1591 |
if (parser == NULL) |
if (parser == NULL) |
1592 |
{ |
{ |
1593 |
lang = get_language_from_filename (curfdp->infname); |
lang = get_language_from_filename (curfdp->infname, TRUE); |
1594 |
if (lang != NULL && lang->function != NULL) |
if (lang != NULL && lang->function != NULL) |
1595 |
{ |
{ |
1596 |
curfdp->lang = lang; |
curfdp->lang = lang; |
1629 |
} |
} |
1630 |
} |
} |
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 |
1649 |
if (!no_line_directive |
if (!no_line_directive |
1650 |
&& curfdp->lang != NULL && curfdp->lang->metasource) |
&& curfdp->lang != NULL && curfdp->lang->metasource) |
1651 |
/* It may be that this is an xxx.y file, and we already parsed an xxx.c |
/* It may be that this is a bingo.y file, and we already parsed a bingo.c |
1652 |
file, or anyway we parsed a file that is automatically generated from |
file, or anyway we parsed a file that is automatically generated from |
1653 |
this one. If this is the case, the xxx.c file contained #line |
this one. If this is the case, the bingo.c file contained #line |
1654 |
directives that generated tags pointing to this file. Let's delete |
directives that generated tags pointing to this file. Let's delete |
1655 |
them all before parsing this file, which is the real source. */ |
them all before parsing this file, which is the real source. */ |
1656 |
{ |
{ |
1666 |
*fdpp = badfdp->next; /* remove the bad description from the list */ |
*fdpp = badfdp->next; /* remove the bad description from the list */ |
1667 |
fdpp = &badfdp->next; /* advance the list pointer */ |
fdpp = &badfdp->next; /* advance the list pointer */ |
1668 |
|
|
1669 |
fprintf (stderr, "Removing references to \"%s\" obtained from \"%s\"\n", |
if (DEBUG) |
1670 |
badfdp->taggedfname, badfdp->infname); |
fprintf (stderr, |
1671 |
|
"Removing references to \"%s\" obtained from \"%s\"\n", |
1672 |
|
badfdp->taggedfname, badfdp->infname); |
1673 |
|
|
1674 |
/* Delete the tags referring to badfdp. */ |
/* Delete the tags referring to badfdp. */ |
1675 |
invalidate_nodes (badfdp, nodehead); |
invalidate_nodes (badfdp, nodehead); |
1676 |
|
|
1692 |
return; |
return; |
1693 |
} |
} |
1694 |
|
|
|
/* We rewind here, even if inf may be a pipe. We fail if the |
|
|
length of the first line is longer than the pipe block size, |
|
|
which is unlikely. */ |
|
|
rewind (inf); |
|
|
|
|
1695 |
/* Else try Fortran. */ |
/* Else try Fortran. */ |
1696 |
old_last_node = last_node; |
old_last_node = last_node; |
1697 |
curfdp->lang = get_language_from_langname ("fortran"); |
curfdp->lang = get_language_from_langname ("fortran"); |
1938 |
{ |
{ |
1939 |
if (np->left != NULL) |
if (np->left != NULL) |
1940 |
invalidate_nodes (badfdp, np->left); |
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. */ |
1944 |
if (np->fdp == badfdp) |
if (np->fdp == badfdp) |
1945 |
np-> valid = FALSE; |
np-> valid = FALSE; |
1946 |
if (np->right != NULL) |
if (np->right != NULL) |
5766 |
return (char *)r; |
return (char *)r; |
5767 |
} |
} |
5768 |
|
|
|
|
|
5769 |
/* |
/* |
5770 |
* Return the ptr in sp at which the character c first |
* Return the ptr in sp at which the character c first |
5771 |
* appears; NULL if not found |
* appears; NULL if not found |
5785 |
return NULL; |
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); |
5806 |
|
} |
5807 |
|
|
5808 |
/* Skip spaces, return new pointer. */ |
/* Skip spaces, return new pointer. */ |
5809 |
static char * |
static char * |
5810 |
skip_spaces (cp) |
skip_spaces (cp) |