Mercurial > emacs
changeset 44735:98b894d1d3ad
(last_node): Make it a global variable.
(process_file): Print the tags from the nodes as soon as
possible, and delete the nodes. This brings down the memory
occupancy as etags to almost the same level as when the #line
directives were not parsed.
(free_fdesc): New function.
(find_entries): Use it.
(invalidate_nodes): In etags mode, do not just mark the nodes as
invalid, do delete them.
author | Francesco Potortì <pot@gnu.org> |
---|---|
date | Mon, 22 Apr 2002 14:11:26 +0000 |
parents | 712ef4d4683e |
children | 2ae99744dc81 |
files | lib-src/etags.c |
diffstat | 1 files changed, 87 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/etags.c Mon Apr 22 07:58:15 2002 +0000 +++ b/lib-src/etags.c Mon Apr 22 14:11:26 2002 +0000 @@ -33,7 +33,7 @@ * Francesco Potort́ <pot@gnu.org> has maintained it since 1993. */ -char pot_etags_version[] = "@(#) pot revision number is 15.15"; +char pot_etags_version[] = "@(#) pot revision number is 15.16"; #define TRUE 1 #define FALSE 0 @@ -368,9 +368,10 @@ static void process_file __P((char *, language *)); static void find_entries __P((FILE *)); static void free_tree __P((node *)); +static void free_fdesc __P((fdesc *)); static void pfnote __P((char *, bool, char *, int, int, long)); static void new_pfnote __P((char *, int, bool, char *, int, int, long)); -static void invalidate_nodes __P((fdesc *, node *)); +static void invalidate_nodes __P((fdesc *, node **)); static void put_entries __P((node *)); static char *concat __P((char *, char *, char *)); @@ -410,6 +411,7 @@ static const int invalidcharno = -1; static node *nodehead; /* the head of the binary tree of tags */ +static node *last_node; /* the last node created */ static linebuffer lb; /* the current line */ @@ -1531,19 +1533,44 @@ pfatal (file); /* If not Ctags, and if this is not metasource and if it contained no #line - directives, we can write the tags and free curfdp an all nodes pointing to - it. */ + directives, we can write the tags and free all nodes pointing to + curfdp. */ if (!CTAGS - && curfdp == fdhead /* no #line directives in this file */ + && curfdp->usecharno /* no #line directives in this file */ && !curfdp->lang->metasource) { - /* Write tags for file curfdp->taggedfname. */ - ; + node *np, *prev; + + /* Look for the head of the sublist relative to this file. See add_node + for the structure of the node tree. */ + prev = NULL; + for (np = nodehead; np != NULL; prev = np, np = np->left) + if (np->fdp == curfdp) + break; + + /* If we generated tags for this file, write and delete them. */ + if (np != NULL) + { + /* This is the head of the last sublist, if any. The following + instructions depend on this being true. */ + assert (np->left == NULL); + + assert (fdhead == curfdp); + assert (last_node->fdp == curfdp); + put_entries (np); /* write tags for file curfdp->taggedfname */ + free_tree (np); /* remove the written nodes */ + if (prev == NULL) + nodehead = NULL; /* no nodes left */ + else + prev->left = NULL; /* delete the pointer to the sublist */ + } } cleanup: if (compressed_name) free (compressed_name); if (uncompressed_name) free (uncompressed_name); + last_node = NULL; + curfdp = NULL; return; } @@ -1578,8 +1605,6 @@ * 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 (inf) FILE *inf; @@ -1677,17 +1702,10 @@ badfdp->taggedfname, badfdp->infname); /* Delete the tags referring to badfdp. */ - invalidate_nodes (badfdp, nodehead); + invalidate_nodes (badfdp, &nodehead); *fdpp = badfdp->next; /* remove the bad description from the list */ - - /* Delete badfdp. */ - if (badfdp->infname != NULL) free (badfdp->infname); - if (badfdp->infabsname != NULL) free (badfdp->infabsname); - if (badfdp->infabsdir != NULL) free (badfdp->infabsdir); - if (badfdp->taggedfname != NULL) free (badfdp->taggedfname); - if (badfdp->prop != NULL) free (badfdp->prop); - free (badfdp); + free_fdesc (badfdp); } else fdpp = &(*fdpp)->next; /* advance the list pointer */ @@ -1850,6 +1868,22 @@ } /* + * free_fdesc () + * delete a file description + */ +static void +free_fdesc (fdp) + register fdesc *fdp; +{ + if (fdp->infname != NULL) free (fdp->infname); + if (fdp->infabsname != NULL) free (fdp->infabsname); + if (fdp->infabsdir != NULL) free (fdp->infabsdir); + if (fdp->taggedfname != NULL) free (fdp->taggedfname); + if (fdp->prop != NULL) free (fdp->prop); + free (fdp); +} + +/* * 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 @@ -1873,16 +1907,16 @@ } if (!CTAGS) + /* Etags Mode */ { - /* 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->fdp == np->fdp) + if (last_node != NULL && last_node->fdp == np->fdp) { /* Let's use the same sublist as the last added node. */ + assert (last_node->right == NULL); last_node->right = np; last_node = np; } @@ -1896,7 +1930,8 @@ /* The head of this sublist is not good for us. Let's try the next one. */ add_node (np, &cur_node->left); - } + } /* if ETAGS mode */ + else { /* Ctags Mode */ @@ -1930,28 +1965,44 @@ /* Actually add the node */ add_node (np, dif < 0 ? &cur_node->left : &cur_node->right); - } + } /* if CTAGS mode */ } /* * invalidate_nodes () * Scan the node tree and invalidate all nodes pointing to the - * given file description. + * given file description (CTAGS case) or free them (ETAGS case). */ static void -invalidate_nodes (badfdp, np) +invalidate_nodes (badfdp, npp) fdesc *badfdp; - node *np; + node **npp; { - if (np->left != NULL) - invalidate_nodes (badfdp, np->left); - /* Memory leak here: if not CTAGS, in which case it would be quite - difficult, the node could be freed. If CTAGS the node is part of a - binary tree, if not it is part of a list of lists. */ - if (np->fdp == badfdp) - np-> valid = FALSE; - if (np->right != NULL) - invalidate_nodes (badfdp, np->right); + node *np = *npp; + + if (np == NULL) + return; + + if (CTAGS) + { + if (np->left != NULL) + invalidate_nodes (badfdp, &np->left); + if (np->fdp == badfdp) + np-> valid = FALSE; + if (np->right != NULL) + invalidate_nodes (badfdp, &np->right); + } + else + { + node **next = &np->left; + if (np->fdp == badfdp) + { + *npp = *next; /* detach the sublist from the list */ + np->left = NULL; /* isolate it */ + free_tree (np); /* free it */ + } + invalidate_nodes (badfdp, next); + } } @@ -6138,6 +6189,6 @@ * indent-tabs-mode: t * tab-width: 8 * fill-column: 79 - * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc") + * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc" "node") * End: */