summaryrefslogtreecommitdiff
path: root/libdb/db_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdb/db_lookup.c')
-rw-r--r--libdb/db_lookup.c104
1 files changed, 43 insertions, 61 deletions
diff --git a/libdb/db_lookup.c b/libdb/db_lookup.c
index db062597..b43269a6 100644
--- a/libdb/db_lookup.c
+++ b/libdb/db_lookup.c
@@ -51,6 +51,7 @@
#include "debug.h"
#include "fatal.h"
+#include "filenames.h"
#include "glcontainers.h"
#include "wordfnmatch.h"
#include "xregcomp.h"
@@ -143,27 +144,6 @@ datum make_multi_key (const char *page, const char *ext)
return key;
}
-/* Free allocated elements of a mandata structure, but not the structure
- * itself.
- */
-void free_mandata_elements (struct mandata *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 a mandata structure and its elements. */
-void free_mandata_struct (struct mandata *pinfo)
-{
- if (pinfo)
- free_mandata_elements (pinfo);
- free (pinfo);
-}
-
/* Get the key that should be used for a given name. The caller is
* responsible for freeing the return value.
*/
@@ -209,33 +189,43 @@ static char **split_data (MYDBM_FILE dbf, char *content, char *start[])
}
/* Parse the db-returned data and put it into a mandata format */
-void split_content (MYDBM_FILE dbf, char *cont_ptr, struct mandata *pinfo)
+struct mandata *split_content (MYDBM_FILE dbf, char *cont_ptr)
{
+ struct mandata *info;
char *start[FIELDS];
char **data;
data = split_data (dbf, cont_ptr, start);
- pinfo->name = copy_if_set (*(data++));
- pinfo->ext = *(data++);
- pinfo->sec = *(data++);
- pinfo->mtime.tv_sec = (time_t) atol (*(data++));
- pinfo->mtime.tv_nsec = atol (*(data++));
- pinfo->id = **(data++); /* single char id */
- pinfo->pointer = *(data++);
- pinfo->filter = *(data++);
- pinfo->comp = *(data++);
- pinfo->whatis = *(data);
-
- pinfo->addr = cont_ptr;
+ info = XZALLOC (struct mandata);
+ info->name = copy_if_set (*(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 = xstrdup (*(data++));
+ info->filter = xstrdup (*(data++));
+ info->comp = xstrdup (*(data++));
+ info->whatis = xstrdup (*(data));
+ return info;
}
-static bool name_ext_equals (const void *elt1, const void *elt2)
+bool ATTRIBUTE_PURE name_ext_equals (const void *elt1, const void *elt2)
{
const struct name_ext *ref1 = elt1, *ref2 = elt2;
return STREQ (ref1->name, ref2->name) && STREQ (ref1->ext, ref2->ext);
}
+int ATTRIBUTE_PURE name_ext_compare (const void *elt1, const void *elt2)
+{
+ const struct name_ext *ref1 = elt1, *ref2 = elt2;
+ int name_cmp = strcmp (ref1->name, ref2->name);
+ if (name_cmp)
+ return name_cmp;
+ return strcmp (ref1->ext, ref2->ext);
+}
+
/* Extract all of the names/extensions associated with this key. Each case
* variant of a name will be returned separately.
*
@@ -260,7 +250,7 @@ gl_list_t list_extensions (char *data)
/* Don't copy these; they will point into the given string. */
name_ext->name = name;
name_ext->ext = ext;
- gl_list_add_last (list, name_ext);
+ gl_sortedlist_add (list, name_ext_compare, name_ext);
}
debug ("found %zu names/extensions\n", gl_list_size (list));
@@ -303,8 +293,7 @@ static gl_list_t dblookup (MYDBM_FILE dbf, const char *page,
else if (*MYDBM_DPTR (cont) != '\t') { /* Just one entry */
bool matches = false;
- info = infoalloc ();
- split_content (dbf, MYDBM_DPTR (cont), info);
+ info = split_content (dbf, MYDBM_DPTR (cont));
if (!info->name)
info->name = xstrdup (page);
if (!(flags & MATCH_CASE) || STREQ (info->name, page)) {
@@ -370,16 +359,15 @@ static gl_list_t dblookup (MYDBM_FILE dbf, const char *page,
MYDBM_FREE_DPTR (key);
/* Allocate info struct and add it to the list. */
- info = infoalloc ();
- split_content (dbf, MYDBM_DPTR (multi_cont), info);
+ info = split_content (dbf, MYDBM_DPTR (multi_cont));
if (!info->name)
info->name = xstrdup (ref->name);
gl_list_add_last (infos, info);
}
gl_list_free (refs);
- MYDBM_FREE_DPTR (cont);
}
+ MYDBM_FREE_DPTR (cont);
return infos;
}
@@ -412,7 +400,6 @@ gl_list_t dblookup_pattern (MYDBM_FILE dbf, const char *pattern,
bool pattern_regex, bool try_descriptions)
{
gl_list_t infos;
- struct mandata *tail = NULL;
datum key, cont;
regex_t preg;
@@ -438,12 +425,10 @@ gl_list_t dblookup_pattern (MYDBM_FILE dbf, const char *pattern,
end = man_btree_nextkeydata (dbf, &key, &cont);
while (!end) {
#endif /* !BTREE */
- struct mandata info;
+ struct mandata *info = NULL;
char *tab;
bool got_match;
- memset (&info, 0, sizeof (info));
-
if (!MYDBM_DPTR (cont))
{
debug ("key was %s\n", MYDBM_DPTR (key));
@@ -466,45 +451,43 @@ gl_list_t dblookup_pattern (MYDBM_FILE dbf, const char *pattern,
/* a real page */
- split_content (dbf, MYDBM_DPTR (cont), &info);
+ info = split_content (dbf, MYDBM_DPTR (cont));
/* If there's a section given, does it match either the
* section or extension of this page?
*/
if (section &&
- (!STREQ (section, info.sec) && !STREQ (section, info.ext)))
+ (!STREQ (section, info->sec) &&
+ !STREQ (section, info->ext)))
goto nextpage;
tab = strrchr (MYDBM_DPTR (key), '\t');
if (tab)
*tab = '\0';
- if (!info.name)
- info.name = xstrdup (MYDBM_DPTR (key));
+ if (!info->name)
+ info->name = xstrdup (MYDBM_DPTR (key));
if (pattern_regex)
- got_match = (regexec (&preg, info.name,
+ got_match = (regexec (&preg, info->name,
0, NULL, 0) == 0);
else
- got_match = fnmatch (pattern, info.name,
+ got_match = fnmatch (pattern, info->name,
match_case ? 0
: FNM_CASEFOLD) == 0;
- if (try_descriptions && !got_match && info.whatis) {
+ if (try_descriptions && !got_match && info->whatis) {
if (pattern_regex)
- got_match = (regexec (&preg, info.whatis,
+ got_match = (regexec (&preg, info->whatis,
0, NULL, 0) == 0);
else
got_match = word_fnmatch (pattern,
- info.whatis);
+ info->whatis);
}
if (!got_match)
goto nextpage_tab;
- tail = infoalloc ();
- memcpy (tail, &info, sizeof (info));
- info.name = NULL; /* steal memory */
- MYDBM_SET_DPTR (cont, NULL); /* == info.addr */
- gl_list_add_last (infos, tail);
+ gl_list_add_last (infos, info);
+ info = NULL; /* avoid freeing later */
nextpage_tab:
if (tab)
@@ -520,8 +503,7 @@ nextpage:
MYDBM_FREE_DPTR (key);
end = man_btree_nextkeydata (dbf, &key, &cont);
#endif /* !BTREE */
- info.addr = NULL;
- free_mandata_elements (&info);
+ free_mandata_struct (info);
}
if (pattern_regex)