summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2022-09-24 14:46:47 +0100
committerColin Watson <cjwatson@debian.org>2022-09-24 14:46:48 +0100
commitb1615c44fe20c205be2b5ba5cd95e0cc8510d766 (patch)
tree4b654b3ddea1c6e4da999597e4fc40138fd3876e
parent26b957306113c1cf47133268a938f32c31722ab3 (diff)
Simplify struct mandata memory allocation
The arrangement where most of the fields of `struct mandata` were constant pointers into the `addr` field was a bit more memory-efficient, but it made some kinds of analysis and reorganization very difficult, and we don't actually need to be quite that frugal about memory. Reorganize this to allocate each field independently instead. * lib/filenames.c (filename_info): Allocate each field independently. Use Gnulib's `base_name` and `dir_name` functions to parse paths. Stop setting `info->addr`. (free_mandata_struct): Free the `ext`, `sec`, `pointer`, `comp`, `filter`, and `whatis` fields. Stop freeing `addr`. * lib/filenames.h (struct mandata): Remove `addr`. Make `ext`, `sec`, `pointer`, `comp`, `filter`, and `whatis` non-`const`. * libdb/db_lookup.c (split_content): Copy the `ext`, `sec`, `pointer`, `filter`, `comp`, and `whatis` fields. Stop setting `addr`. * libdb/db_store.c (make_content): Copy the `pointer`, `comp`, `filter`, and `whatis` fields. * src/descriptions_store.c (store_descriptions): Copy `pointer` and `whatis` fields. * src/straycats.c (check_for_stray): Copy `comp`, `ext`, `sec`, and `filter` fields. * libdb/db_lookup.c (dblookup): Always free `cont`'s data pointer, since it's no longer sometimes borrowed. * libdb/db_store.c (dbstore): Free `cont`'s and `oldcont`'s data pointers, since they're no longer borrowed. * src/check_mandirs.c (purge_missing): Free `content`'s data pointer, since it's no longer borrowed. * libdb/db_lookup.c (dblookup_pattern): Stop freeing `info->addr`. * src/catman.c (parse_for_sec): Stop freeing `entry->addr`. * src/whatis.c (do_apropos): Stop freeing `info->addr`.
-rw-r--r--lib/filenames.c44
-rw-r--r--lib/filenames.h34
-rw-r--r--libdb/db_lookup.c18
-rw-r--r--libdb/db_store.c16
-rw-r--r--src/catman.c2
-rw-r--r--src/check_mandirs.c1
-rw-r--r--src/descriptions_store.c16
-rw-r--r--src/straycats.c11
-rw-r--r--src/whatis.c3
9 files changed, 76 insertions, 69 deletions
diff --git a/lib/filenames.c b/lib/filenames.c
index 85665632..026d942a 100644
--- a/lib/filenames.c
+++ b/lib/filenames.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
+#include "dirname.h"
#include "error.h"
#include "xalloc.h"
#include "xvasprintf.h"
@@ -86,64 +87,64 @@ char *make_filename (const char *path, const char *name,
struct mandata *filename_info (const char *file, bool warn_if_bogus)
{
struct mandata *info;
- char *slash, *base_name;
+ char *basename, *dirname;
struct compression *comp;
info = XZALLOC (struct mandata);
- info->addr = xstrdup (file);
- slash = strrchr (info->addr, '/');
- if (slash) {
- *slash = '\0'; /* strip '/base_name' */
- base_name = slash + 1;
- } else
- base_name = info->addr;
+ basename = base_name (file);
/* Bogus files either have (i) no period, ie no extension, (ii)
a compression extension, but no sectional extension, (iii)
a missmatch between the section they are under and the
sectional part of their extension. */
- comp = comp_info (base_name, 1);
+ comp = comp_info (basename, 1);
if (comp) {
- info->comp = comp->ext;
- *(base_name + strlen (comp->stem)) = '\0';
+ info->comp = xstrdup (comp->ext);
+ *(basename + strlen (comp->stem)) = '\0';
free (comp->stem);
} else
info->comp = NULL;
{
- char *ext = strrchr (base_name, '.');
+ char *ext = strrchr (basename, '.');
if (!ext) {
/* no section extension */
if (warn_if_bogus)
gripe_bogus_manpage (file);
+ free (basename);
free_mandata_struct (info);
return NULL;
}
*ext++ = '\0'; /* set section ext */
- info->ext = ext;
+ info->ext = xstrdup (ext);
if (!*info->ext) {
/* zero-length section extension */
if (warn_if_bogus)
gripe_bogus_manpage (file);
+ free (basename);
free_mandata_struct (info);
return NULL;
}
}
- info->sec = strrchr (info->addr, '/') + 4; /* set section name */
+ /* Set section name. */
+ dirname = dir_name (file);
+ info->sec = xstrdup (strrchr (dirname, '/') + 4);
+ free (dirname);
if (strlen (info->sec) >= 1 && strlen (info->ext) >= 1 &&
info->sec[0] != info->ext[0]) {
/* mismatch in section */
if (warn_if_bogus)
gripe_bogus_manpage (file);
+ free (basename);
free_mandata_struct (info);
return NULL;
}
- info->name = xstrdup (base_name);
+ info->name = xstrdup (basename);
return info;
}
@@ -152,12 +153,13 @@ struct mandata *filename_info (const char *file, bool warn_if_bogus)
void free_mandata_struct (struct mandata *pinfo)
{
if (pinfo) {
- if (pinfo->addr)
- /* TODO: this memory appears to be properly owned by
- * the caller; why do we free it here?
- */
- free (pinfo->addr); /* free the 'content' */
- free (pinfo->name); /* free the real name */
+ free (pinfo->name);
+ free (pinfo->ext);
+ free (pinfo->sec);
+ free (pinfo->pointer);
+ free (pinfo->comp);
+ free (pinfo->filter);
+ free (pinfo->whatis);
}
free (pinfo);
}
diff --git a/lib/filenames.h b/lib/filenames.h
index 70980a63..66bc48aa 100644
--- a/lib/filenames.h
+++ b/lib/filenames.h
@@ -28,22 +28,24 @@
#include "timespec.h"
struct mandata {
- char *addr; /* ptr to memory containing the fields */
-
- char *name; /* Name of page, if != key */
-
- /* The following are all const because they should be pointers to
- * parts of strings allocated elsewhere (often the addr field above)
- * and should not be written through or freed themselves.
- */
- const char *ext; /* Filename ext w/o comp ext */
- const char *sec; /* Section name/number */
- char id; /* id for this entry */
- const char *pointer; /* id related file pointer */
- const char *comp; /* Compression extension */
- const char *filter; /* filters needed for the page */
- const char *whatis; /* whatis description for page */
- struct timespec mtime; /* mod time for file */
+ /* Name of page, if not equal to the key. */
+ char *name;
+ /* Filename extension without compression extension. */
+ char *ext;
+ /* Section name/number. */
+ char *sec;
+ /* ID (i.e. type) of this entry. */
+ char id;
+ /* ID-related file pointer. */
+ char *pointer;
+ /* Compression extension. */
+ char *comp;
+ /* Filters needed for the page. */
+ char *filter;
+ /* Whatis description for the page. */
+ char *whatis;
+ /* Modification time for file. */
+ struct timespec mtime;
};
extern char *make_filename (const char *path, const char *name,
diff --git a/libdb/db_lookup.c b/libdb/db_lookup.c
index 2cacdb73..b43269a6 100644
--- a/libdb/db_lookup.c
+++ b/libdb/db_lookup.c
@@ -199,17 +199,15 @@ struct mandata *split_content (MYDBM_FILE dbf, char *cont_ptr)
info = XZALLOC (struct mandata);
info->name = copy_if_set (*(data++));
- info->ext = *(data++);
- info->sec = *(data++);
+ info->ext = xstrdup (*(data++));
+ info->sec = xstrdup (*(data++));
info->mtime.tv_sec = (time_t) atol (*(data++));
info->mtime.tv_nsec = atol (*(data++));
info->id = **(data++); /* single char id */
- info->pointer = *(data++);
- info->filter = *(data++);
- info->comp = *(data++);
- info->whatis = *(data);
-
- info->addr = cont_ptr;
+ info->pointer = xstrdup (*(data++));
+ info->filter = xstrdup (*(data++));
+ info->comp = xstrdup (*(data++));
+ info->whatis = xstrdup (*(data));
return info;
}
@@ -368,8 +366,8 @@ static gl_list_t dblookup (MYDBM_FILE dbf, const char *page,
}
gl_list_free (refs);
- MYDBM_FREE_DPTR (cont);
}
+ MYDBM_FREE_DPTR (cont);
return infos;
}
@@ -505,8 +503,6 @@ nextpage:
MYDBM_FREE_DPTR (key);
end = man_btree_nextkeydata (dbf, &key, &cont);
#endif /* !BTREE */
- if (info)
- info->addr = NULL;
free_mandata_struct (info);
}
diff --git a/libdb/db_store.c b/libdb/db_store.c
index 92926dc7..eae5c271 100644
--- a/libdb/db_store.c
+++ b/libdb/db_store.c
@@ -135,13 +135,13 @@ static datum make_content (struct mandata *in)
memset (&cont, 0, sizeof cont);
if (!in->pointer)
- in->pointer = dash;
- if (!in->filter)
- in->filter = dash;
+ in->pointer = xstrdup (dash);
if (!in->comp)
- in->comp = dash;
+ in->comp = xstrdup (dash);
+ if (!in->filter)
+ in->filter = xstrdup (dash);
if (!in->whatis)
- in->whatis = dash + 1;
+ in->whatis = xstrdup (dash + 1);
value = xasprintf (
"%s\t%s\t%s\t%ld\t%ld\t%c\t%s\t%s\t%s\t%s",
@@ -278,7 +278,7 @@ int dbstore (MYDBM_FILE dbf, struct mandata *in, const char *base)
info = split_content (dbf, MYDBM_DPTR (cont));
ret = replace_if_necessary (dbf, in, info,
newkey, newcont);
- /* MYDBM_FREE_DPTR (cont); */
+ MYDBM_FREE_DPTR (cont);
free_mandata_struct (info);
MYDBM_FREE_DPTR (newkey);
MYDBM_FREE_DPTR (newcont);
@@ -348,7 +348,7 @@ int dbstore (MYDBM_FILE dbf, struct mandata *in, const char *base)
newcont = make_content (in);
ret = replace_if_necessary (dbf, in, old,
oldkey, newcont);
- /* MYDBM_FREE_DPTR (oldcont); */
+ MYDBM_FREE_DPTR (oldcont);
free_mandata_struct (old);
MYDBM_FREE_DPTR (newcont);
MYDBM_FREE_DPTR (lastkey);
@@ -412,7 +412,7 @@ int dbstore (MYDBM_FILE dbf, struct mandata *in, const char *base)
if (MYDBM_REPLACE (dbf, oldkey, newcont))
gripe_replace_key (dbf, MYDBM_DPTR (oldkey));
- /* MYDBM_FREE_DPTR (oldcont); */
+ MYDBM_FREE_DPTR (oldcont);
free_mandata_struct (old);
MYDBM_FREE_DPTR (newcont);
free (old_name);
diff --git a/src/catman.c b/src/catman.c
index a35bd61c..100cf9aa 100644
--- a/src/catman.c
+++ b/src/catman.c
@@ -318,8 +318,6 @@ static int parse_for_sec (MYDBM_FILE dbf,
}
}
- /* == MYDBM_DPTR (content), freed below */
- entry->addr = NULL;
free_mandata_struct (entry);
}
diff --git a/src/check_mandirs.c b/src/check_mandirs.c
index 0c3b534c..855898f5 100644
--- a/src/check_mandirs.c
+++ b/src/check_mandirs.c
@@ -1053,6 +1053,7 @@ int purge_missing (MYDBM_FILE dbf, const char *manpath, const char *catpath)
free (nicekey);
free_mandata_struct (entry);
+ MYDBM_FREE_DPTR (content);
nextkey = MYDBM_NEXTKEY (dbf, key);
MYDBM_FREE_DPTR (key);
key = nextkey;
diff --git a/src/descriptions_store.c b/src/descriptions_store.c
index 73d8938d..69e2cd37 100644
--- a/src/descriptions_store.c
+++ b/src/descriptions_store.c
@@ -94,8 +94,13 @@ void store_descriptions (MYDBM_FILE dbf, gl_list_t descs, struct mandata *info,
if (STREQ (base, desc->name)) {
info->id = save_id;
+ free (info->pointer);
info->pointer = NULL;
- info->whatis = desc->whatis;
+ free (info->whatis);
+ if (desc->whatis)
+ info->whatis = xstrdup (desc->whatis);
+ else
+ info->whatis = NULL;
info->mtime = save_mtime;
found_real_page = true;
} else if (trace) {
@@ -122,8 +127,13 @@ void store_descriptions (MYDBM_FILE dbf, gl_list_t descs, struct mandata *info,
info->id = ULT_MAN;
else
info->id = save_id;
+ free (info->pointer);
info->pointer = NULL;
- info->whatis = desc->whatis;
+ free (info->whatis);
+ if (desc->whatis)
+ info->whatis = xstrdup (desc->whatis);
+ else
+ info->whatis = NULL;
if (lstat (trace_name, &st) == 0)
info->mtime = get_stat_mtime (&st);
else
@@ -146,10 +156,12 @@ next_trace:
info->id = WHATIS_MAN;
else
info->id = WHATIS_CAT;
+ free (info->pointer);
info->pointer = xstrdup (base);
/* Don't waste space storing the whatis in the db
* more than once.
*/
+ free (info->whatis);
info->whatis = NULL;
info->mtime = save_mtime;
}
diff --git a/src/straycats.c b/src/straycats.c
index e0bf871b..e4c7c2a7 100644
--- a/src/straycats.c
+++ b/src/straycats.c
@@ -134,9 +134,8 @@ static int check_for_stray (MYDBM_FILE dbf)
goto next;
} else if (comp_info (ext, 0)) {
*ext = '\0';
- info->comp = ext + 1;
- } else
- info->comp = NULL;
+ info->comp = xstrdup (ext + 1);
+ }
ext = strrchr (mandir, '.');
*(mandir + lenman - 1) = '\0';
@@ -184,7 +183,7 @@ static int check_for_stray (MYDBM_FILE dbf)
lg.whatis = 0;
*(ext++) = '\0';
- info->ext = ext;
+ info->ext = xstrdup (ext);
/* see if we already have it, before going any
further */
@@ -198,9 +197,9 @@ static int check_for_stray (MYDBM_FILE dbf)
mandir_base, info->ext);
/* fill in the missing parts of the structure */
- info->sec = section;
+ info->sec = xstrdup (section);
info->id = STRAY_CAT;
- info->filter = "-";
+ info->filter = xstrdup ("-");
info->mtime.tv_sec = 0;
info->mtime.tv_nsec = 0;
diff --git a/src/whatis.c b/src/whatis.c
index e3f934b7..639f1c89 100644
--- a/src/whatis.c
+++ b/src/whatis.c
@@ -777,9 +777,6 @@ nextpage:
end = man_btree_nextkeydata (dbf, &key, &cont);
#endif /* !BTREE */
#pragma GCC diagnostic pop
- if (info)
- /* == MYDBM_DPTR (cont), freed above */
- info->addr = NULL;
free_mandata_struct (info);
}