diff options
Diffstat (limited to 'libdb/db_lookup.c')
-rw-r--r-- | libdb/db_lookup.c | 104 |
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) |