From 8378bcd3611c9b86446e52b38ed4c1cc7857b963 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Francesco=20Potort=C3=AC?= Date: Mon, 22 Apr 2002 14:12:08 +0000 Subject: [PATCH] (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. --- lib-src/ChangeLog | 12 +++++ lib-src/etags.c | 123 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 99 insertions(+), 36 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 863f53ce747..747df2521cc 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,15 @@ +2002-04-22 Francesco Potorti` + + * etags.c: (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. + 2002-04-21 Gerd Moellmann * ebrowse.c (add_declarator): Test *CLS instead of CLS. diff --git a/lib-src/etags.c b/lib-src/etags.c index 67dc1c651d6..0ba1ccf861f 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. */ * Francesco Potortì 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 initbuffer __P((linebuffer *)); 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 char *dbp; /* pointer to start of current tag */ 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 @@ process_file (file, lang) 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 @@ init () * 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 @@ find_entries (inf) 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 */ @@ -1849,6 +1867,22 @@ free_tree (np) } } +/* + * 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 @@ -1873,16 +1907,16 @@ add_node (np, cur_node_p) } 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 @@ add_node (np, cur_node_p) /* 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 @@ add_node (np, cur_node_p) /* 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 @@ xrealloc (ptr, size) * 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: */ -- 2.39.2