summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2007-03-20 03:02:26 +0000
committerPaul Smith <psmith@gnu.org>2007-03-20 03:02:26 +0000
commit6ccf33cdbdfda2aea5d51e4d4991881c74d853d1 (patch)
treece963770c6d0dc0428a6bce65d96da4b710e2831 /dir.c
parente4da30858037b431880263676e8f90b1f8412a38 (diff)
downloadgunmake-6ccf33cdbdfda2aea5d51e4d4991881c74d853d1.tar.gz
This is a major update, which switches virtually every allocated-but-not-freed
string into the strcache. As a side-effect, many more structure members and function arguments can/should be declared const. As mentioned in the changelog, unfortunately measurement shows that this change does not yet reduce memory. The problem is with secondary expansion: because of this we store all the prerequisites in the string cache twice. First we store the prerequisite string after initial expansion but before secondary expansion, then we store each individual file after secondary expansion and expand_deps(). I plan to change expand_deps() to be callable in either context (eval or snap_deps) then have non-second-expansion targets call expand_deps() during eval, so that we only need to store that dependency list once.
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/dir.c b/dir.c
index 12e0382..de4debc 100644
--- a/dir.c
+++ b/dir.c
@@ -1124,29 +1124,28 @@ open_dirstream (const char *directory)
static struct dirent *
read_dirstream (__ptr_t stream)
{
+ static char *buf;
+ static unsigned int bufsz;
+
struct dirstream *const ds = (struct dirstream *) stream;
struct directory_contents *dc = ds->contents;
struct dirfile **dirfile_end = (struct dirfile **) dc->dirfiles.ht_vec + dc->dirfiles.ht_size;
- static char *buf;
- static unsigned int bufsz;
while (ds->dirfile_slot < dirfile_end)
{
- register struct dirfile *df = *ds->dirfile_slot++;
+ struct dirfile *df = *ds->dirfile_slot++;
if (! HASH_VACANT (df) && !df->impossible)
{
- /* The glob interface wants a `struct dirent',
- so mock one up. */
+ /* The glob interface wants a `struct dirent', so mock one up. */
struct dirent *d;
unsigned int len = df->length + 1;
- if (sizeof *d - sizeof d->d_name + len > bufsz)
+ unsigned int sz = sizeof (*d) - sizeof (d->d_name) + len;
+ if (sz > bufsz)
{
- if (buf != 0)
- free (buf);
bufsz *= 2;
- if (sizeof *d - sizeof d->d_name + len > bufsz)
- bufsz = sizeof *d - sizeof d->d_name + len;
- buf = xmalloc (bufsz);
+ if (sz > bufsz)
+ bufsz = sz;
+ buf = xrealloc (buf, bufsz);
}
d = (struct dirent *) buf;
#ifdef __MINGW32__
@@ -1200,7 +1199,6 @@ local_stat (const char *path, struct stat *buf)
void
dir_setup_glob (glob_t *gl)
{
- /* Bogus sunos4 compiler complains (!) about & before functions. */
gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream;
gl->gl_closedir = ansi_free;