summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in5
-rw-r--r--src/accessdb.c3
-rw-r--r--src/catman.c31
-rw-r--r--src/check_mandirs.c160
-rw-r--r--src/descriptions.c75
-rw-r--r--src/descriptions.h15
-rw-r--r--src/descriptions_store.c46
-rw-r--r--src/globbing.c166
-rw-r--r--src/globbing.h8
-rw-r--r--src/globbing_test.c29
-rw-r--r--src/lexgrog_test.c41
-rw-r--r--src/man.c558
-rw-r--r--src/manconv_main.c5
-rw-r--r--src/mandb.c111
-rw-r--r--src/manp.c632
-rw-r--r--src/manp.h14
-rw-r--r--src/manpath.c11
-rw-r--r--src/straycats.c57
-rw-r--r--src/tests/Makefile.in5
-rw-r--r--src/ult_src.c52
-rw-r--r--src/ult_src.h20
-rw-r--r--src/whatis.c234
-rw-r--r--src/zsoelim.c129
-rw-r--r--src/zsoelim.h8
-rw-r--r--src/zsoelim.l67
-rw-r--r--src/zsoelim_main.c9
26 files changed, 1192 insertions, 1299 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index c2f4385a..413cae19 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -103,6 +103,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/m4/man-arg-db.m4 \
$(top_srcdir)/m4/man-arg-device.m4 \
$(top_srcdir)/m4/man-arg-mandirs.m4 \
+ $(top_srcdir)/m4/man-arg-manual.m4 \
$(top_srcdir)/m4/man-arg-override-dir.m4 \
$(top_srcdir)/m4/man-arg-sections.m4 \
$(top_srcdir)/m4/man-arg-setuid.m4 \
@@ -125,7 +126,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/gl/m4/btowc.m4 \
$(top_srcdir)/gl/m4/builtin-expect.m4 \
$(top_srcdir)/gl/m4/canonicalize.m4 \
- $(top_srcdir)/gl/m4/chdir-long.m4 \
+ $(top_srcdir)/gl/m4/chdir-long.m4 $(top_srcdir)/gl/m4/chown.m4 \
$(top_srcdir)/gl/m4/clock_time.m4 $(top_srcdir)/gl/m4/close.m4 \
$(top_srcdir)/gl/m4/closedir.m4 $(top_srcdir)/gl/m4/codeset.m4 \
$(top_srcdir)/gl/m4/d-ino.m4 $(top_srcdir)/gl/m4/d-type.m4 \
@@ -169,7 +170,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/gl/m4/intmax_t.m4 \
$(top_srcdir)/gl/m4/inttypes_h.m4 $(top_srcdir)/gl/m4/ioctl.m4 \
$(top_srcdir)/gl/m4/langinfo_h.m4 \
- $(top_srcdir)/gl/m4/largefile.m4 \
+ $(top_srcdir)/gl/m4/largefile.m4 $(top_srcdir)/gl/m4/lchown.m4 \
$(top_srcdir)/gl/m4/lib-ignore.m4 \
$(top_srcdir)/gl/m4/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
$(top_srcdir)/gl/m4/lib-prefix.m4 \
diff --git a/src/accessdb.c b/src/accessdb.c
index 21f18cb8..ff3fef5e 100644
--- a/src/accessdb.c
+++ b/src/accessdb.c
@@ -27,6 +27,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -70,7 +71,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'h':
argp_state_help (state, state->out_stream,
diff --git a/src/catman.c b/src/catman.c
index 489b33ca..c58ef6c0 100644
--- a/src/catman.c
+++ b/src/catman.c
@@ -31,6 +31,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
@@ -61,6 +62,7 @@
#endif /* !ARG_MAX */
#include "argp.h"
+#include "gl_list.h"
#include "progname.h"
#include "gettext.h"
@@ -72,6 +74,7 @@
#include "cleanup.h"
#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "sandbox.h"
@@ -110,7 +113,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'M':
manp = arg;
@@ -164,7 +167,7 @@ static struct argp argp = { options, parse_opt, args_doc };
static char *locale;
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
static void post_fork (void)
{
@@ -353,7 +356,7 @@ static int check_access (const char *directory)
int main (int argc, char *argv[])
{
char *sys_manp;
- char **mp;
+ char *mp;
const char **sp;
set_program_name (argv[0]);
@@ -388,14 +391,14 @@ int main (int argc, char *argv[])
debug ("manpath=%s\n", manp);
- /* get the manpath as an array of pointers */
- create_pathlist (manp, manpathlist);
-
- for (mp = manpathlist; *mp; mp++) {
+ /* get the manpath as a list of pointers */
+ manpathlist = create_pathlist (manp);
+
+ GL_LIST_FOREACH_START (manpathlist, mp) {
char *catpath;
size_t len;
- catpath = get_catpath (*mp, SYSTEM_CAT | USER_CAT);
+ catpath = get_catpath (mp, SYSTEM_CAT | USER_CAT);
if (catpath) {
if (is_directory (catpath) != 1) {
@@ -404,10 +407,10 @@ int main (int argc, char *argv[])
}
database = mkdbname (catpath);
} else {
- if (is_directory (*mp) != 1)
+ if (is_directory (mp) != 1)
continue;
- database = mkdbname (*mp);
- catpath = xstrdup (*mp);
+ database = mkdbname (mp);
+ catpath = xstrdup (mp);
}
len = strlen (catpath);
@@ -419,14 +422,14 @@ int main (int argc, char *argv[])
continue;
if (check_access (catpath))
continue;
- if (parse_for_sec (*mp, *sp)) {
- error (0, 0, _("unable to update %s"), *mp);
+ if (parse_for_sec (mp, *sp)) {
+ error (0, 0, _("unable to update %s"), mp);
break;
}
}
free (catpath);
- }
+ } GL_LIST_FOREACH_END (manpathlist);
free_pathlist (manpathlist);
free (locale);
diff --git a/src/check_mandirs.c b/src/check_mandirs.c
index c8c33dce..5aba37cb 100644
--- a/src/check_mandirs.c
+++ b/src/check_mandirs.c
@@ -31,6 +31,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -43,6 +44,10 @@
#include <unistd.h>
#include "dirname.h"
+#include "gl_array_list.h"
+#include "gl_hash_map.h"
+#include "gl_xlist.h"
+#include "gl_xmap.h"
#include "stat-time.h"
#include "timespec.h"
#include "xvasprintf.h"
@@ -53,10 +58,9 @@
#include "manconfig.h"
#include "error.h"
-#include "hashtable.h"
+#include "glcontainers.h"
#include "orderfiles.h"
#include "security.h"
-#include "xchown.h"
#include "mydbm.h"
#include "db_storage.h"
@@ -68,24 +72,24 @@
#include "ult_src.h"
#include "check_mandirs.h"
-int opt_test; /* don't update db */
+bool opt_test; /* don't update db */
int pages;
-int force_rescan = 0;
+bool force_rescan = false;
-static struct hashtable *whatis_hash = NULL;
+gl_map_t whatis_map = NULL;
-struct whatis_hashent {
+struct whatis {
char *whatis;
- struct ult_trace trace;
+ gl_list_t trace;
};
-static void whatis_hashtable_free (void *defn)
+static void whatis_free (const void *value)
{
- struct whatis_hashent *hashent = defn;
+ struct whatis *whatis = (struct whatis *) value;
- free (hashent->whatis);
- free_ult_trace (&hashent->trace);
- free (hashent);
+ free (whatis->whatis);
+ gl_list_free (whatis->trace);
+ free (whatis);
}
static void gripe_multi_extensions (const char *path, const char *sec,
@@ -127,12 +131,11 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
struct mandata info, *exists;
struct stat buf;
size_t len;
- struct ult_trace ult_trace;
- struct whatis_hashent *whatis;
+ gl_list_t ult_trace = NULL;
+ const struct whatis *whatis;
memset (&lg, 0, sizeof (struct lexgrog));
memset (&info, 0, sizeof (struct mandata));
- memset (&ult_trace, 0, sizeof (struct ult_trace));
manpage = filename_info (file, &info, NULL);
if (!manpage)
@@ -158,7 +161,7 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
* save both an ult_src() and a find_name(), amongst other wastes of
* time.
*/
- exists = dblookup_exact (dbf, manpage_base, info.ext, 1);
+ exists = dblookup_exact (dbf, manpage_base, info.ext, true);
/* Ensure we really have the actual page. Gzip keeps the mtime the
* same when it compresses, so we have to compare compression
@@ -202,8 +205,8 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
*/
{
/* Avoid too much noise in debug output */
- int save_debug = debug_level;
- debug_level = 0;
+ bool save_debug = debug_level;
+ debug_level = false;
ult = ult_src (file, path, &buf, SOFT_LINK | HARD_LINK, NULL);
debug_level = save_debug;
}
@@ -215,10 +218,10 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
return;
}
- if (!whatis_hash)
- whatis_hash = hashtable_create (&whatis_hashtable_free);
+ if (!whatis_map)
+ whatis_map = new_string_map (GL_HASH_MAP, whatis_free);
- whatis = hashtable_lookup (whatis_hash, ult, strlen (ult));
+ whatis = gl_map_get (whatis_map, ult);
if (!whatis) {
if (!STRNEQ (ult, file, len))
debug ("\ntest_manfile(): link not in cache:\n"
@@ -228,8 +231,9 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
* looking for whatis info in files containing only '.so
* manx/foo.x', which will give us an unobtainable whatis
* for the entry. */
+ ult_trace = new_string_list (GL_ARRAY_LIST, true);
ult = ult_src (file, path, &buf,
- SO_LINK | SOFT_LINK | HARD_LINK, &ult_trace);
+ SO_LINK | SOFT_LINK | HARD_LINK, ult_trace);
}
if (!ult) {
@@ -261,6 +265,7 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
else {
/* Cache miss; go and get the whatis info in its raw state. */
char *file_base = base_name (file);
+ struct whatis *new_whatis;
lg.type = MANPAGE;
drop_effective_privs ();
@@ -268,11 +273,12 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
free (file_base);
regain_effective_privs ();
- whatis = XMALLOC (struct whatis_hashent);
- whatis->whatis = lg.whatis ? xstrdup (lg.whatis) : NULL;
+ new_whatis = XMALLOC (struct whatis);
+ new_whatis->whatis = lg.whatis ? xstrdup (lg.whatis) : NULL;
/* We filled out ult_trace above. */
- memcpy (&whatis->trace, &ult_trace, sizeof (ult_trace));
- hashtable_install (whatis_hash, ult, strlen (ult), whatis);
+ new_whatis->trace = ult_trace;
+ gl_map_put (whatis_map, xstrdup (ult), new_whatis);
+ whatis = new_whatis;
}
debug ("\"%s\"\n", lg.whatis);
@@ -281,15 +287,11 @@ void test_manfile (MYDBM_FILE dbf, const char *file, const char *path)
info.pointer = NULL; /* direct page, so far */
info.filter = lg.filters;
if (lg.whatis) {
- struct page_description *descs =
- parse_descriptions (manpage_base, lg.whatis);
- if (descs) {
- if (!opt_test)
- store_descriptions (dbf, descs, &info,
- path, manpage_base,
- &whatis->trace);
- free_descriptions (descs);
- }
+ gl_list_t descs = parse_descriptions (manpage_base, lg.whatis);
+ if (!opt_test)
+ store_descriptions (dbf, descs, &info, path,
+ manpage_base, whatis->trace);
+ gl_list_free (descs);
} else if (quiet < 2) {
(void) stat (ult, &buf);
if (buf.st_size == 0)
@@ -311,8 +313,8 @@ static void add_dir_entries (MYDBM_FILE dbf, const char *path, char *infile)
int len;
struct dirent *newdir;
DIR *dir;
- char **names;
- size_t names_len, names_max, i;
+ gl_list_t names;
+ const char *name;
manpage = xasprintf ("%s/%s/", path, infile);
len = strlen (manpage);
@@ -329,9 +331,7 @@ static void add_dir_entries (MYDBM_FILE dbf, const char *path, char *infile)
return;
}
- names_len = 0;
- names_max = 1024;
- names = XNMALLOC (names_max, char *);
+ names = new_string_list (GL_ARRAY_LIST, false);
/* strlen(newdir->d_name) could be replaced by newdir->d_reclen */
@@ -339,24 +339,19 @@ static void add_dir_entries (MYDBM_FILE dbf, const char *path, char *infile)
if (*newdir->d_name == '.' &&
strlen (newdir->d_name) < (size_t) 3)
continue;
- if (names_len >= names_max) {
- names_max *= 2;
- names = xnrealloc (names, names_max, sizeof (char *));
- }
- names[names_len++] = xstrdup (newdir->d_name);
+ gl_list_add_last (names, xstrdup (newdir->d_name));
}
closedir (dir);
- order_files (infile, names, names_len);
+ order_files (infile, &names);
- for (i = 0; i < names_len; ++i) {
- manpage = appendstr (manpage, names[i], (void *) 0);
+ GL_LIST_FOREACH_START (names, name) {
+ manpage = appendstr (manpage, name, (void *) 0);
test_manfile (dbf, manpage, path);
*(manpage + len) = '\0';
- free (names[i]);
- }
+ } GL_LIST_FOREACH_END (names);
- free (names);
+ gl_list_free (names);
free (manpage);
}
@@ -379,11 +374,8 @@ void chown_if_possible (const char *path)
(st.st_uid != man_owner->pw_uid ||
st.st_gid != man_owner->pw_gid)) {
debug ("fixing ownership of %s\n", path);
-#ifdef HAVE_LCHOWN
- xlchown (path, man_owner->pw_uid, man_owner->pw_gid);
-#else
- xchown (path, man_owner->pw_uid, man_owner->pw_gid);
-#endif
+ if (lchown (path, man_owner->pw_uid, man_owner->pw_gid) < 0)
+ error (FATAL, 0, _("can't chown %s"), path);
}
}
#else /* !MAN_OWNER */
@@ -652,12 +644,12 @@ int create_db (const char *manpath, const char *catpath)
}
/* Make sure an existing database is essentially sane. */
-static int sanity_check_db (MYDBM_FILE dbf)
+static bool sanity_check_db (MYDBM_FILE dbf)
{
datum key;
if (dbver_rd (dbf))
- return 0;
+ return false;
key = MYDBM_FIRSTKEY (dbf);
while (MYDBM_DPTR (key) != NULL) {
@@ -668,7 +660,7 @@ static int sanity_check_db (MYDBM_FILE dbf)
debug ("warning: %s has a key with no content (%s); "
"rebuilding\n", database, MYDBM_DPTR (key));
MYDBM_FREE_DPTR (key);
- return 0;
+ return false;
}
MYDBM_FREE_DPTR (content);
nextkey = MYDBM_NEXTKEY (dbf, key);
@@ -676,7 +668,7 @@ static int sanity_check_db (MYDBM_FILE dbf)
key = nextkey;
}
- return 1;
+ return true;
}
/* routine to update the db, ensure that it is consistent with the
@@ -771,38 +763,38 @@ pointers_next:
* out that this is better handled in look_for_file() itself.
*/
static int count_glob_matches (const char *name, const char *ext,
- char **source, struct timespec db_mtime)
+ gl_list_t source, struct timespec db_mtime)
{
- char **walk;
+ const char *walk;
int count = 0;
- for (walk = source; walk && *walk; ++walk) {
+ GL_LIST_FOREACH_START (source, walk) {
struct mandata info;
struct stat statbuf;
char *buf;
memset (&info, 0, sizeof (struct mandata));
- if (stat (*walk, &statbuf) == -1) {
+ if (stat (walk, &statbuf) == -1) {
debug ("count_glob_matches: excluding %s "
- "because stat failed\n", *walk);
+ "because stat failed\n", walk);
continue;
}
if (db_mtime.tv_sec != (time_t) -1 &&
timespec_cmp (get_stat_mtime (&statbuf), db_mtime) <= 0) {
debug ("count_glob_matches: excluding %s, "
- "no newer than database\n", *walk);
+ "no newer than database\n", walk);
continue;
}
- buf = filename_info (*walk, &info, name);
+ buf = filename_info (walk, &info, name);
if (buf) {
if (STREQ (ext, info.ext))
++count;
free (info.name);
free (buf);
}
- }
+ } GL_LIST_FOREACH_END (source);
return count;
}
@@ -811,7 +803,7 @@ static int count_glob_matches (const char *name, const char *ext,
* page.
*/
static int purge_normal (MYDBM_FILE dbf, const char *name,
- struct mandata *info, char **found)
+ struct mandata *info, gl_list_t found)
{
struct timespec t;
@@ -834,8 +826,8 @@ static int purge_normal (MYDBM_FILE dbf, const char *name,
/* Decide whether to purge a reference to a WHATIS_MAN or WHATIS_CAT page. */
static int purge_whatis (MYDBM_FILE dbf, const char *path, int cat,
- const char *name, struct mandata *info, char **found,
- struct timespec db_mtime)
+ const char *name, struct mandata *info,
+ gl_list_t found, struct timespec db_mtime)
{
/* TODO: On some systems, the cat page extension differs from the
* man page extension, so this may be too strict.
@@ -852,7 +844,7 @@ static int purge_whatis (MYDBM_FILE dbf, const char *path, int cat,
debug ("%s(%s): whatis replaced by real page; "
"forcing a rescan just in case\n",
name, info->ext);
- force_rescan = 1;
+ force_rescan = true;
return 0;
} else if (STREQ (info->pointer, "-")) {
/* This is broken; a WHATIS_MAN should never have an empty
@@ -870,23 +862,26 @@ static int purge_whatis (MYDBM_FILE dbf, const char *path, int cat,
debug ("%s(%s): whatis had empty pointer; "
"forcing a rescan just in case\n",
name, info->ext);
- force_rescan = 1;
+ force_rescan = true;
return 1;
} else {
/* Does the real page still exist? */
- char **real_found;
- int save_debug = debug_level;
+ gl_list_t real_found;
+ bool save_debug = debug_level;
struct timespec t;
+ int count;
- debug_level = 0;
+ debug_level = false;
real_found = look_for_file (path, info->ext,
info->pointer, cat, LFF_MATCHCASE);
debug_level = save_debug;
t.tv_sec = -1;
t.tv_nsec = -1;
- if (count_glob_matches (info->pointer, info->ext, real_found,
- t))
+ count = count_glob_matches (info->pointer, info->ext,
+ real_found, t);
+ gl_list_free (real_found);
+ if (count)
return 0;
if (!opt_test)
@@ -923,7 +918,7 @@ static int check_multi_key (const char *name, const char *content)
if (!valid) {
debug ("%s: broken multi key \"%s\", "
"forcing a rescan\n", name, content);
- force_rescan = 1;
+ force_rescan = true;
return 1;
}
@@ -985,8 +980,8 @@ int purge_missing (const char *manpath, const char *catpath,
datum content, nextkey;
struct mandata entry;
char *nicekey, *tab;
- int save_debug;
- char **found;
+ bool save_debug;
+ gl_list_t found;
/* Ignore db identifier keys. */
if (*MYDBM_DPTR (key) == '$') {
@@ -1025,7 +1020,7 @@ int purge_missing (const char *manpath, const char *catpath,
split_content (MYDBM_DPTR (content), &entry);
save_debug = debug_level;
- debug_level = 0; /* look_for_file() is quite noisy */
+ debug_level = false; /* look_for_file() is quite noisy */
if (entry.id <= WHATIS_MAN)
found = look_for_file (manpath, entry.ext,
entry.name ? entry.name
@@ -1051,6 +1046,7 @@ int purge_missing (const char *manpath, const char *catpath,
count += purge_whatis (dbf, catpath, 1, nicekey,
&entry, found, db_mtime);
+ gl_list_free (found);
free (nicekey);
free_mandata_elements (&entry);
diff --git a/src/descriptions.c b/src/descriptions.c
index 009a50ba..09295b8e 100644
--- a/src/descriptions.c
+++ b/src/descriptions.c
@@ -27,21 +27,36 @@
#include <string.h>
#include <stdlib.h>
+#include "gl_array_list.h"
+#include "gl_xlist.h"
+
#include "manconfig.h"
#include "descriptions.h"
+/* Free a page description. */
+void page_description_free (const void *value)
+{
+ struct page_description *desc = (struct page_description *) value;
+
+ free (desc->name);
+ free (desc->whatis);
+ free (desc);
+}
+
/* Parse the description in a whatis line returned by find_name() into a
- * sequence of names and whatis descriptions.
+ * list of names and whatis descriptions.
*/
-struct page_description *parse_descriptions (const char *base,
- const char *whatis)
+gl_list_t parse_descriptions (const char *base, const char *whatis)
{
const char *sep, *nextsep;
- struct page_description *desc = NULL, *head = NULL;
+ gl_list_t descs;
int seen_base = 0;
+ descs = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL,
+ page_description_free, true);
+
if (!whatis)
- return NULL;
+ return descs;
sep = whatis;
@@ -74,7 +89,7 @@ struct page_description *parse_descriptions (const char *base,
dash = strstr (record, " - ");
if (dash)
names = xstrndup (record, dash - record);
- else if (!desc)
+ else if (!gl_list_size (descs))
/* Some pages have a NAME section with just the page
* name and no whatis. We might as well include
* this.
@@ -93,6 +108,7 @@ struct page_description *parse_descriptions (const char *base,
for (token = strtok (names, ","); token;
token = strtok (NULL, ",")) {
char *name = trim_spaces (token);
+ struct page_description *desc;
/* Skip name tokens containing whitespace. They are
* almost never useful as manual page names.
@@ -103,16 +119,10 @@ struct page_description *parse_descriptions (const char *base,
}
/* Allocate new description node. */
- if (head) {
- desc->next = xmalloc (sizeof *desc);
- desc = desc->next;
- } else {
- desc = xmalloc (sizeof *desc);
- head = desc;
- }
+ desc = xmalloc (sizeof *desc);
desc->name = name; /* steal memory */
desc->whatis = dash ? trim_spaces (dash + 3) : NULL;
- desc->next = NULL;
+ gl_list_add_last (descs, desc);
if (base && STREQ (base, desc->name))
seen_base = 1;
@@ -129,33 +139,18 @@ next:
* list.
*/
if (base && !seen_base) {
- if (head) {
- desc->next = xmalloc (sizeof *desc);
- desc = desc->next;
- desc->whatis =
- head->whatis ? xstrdup (head->whatis) : NULL;
- } else {
- desc = xmalloc (sizeof *desc);
- head = desc;
- desc->whatis = NULL;
- }
+ struct page_description *desc = xmalloc (sizeof *desc);
+
desc->name = xstrdup (base);
- desc->next = NULL;
+ desc->whatis = NULL;
+ if (gl_list_size (descs)) {
+ const struct page_description *first =
+ gl_list_get_at (descs, 0);
+ if (first->whatis)
+ desc->whatis = xstrdup (first->whatis);
+ }
+ gl_list_add_last (descs, desc);
}
- return head;
-}
-
-/* Free a description list and all its contents. */
-void free_descriptions (struct page_description *head)
-{
- struct page_description *desc = head, *prev;
-
- while (desc) {
- free (desc->name);
- free (desc->whatis);
- prev = desc;
- desc = desc->next;
- free (prev);
- }
+ return descs;
}
diff --git a/src/descriptions.h b/src/descriptions.h
index a0161be8..38ae412a 100644
--- a/src/descriptions.h
+++ b/src/descriptions.h
@@ -20,21 +20,18 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "gl_list.h"
+
#include "db_storage.h"
struct page_description {
char *name;
char *whatis;
- struct page_description *next;
};
-struct ult_trace;
-
-extern struct page_description *parse_descriptions (const char *base,
- const char *whatis);
-extern void store_descriptions (MYDBM_FILE dbf,
- const struct page_description *head,
+/* Returns a list of struct page_description. */
+extern gl_list_t parse_descriptions (const char *base, const char *whatis);
+extern void store_descriptions (MYDBM_FILE dbf, gl_list_t descs,
struct mandata *info,
const char *path, const char *base,
- struct ult_trace *trace);
-extern void free_descriptions (struct page_description *head);
+ gl_list_t trace);
diff --git a/src/descriptions_store.c b/src/descriptions_store.c
index c473aee5..47d0b912 100644
--- a/src/descriptions_store.c
+++ b/src/descriptions_store.c
@@ -24,6 +24,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -31,9 +32,12 @@
#include "gettext.h"
#define _(String) gettext (String)
+#include "error.h"
+#include "gl_list.h"
+
#include "manconfig.h"
-#include "error.h"
+#include "glcontainers.h"
#include "db_storage.h"
@@ -60,39 +64,38 @@ static int is_prefix (const char *path, const char *dir)
/* Take a list of descriptions returned by parse_descriptions() and store
* it into the database.
*/
-void store_descriptions (MYDBM_FILE dbf, const struct page_description *head,
- struct mandata *info,
- const char *path, const char *base,
- struct ult_trace *trace)
+void store_descriptions (MYDBM_FILE dbf, gl_list_t descs, struct mandata *info,
+ const char *path, const char *base, gl_list_t trace)
{
const struct page_description *desc;
char save_id = info->id;
- size_t i;
+ const char *trace_name;
- if (trace) {
- for (i = 0; i < trace->len; ++i)
- debug ("trace->names[%zu] = '%s'\n",
- i, trace->names[i]);
+ if (gl_list_size (descs) && trace) {
+ GL_LIST_FOREACH_START (trace, trace_name)
+ debug ("trace: '%s'\n", trace_name);
+ GL_LIST_FOREACH_END (trace);
}
- for (desc = head; desc; desc = desc->next) {
+ GL_LIST_FOREACH_START (descs, desc) {
/* Either it's the real thing or merely a reference. Get the
* id and pointer right in either case.
*/
- int found_real_page = 0;
- int found_external = 0;
+ bool found_real_page = false;
+ bool found_external = false;
if (STREQ (base, desc->name)) {
info->id = save_id;
info->pointer = NULL;
info->whatis = desc->whatis;
- found_real_page = 1;
+ found_real_page = true;
} else if (trace) {
- for (i = 0; i < trace->len; ++i) {
+ size_t i = 0;
+ GL_LIST_FOREACH_START (trace, trace_name) {
struct mandata trace_info;
char *buf;
- buf = filename_info (trace->names[i],
+ buf = filename_info (trace_name,
&trace_info, "");
if (trace_info.name &&
STREQ (trace_info.name, desc->name)) {
@@ -101,24 +104,25 @@ void store_descriptions (MYDBM_FILE dbf, const struct page_description *head,
* hierarchy; skip this
* description.
*/
- found_external = 1;
+ found_external = true;
free (trace_info.name);
free (buf);
break;
}
- if (i == trace->len - 1 &&
+ if (i == gl_list_size (trace) - 1 &&
save_id == SO_MAN)
info->id = ULT_MAN;
else
info->id = save_id;
info->pointer = NULL;
info->whatis = desc->whatis;
- found_real_page = 1;
+ found_real_page = true;
}
free (trace_info.name);
free (buf);
- }
+ ++i;
+ } GL_LIST_FOREACH_END (trace);
}
if (found_external) {
@@ -144,5 +148,5 @@ void store_descriptions (MYDBM_FILE dbf, const struct page_description *head,
gripe_bad_store (base, info->ext);
break;
}
- }
+ } GL_LIST_FOREACH_END (descs);
}
diff --git a/src/globbing.c b/src/globbing.c
index 2fc8e24a..017c3611 100644
--- a/src/globbing.c
+++ b/src/globbing.c
@@ -27,6 +27,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
@@ -35,13 +36,17 @@
#include <dirent.h>
#include "fnmatch.h"
+#include "gl_array_list.h"
+#include "gl_hash_map.h"
+#include "gl_xlist.h"
+#include "gl_xmap.h"
#include "regex.h"
#include "xvasprintf.h"
#include "manconfig.h"
#include "error.h"
-#include "hashtable.h"
+#include "glcontainers.h"
#include "cleanup.h"
#include "xregcomp.h"
@@ -109,23 +114,23 @@ static int parse_layout (const char *layout)
}
}
-struct dirent_hashent {
+struct dirent_names {
char **names;
size_t names_len, names_max;
};
-static void dirent_hashtable_free (void *defn)
+static void dirent_names_free (const void *value)
{
- struct dirent_hashent *hashent = defn;
+ struct dirent_names *cache = (struct dirent_names *) value;
size_t i;
- for (i = 0; i < hashent->names_len; ++i)
- free (hashent->names[i]);
- free (hashent->names);
- free (hashent);
+ for (i = 0; i < cache->names_len; ++i)
+ free (cache->names[i]);
+ free (cache->names);
+ free (cache);
}
-static struct hashtable *dirent_hash = NULL;
+static gl_map_t dirent_map = NULL;
static int cache_compare (const void *a, const void *b)
{
@@ -134,17 +139,17 @@ static int cache_compare (const void *a, const void *b)
return strcasecmp (left, right);
}
-static struct dirent_hashent *update_directory_cache (const char *path)
+static struct dirent_names *update_directory_cache (const char *path)
{
- struct dirent_hashent *cache;
+ struct dirent_names *cache;
DIR *dir;
struct dirent *entry;
- if (!dirent_hash) {
- dirent_hash = hashtable_create (&dirent_hashtable_free);
- push_cleanup ((cleanup_fun) hashtable_free, dirent_hash, 0);
+ if (!dirent_map) {
+ dirent_map = new_string_map (GL_HASH_MAP, dirent_names_free);
+ push_cleanup ((cleanup_fun) gl_map_free, dirent_map, 0);
}
- cache = hashtable_lookup (dirent_hash, path, strlen (path));
+ cache = (struct dirent_names *) gl_map_get (dirent_map, path);
/* Check whether we've got this one already. */
if (cache) {
@@ -160,7 +165,7 @@ static struct dirent_hashent *update_directory_cache (const char *path)
return NULL;
}
- cache = XMALLOC (struct dirent_hashent);
+ cache = XMALLOC (struct dirent_names);
cache->names_len = 0;
cache->names_max = 1024;
cache->names = XNMALLOC (cache->names_max, char *);
@@ -179,7 +184,7 @@ static struct dirent_hashent *update_directory_cache (const char *path)
qsort (cache->names, cache->names_len, sizeof *cache->names,
&cache_compare);
- hashtable_install (dirent_hash, path, strlen (path), cache);
+ gl_map_put (dirent_map, xstrdup (path), cache);
closedir (dir);
return cache;
@@ -197,34 +202,16 @@ static int pattern_compare (const void *a, const void *b)
return strncasecmp (key->pattern, memb, key->len);
}
-static void clear_glob (glob_t *pglob)
+static void match_in_directory (const char *path, const char *pattern,
+ int opts, gl_list_t matched)
{
- /* look_for_file declares this static, so it's zero-initialised.
- * globfree() can deal with checking it before freeing.
- */
- globfree (pglob);
-
- pglob->gl_pathc = 0;
- pglob->gl_pathv = NULL;
- pglob->gl_offs = 0;
-}
-
-static void match_in_directory (const char *path, const char *pattern, int opts,
- glob_t *pglob, size_t *allocated)
-{
- struct dirent_hashent *cache;
- size_t my_allocated = 0;
+ struct dirent_names *cache;
int flags;
regex_t preg;
struct pattern_bsearch pattern_start = { NULL, -1 };
char **bsearched;
size_t i;
- if (!allocated)
- allocated = &my_allocated;
- if (!*allocated)
- clear_glob (pglob);
-
cache = update_directory_cache (path);
if (!cache) {
debug ("directory cache update failed\n");
@@ -233,12 +220,6 @@ static void match_in_directory (const char *path, const char *pattern, int opts,
debug ("globbing pattern in %s: %s\n", path, pattern);
- if (!*allocated) {
- *allocated = 4;
- pglob->gl_pathv = XNMALLOC (*allocated, char *);
- pglob->gl_pathv[0] = NULL;
- }
-
if (opts & LFF_REGEX)
flags = REG_EXTENDED | REG_NOSUB |
((opts & LFF_MATCHCASE) ? 0 : REG_ICASE);
@@ -280,46 +261,25 @@ static void match_in_directory (const char *path, const char *pattern, int opts,
debug ("matched: %s/%s\n", path, cache->names[i]);
- if (pglob->gl_pathc >= *allocated) {
- *allocated *= 2;
- pglob->gl_pathv = xnrealloc (
- pglob->gl_pathv, *allocated, sizeof (char *));
- }
- pglob->gl_pathv[pglob->gl_pathc++] =
- xasprintf ("%s/%s", path, cache->names[i]);
+ gl_list_add_last (matched,
+ xasprintf ("%s/%s", path, cache->names[i]));
}
if (opts & LFF_REGEX)
regfree (&preg);
else
free (pattern_start.pattern);
-
- if (pglob->gl_pathc >= *allocated) {
- *allocated *= 2;
- pglob->gl_pathv = xnrealloc (pglob->gl_pathv,
- *allocated, sizeof (char *));
- }
- pglob->gl_pathv[pglob->gl_pathc] = NULL;
-
- return;
}
-char **look_for_file (const char *hier, const char *sec,
- const char *unesc_name, int cat, int opts)
+gl_list_t look_for_file (const char *hier, const char *sec,
+ const char *unesc_name, int cat, int opts)
{
+ gl_list_t matched;
char *pattern, *path = NULL;
- static glob_t gbuf;
- static int cleanup_installed = 0;
static int layout = -1;
char *name;
- if (!cleanup_installed) {
- /* appease valgrind */
- push_cleanup ((cleanup_fun) globfree, &gbuf, 0);
- cleanup_installed = 1;
- }
-
- clear_glob (&gbuf);
+ matched = new_string_list (GL_ARRAY_LIST, false);
/* This routine only does a minimum amount of matching. It does not
find cat files in the alternate cat directory. */
@@ -337,41 +297,39 @@ char **look_for_file (const char *hier, const char *sec,
/* allow lookups like "3x foo" to match "../man3/foo.3x" */
if (layout & LAYOUT_GNU) {
- glob_t dirs;
- size_t i;
- size_t allocated = 0;
+ gl_list_t dirs;
+ const char *dir;
- memset (&dirs, 0, sizeof (dirs));
+ dirs = new_string_list (GL_ARRAY_LIST, false);
pattern = xasprintf ("%s\t*", cat ? "cat" : "man");
*strrchr (pattern, '\t') = *sec;
- match_in_directory (hier, pattern, LFF_MATCHCASE, &dirs, NULL);
+ match_in_directory (hier, pattern, LFF_MATCHCASE, dirs);
free (pattern);
pattern = make_pattern (name, sec, opts);
- for (i = 0; i < dirs.gl_pathc; ++i) {
+ GL_LIST_FOREACH_START (dirs, dir) {
if (path)
*path = '\0';
- match_in_directory (dirs.gl_pathv[i], pattern, opts,
- &gbuf, &allocated);
- }
+ match_in_directory (dir, pattern, opts, matched);
+ } GL_LIST_FOREACH_END (dirs);
free (pattern);
- globfree (&dirs);
+ gl_list_free (dirs);
}
/* Try HPUX style compressed man pages */
- if ((layout & LAYOUT_HPUX) && gbuf.gl_pathc == 0) {
+ if ((layout & LAYOUT_HPUX) && gl_list_size (matched) == 0) {
if (path)
*path = '\0';
path = appendstr (path, hier, cat ? "/cat" : "/man",
sec, ".Z", (void *) 0);
pattern = make_pattern (name, sec, opts);
- match_in_directory (path, pattern, opts, &gbuf, NULL);
+ match_in_directory (path, pattern, opts, matched);
free (pattern);
}
/* Try man pages without the section extension --- IRIX man pages */
- if ((layout & LAYOUT_IRIX) && gbuf.gl_pathc == 0) {
+ if ((layout & LAYOUT_IRIX) && gl_list_size (matched) == 0) {
if (path)
*path = '\0';
path = appendstr (path, hier, cat ? "/cat" : "/man", sec,
@@ -381,12 +339,12 @@ char **look_for_file (const char *hier, const char *sec,
else
pattern = xasprintf ("%s.*", name);
- match_in_directory (path, pattern, opts, &gbuf, NULL);
+ match_in_directory (path, pattern, opts, matched);
free (pattern);
}
/* Try Solaris style man page directories */
- if ((layout & LAYOUT_SOLARIS) && gbuf.gl_pathc == 0) {
+ if ((layout & LAYOUT_SOLARIS) && gl_list_size (matched) == 0) {
if (path)
*path = '\0';
/* TODO: This needs to be man/sec*, not just man/sec. */
@@ -394,12 +352,12 @@ char **look_for_file (const char *hier, const char *sec,
(void *) 0);
pattern = make_pattern (name, sec, opts);
- match_in_directory (path, pattern, opts, &gbuf, NULL);
+ match_in_directory (path, pattern, opts, matched);
free (pattern);
}
/* BSD cat pages take the extension .0 */
- if ((layout & LAYOUT_BSD) && gbuf.gl_pathc == 0) {
+ if ((layout & LAYOUT_BSD) && gl_list_size (matched) == 0) {
if (path)
*path = '\0';
if (cat) {
@@ -412,40 +370,34 @@ char **look_for_file (const char *hier, const char *sec,
path = appendstr (path, hier, "/man", sec, (void *) 0);
pattern = make_pattern (name, sec, opts);
}
- match_in_directory (path, pattern, opts, &gbuf, NULL);
+ match_in_directory (path, pattern, opts, matched);
free (pattern);
}
free (name);
free (path);
- if (gbuf.gl_pathc == 0)
- return NULL;
- else
- return gbuf.gl_pathv;
+ return matched;
}
-char **expand_path (const char *path)
+gl_list_t expand_path (const char *path)
{
int res = 0;
- char **result = NULL;
+ gl_list_t result;
glob_t globbuf;
- size_t i;
+
+ result = new_string_list (GL_ARRAY_LIST, false);
res = glob (path, GLOB_NOCHECK, NULL, &globbuf);
/* if glob failed, return the given path */
- if (res != 0) {
- result = XNMALLOC (2, char *);
- result[0] = xstrdup (path);
- result[1] = NULL;
- return result;
- }
-
- result = XNMALLOC (globbuf.gl_pathc + 1, char *);
- for (i = 0; i < globbuf.gl_pathc; i++) {
- result[i] = xstrdup (globbuf.gl_pathv[i]);
+ if (res != 0)
+ gl_list_add_last (result, xstrdup (path));
+ else {
+ size_t i;
+ for (i = 0; i < globbuf.gl_pathc; ++i)
+ gl_list_add_last (result,
+ xstrdup (globbuf.gl_pathv[i]));
}
- result[globbuf.gl_pathc] = NULL;
globfree (&globbuf);
diff --git a/src/globbing.h b/src/globbing.h
index 1c811418..ea9ff001 100644
--- a/src/globbing.h
+++ b/src/globbing.h
@@ -20,6 +20,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "gl_list.h"
+
enum look_for_file_opts {
LFF_MATCHCASE = 1,
LFF_REGEX = 2,
@@ -27,8 +29,8 @@ enum look_for_file_opts {
};
/* globbing.c */
-extern char **look_for_file (const char *hier, const char *sec,
- const char *unesc_name, int cat, int opts);
+extern gl_list_t look_for_file (const char *hier, const char *sec,
+ const char *unesc_name, int cat, int opts);
/* Expand path with wildcards into list of all existing directories. */
-extern char **expand_path (const char *path);
+extern gl_list_t expand_path (const char *path);
diff --git a/src/globbing_test.c b/src/globbing_test.c
index eb4070a1..5f0878fa 100644
--- a/src/globbing_test.c
+++ b/src/globbing_test.c
@@ -25,10 +25,12 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "argp.h"
+#include "gl_list.h"
#include "progname.h"
#include "gettext.h"
@@ -38,15 +40,16 @@
#include "manconfig.h"
#include "error.h"
+#include "glcontainers.h"
#include "globbing.h"
#include "sandbox.h"
man_sandbox *sandbox; /* unused, but needed by libman */
extern const char *extension;
-static int match_case = 0;
-static int regex_opt = 0;
-static int wildcard = 0;
+static bool match_case = false;
+static bool regex_opt = false;
+static bool wildcard = false;
static char **remaining_args;
const char *argp_program_version = "globbing " PACKAGE_VERSION;
@@ -70,22 +73,22 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'e':
extension = arg;
return 0;
case 'i':
- match_case = 0;
+ match_case = false;
return 0;
case 'I':
- match_case = 1;
+ match_case = true;
return 0;
case 'r':
- regex_opt = 1;
+ regex_opt = true;
return 0;
case 'w':
- wildcard = 1;
+ wildcard = true;
return 0;
case 'h':
argp_state_help (state, state->out_stream,
@@ -115,16 +118,18 @@ int main (int argc, char **argv)
exit (FAIL);
for (i = 0; i <= 1; i++) {
- char **files;
+ gl_list_t files;
+ const char *file;
files = look_for_file (remaining_args[0], remaining_args[1],
remaining_args[2], i,
(match_case ? LFF_MATCHCASE : 0) |
(regex_opt ? LFF_REGEX : 0) |
(wildcard ? LFF_WILDCARD : 0));
- if (files)
- while (*files)
- printf ("%s\n", *files++);
+ GL_LIST_FOREACH_START (files, file)
+ printf ("%s\n", file);
+ GL_LIST_FOREACH_END (files);
+ gl_list_free (files);
}
return 0;
}
diff --git a/src/lexgrog_test.c b/src/lexgrog_test.c
index c310aa0c..4fb39fd1 100644
--- a/src/lexgrog_test.c
+++ b/src/lexgrog_test.c
@@ -26,6 +26,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -33,6 +34,8 @@
#include <sys/stat.h>
#include "argp.h"
+#include "error.h"
+#include "gl_list.h"
#include "progname.h"
#include "gettext.h"
@@ -42,7 +45,7 @@
#include "manconfig.h"
#include "cleanup.h"
-#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "sandbox.h"
#include "security.h"
@@ -53,7 +56,8 @@
int quiet = 1;
man_sandbox *sandbox;
-static int parse_man = 0, parse_cat = 0, show_whatis = 0, show_filters = 0;
+static bool parse_man = false, parse_cat = false;
+static bool show_whatis = false, show_filters = false;
static const char *encoding = NULL;
static char **files;
static int num_files;
@@ -80,19 +84,19 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'm':
- parse_man = 1;
+ parse_man = true;
return 0;
case 'c':
- parse_cat = 1;
+ parse_cat = true;
return 0;
case 'w':
- show_whatis = 1;
+ show_whatis = true;
return 0;
case 'f':
- show_filters = 1;
+ show_filters = true;
return 0;
case 'E':
encoding = arg;
@@ -119,9 +123,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
"-m -c");
/* defaults: --man, --whatis */
if (!parse_man && !parse_cat)
- parse_man = 1;
+ parse_man = true;
if (!show_whatis && !show_filters)
- show_whatis = 1;
+ show_whatis = true;
return 0;
}
return ARGP_ERR_UNKNOWN;
@@ -148,7 +152,7 @@ int main (int argc, char **argv)
{
int type = 0;
int i;
- int some_failed = 0;
+ bool some_failed = false;
set_program_name (argv[0]);
@@ -173,7 +177,7 @@ int main (int argc, char **argv)
for (i = 0; i < num_files; ++i) {
lexgrog lg;
const char *file;
- int found = 0;
+ bool found = false;
lg.type = type;
@@ -205,13 +209,12 @@ int main (int argc, char **argv)
}
if (file && find_name (file, "-", &lg, encoding)) {
- struct page_description *descs =
- parse_descriptions (NULL, lg.whatis);
+ gl_list_t descs = parse_descriptions (NULL, lg.whatis);
const struct page_description *desc;
- for (desc = descs; desc; desc = desc->next) {
+ GL_LIST_FOREACH_START (descs, desc) {
if (!desc->name || !desc->whatis)
continue;
- found = 1;
+ found = true;
printf ("%s", files[i]);
if (show_filters)
printf (" (%s)", lg.filters);
@@ -219,18 +222,20 @@ int main (int argc, char **argv)
printf (": \"%s - %s\"",
desc->name, desc->whatis);
printf ("\n");
- }
- free_descriptions (descs);
+ } GL_LIST_FOREACH_END (descs);
+ gl_list_free (descs);
free (lg.filters);
free (lg.whatis);
}
if (!found) {
printf ("%s: parse failed\n", files[i]);
- some_failed = 1;
+ some_failed = true;
}
}
+ sandbox_free (sandbox);
+
if (some_failed)
return FATAL;
else
diff --git a/src/man.c b/src/man.c
index a1445964..78c8968c 100644
--- a/src/man.c
+++ b/src/man.c
@@ -40,6 +40,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -48,18 +49,8 @@
#include <errno.h>
#include <termios.h>
#include <unistd.h>
-
-#ifndef R_OK
-# define R_OK 4
-# define X_OK 1
-#endif /* !R_OK */
-
#include <limits.h>
-
-#if HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
+#include <fcntl.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
@@ -68,13 +59,19 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_array_list.h"
+#include "gl_hash_map.h"
+#include "gl_list.h"
+#include "gl_xlist.h"
+#include "gl_xmap.h"
#include "minmax.h"
#include "progname.h"
#include "regex.h"
#include "stat-time.h"
#include "utimens.h"
-#include "xvasprintf.h"
#include "xgetcwd.h"
+#include "xvasprintf.h"
+#include "xstdopen.h"
#include "gettext.h"
#include <locale.h>
@@ -85,7 +82,7 @@
#include "error.h"
#include "cleanup.h"
-#include "hashtable.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "pathsearch.h"
#include "linelength.h"
@@ -137,7 +134,7 @@ char *lang;
#define TFMT_PROG "mandb_tfmt"
#undef ALT_EXT_FORMAT /* allow external formatters located in cat hierarchy */
-static int global_manpath = -1; /* global or user manual page hierarchy? */
+static bool global_manpath; /* global or user manual page hierarchy? */
static int skip; /* page exists but has been skipped */
#if defined _AIX || defined __sgi
@@ -175,27 +172,20 @@ enum opts {
OPT_MAX
};
-struct string_llist;
-struct string_llist {
- const char *name;
- struct string_llist *next;
-};
-
-
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
/* globals */
int quiet = 1;
char *database = NULL;
extern const char *extension; /* for globbing.c */
extern char *user_config_file; /* defined in manp.c */
-extern int disable_cache;
+extern bool disable_cache;
extern int min_cat_width, max_cat_width, cat_width;
man_sandbox *sandbox;
/* locals */
static const char *alt_system_name;
-static const char **section_list;
+static gl_list_t section_list;
static const char *section;
static char *colon_sep_section_list;
static const char *preprocessors;
@@ -207,33 +197,33 @@ static char *less;
static const char *std_sections[] = STD_SECTIONS;
static char *manp;
static const char *external;
-static struct hashtable *db_hash = NULL;
+static gl_map_t db_map = NULL;
-static int troff;
+static bool troff;
static const char *roff_device = NULL;
static const char *want_encoding = NULL;
#ifdef NROFF_WARNINGS
static const char default_roff_warnings[] = "mac";
-static struct string_llist *roff_warnings = NULL;
+static gl_list_t roff_warnings;
#endif /* NROFF_WARNINGS */
-static int global_apropos;
-static int print_where, print_where_cat;
-static int catman;
-static int local_man_file;
-static int findall;
-static int update;
-static int match_case;
-static int regex_opt;
-static int wildcard;
-static int names_only;
+static bool global_apropos;
+static bool print_where, print_where_cat;
+static bool catman;
+static bool local_man_file;
+static bool findall;
+static bool update;
+static bool match_case;
+static bool regex_opt;
+static bool wildcard;
+static bool names_only;
static int ult_flags = SO_LINK | SOFT_LINK | HARD_LINK;
static const char *recode = NULL;
-static int no_hyphenation;
-static int no_justification;
-static int subpages = 1;
+static bool no_hyphenation;
+static bool no_justification;
+static bool subpages = true;
-static int ascii; /* insert tr in the output pipe */
-static int save_cat; /* security breach? Can we save the cat? */
+static bool ascii; /* insert tr in the output pipe */
+static bool save_cat; /* security breach? Can we save the cat? */
static int first_arg;
@@ -248,9 +238,9 @@ static struct timespec man_modtime; /* modtime of man page, for
* commit_tmp_cat() */
# ifdef TROFF_IS_GROFF
-static int ditroff;
+static bool ditroff;
static const char *gxditview;
-static int htmlout;
+static bool htmlout;
static const char *html_pager;
# endif /* TROFF_IS_GROFF */
@@ -352,7 +342,7 @@ static void init_html_pager (void)
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
- static int apropos, whatis; /* retain values between calls */
+ static bool apropos, whatis; /* retain values between calls */
/* Please keep these keys in the same order as in options above. */
switch (key) {
@@ -360,7 +350,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
user_config_file = arg;
return 0;
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'D':
/* discard all preset options */
@@ -369,11 +359,11 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
print_where = print_where_cat =
ascii = match_case =
regex_opt = wildcard = names_only =
- no_hyphenation = no_justification = 0;
+ no_hyphenation = no_justification = false;
#ifdef TROFF_IS_GROFF
- ditroff = 0;
+ ditroff = false;
gxditview = NULL;
- htmlout = 0;
+ htmlout = false;
init_html_pager ();
#endif
roff_device = want_encoding = extension = pager =
@@ -390,13 +380,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
const char *warning;
for (warning = strtok (s, ","); warning;
- warning = strtok (NULL, ",")) {
- struct string_llist *new;
- new = xmalloc (sizeof *new);
- new->name = xstrdup (warning);
- new->next = roff_warnings;
- roff_warnings = new;
- }
+ warning = strtok (NULL, ","))
+ gl_list_add_last (roff_warnings,
+ xstrdup (warning));
free (s);
}
@@ -405,26 +391,26 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
case 'f':
external = WHATIS;
- whatis = 1;
+ whatis = true;
return 0;
case 'k':
external = APROPOS;
- apropos = 1;
+ apropos = true;
return 0;
case 'K':
- global_apropos = 1;
+ global_apropos = true;
return 0;
case 'w':
- print_where = 1;
+ print_where = true;
return 0;
case 'W':
- print_where_cat = 1;
+ print_where_cat = true;
return 0;
case 'l':
- local_man_file = 1;
+ local_man_file = true;
return 0;
case 'c':
- catman = 1;
+ catman = true;
return 0;
case 'R':
recode = arg;
@@ -449,30 +435,30 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
extension = arg;
return 0;
case 'i':
- match_case = 0;
+ match_case = false;
return 0;
case 'I':
- match_case = 1;
+ match_case = true;
return 0;
case OPT_REGEX:
- regex_opt = 1;
- findall = 1;
+ regex_opt = true;
+ findall = true;
return 0;
case OPT_WILDCARD:
- wildcard = 1;
- findall = 1;
+ wildcard = true;
+ findall = true;
return 0;
case OPT_NAMES:
- names_only = 1;
+ names_only = true;
return 0;
case 'a':
- findall = 1;
+ findall = true;
return 0;
case 'u':
- update = 1;
+ update = true;
return 0;
case OPT_NO_SUBPAGES:
- subpages = 0;
+ subpages = false;
return 0;
case 'P':
@@ -482,7 +468,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
prompt_string = arg;
return 0;
case '7':
- ascii = 1;
+ ascii = true;
return 0;
case 'E':
want_encoding = arg;
@@ -490,17 +476,17 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
roff_device = want_encoding;
return 0;
case OPT_NO_HYPHENATION:
- no_hyphenation = 1;
+ no_hyphenation = true;
return 0;
case OPT_NO_JUSTIFICATION:
- no_justification = 1;
+ no_justification = true;
return 0;
case 'p':
preprocessors = arg;
return 0;
#ifdef HAS_TROFF
case 't':
- troff = 1;
+ troff = true;
return 0;
case 'T':
/* Traditional nroff knows -T; troff does not (gets
@@ -508,27 +494,27 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
* does -T imply -t?
*/
roff_device = (arg ? arg : "ps");
- troff = 1;
+ troff = true;
return 0;
case 'H':
# ifdef TROFF_IS_GROFF
if (arg)
html_pager = arg;
- htmlout = 1;
- troff = 1;
+ htmlout = true;
+ troff = true;
roff_device = "html";
# endif /* TROFF_IS_GROFF */
return 0;
case 'X':
# ifdef TROFF_IS_GROFF
- troff = 1;
+ troff = true;
gxditview = (arg ? arg : "75");
# endif /* TROFF_IS_GROFF */
return 0;
case 'Z':
# ifdef TROFF_IS_GROFF
- ditroff = 1;
- troff = 1;
+ ditroff = true;
+ troff = true;
# endif /* TROFF_IS_GROFF */
return 0;
#endif /* HAS_TROFF */
@@ -539,8 +525,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_SUCCESS:
/* check for incompatible options */
- if (troff + whatis + apropos + catman +
- (print_where || print_where_cat) > 1) {
+ if ((int) troff + (int) whatis + (int) apropos +
+ (int) catman +
+ (int) (print_where || print_where_cat) > 1) {
char *badopts = xasprintf
("%s%s%s%s%s%s",
troff ? "-[tTZH] " : "",
@@ -553,7 +540,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
_("%s: incompatible options"),
badopts);
}
- if (regex_opt + wildcard > 1) {
+ if ((int) regex_opt + (int) wildcard > 1) {
char *badopts = xasprintf
("%s%s",
regex_opt ? "--regex " : "",
@@ -618,48 +605,6 @@ static void gripe_no_name (const char *sect)
exit (FAIL);
}
-/* In case we're set-id, double-check that our standard file descriptors are
- * open in a standard way. See:
- *
- * http://austingroupbugs.net/view.php?id=173
- */
-static void check_standard_fds (void)
-{
- int flags, mode;
-
- /* We can't even write an error message in this case, so check it
- * first.
- */
- flags = fcntl (2, F_GETFL);
- if (flags < 0)
- exit (FATAL);
- mode = flags & O_ACCMODE;
- if (mode != O_WRONLY && mode != O_RDWR)
- exit (FATAL);
-
- flags = fcntl (0, F_GETFL);
- if (flags < 0) {
- fprintf (stderr, "stdin not open!\n");
- exit (FATAL);
- }
- mode = flags & O_ACCMODE;
- if (mode != O_RDONLY && mode != O_RDWR) {
- fprintf (stderr, "stdin not open for reading!\n");
- exit (FATAL);
- }
-
- flags = fcntl (1, F_GETFL);
- if (flags < 0) {
- fprintf (stderr, "stdout not open!\n");
- exit (FATAL);
- }
- mode = flags & O_ACCMODE;
- if (mode != O_WRONLY && mode != O_RDWR) {
- fprintf (stderr, "stdout not open for writing!\n");
- exit (FATAL);
- }
-}
-
static struct termios tms;
static int tms_set = 0;
static pid_t tms_pid = 0;
@@ -716,7 +661,7 @@ static void heirloom_line_length (void *data)
}
#endif /* HEIRLOOM_NROFF */
-static pipecmd *add_roff_line_length (pipecmd *cmd, int *save_cat_p)
+static pipecmd *add_roff_line_length (pipecmd *cmd, bool *save_cat_p)
{
int length;
pipecmd *ret = NULL;
@@ -733,7 +678,7 @@ static pipecmd *add_roff_line_length (pipecmd *cmd, int *save_cat_p)
debug ("Terminal width %d not within cat page range "
"[%d, %d]\n",
line_length, min_cat_width, max_cat_width);
- *save_cat_p = 0;
+ *save_cat_p = false;
}
}
@@ -976,17 +921,17 @@ static char *locale_manpath (const char *manpath)
*/
static const char *is_section (const char *name)
{
- const char **vs;
+ const char *vs;
- for (vs = section_list; *vs; vs++) {
- if (STREQ (*vs, name))
+ GL_LIST_FOREACH_START (section_list, vs) {
+ if (STREQ (vs, name))
return name;
/* allow e.g. 3perl but disallow 8139too and libfoo */
- if (strlen (*vs) == 1 && CTYPE (isdigit, **vs) &&
+ if (strlen (vs) == 1 && CTYPE (isdigit, *vs) &&
strlen (name) > 1 && !CTYPE (isdigit, name[1]) &&
- STRNEQ (*vs, name, 1))
+ STRNEQ (vs, name, 1))
return name;
- }
+ } GL_LIST_FOREACH_END (section_list);
return NULL;
}
@@ -1067,27 +1012,27 @@ static char *get_preprocessors (pipeline *decomp, const char *dbfilters,
if (dbfilters && (dbfilters[0] != '-') && !preprocessors) {
pp_string = xstrdup (dbfilters);
pp_source = "database";
- save_cat = 1;
+ save_cat = true;
} else if (preprocessors) {
pp_string = xstrdup (preprocessors);
pp_source = "command line";
- save_cat = 0;
+ save_cat = false;
} else if ((pp_string = get_preprocessors_from_file (decomp,
prefixes))) {
pp_source = "file";
- save_cat = 1;
+ save_cat = true;
} else if ((env = getenv ("MANROFFSEQ"))) {
pp_string = xstrdup (env);
pp_source = "environment";
- save_cat = 0;
+ save_cat = false;
} else if (!dbfilters) {
pp_string = xstrdup (DEFAULT_MANROFFSEQ);
pp_source = "default";
- save_cat = 1;
+ save_cat = true;
} else {
pp_string = xstrdup ("");
pp_source = "no filters";
- save_cat = 1;
+ save_cat = true;
}
debug ("pre-processors `%s' from %s\n", pp_string, pp_source);
@@ -1311,7 +1256,7 @@ static pipeline *make_roff_command (const char *dir, const char *file,
do {
#ifdef NROFF_WARNINGS
- struct string_llist *cur;
+ const char *warning;
#endif /* NROFF_WARNINGS */
int wants_dev = 0; /* filter wants a dev argument */
int wants_post = 0; /* postprocessor arguments */
@@ -1359,7 +1304,7 @@ static pipeline *make_roff_command (const char *dir, const char *file,
if (troff) {
cmd = pipecmd_new_argstr
(get_def ("troff", TROFF));
- save_cat = 0;
+ save_cat = false;
} else
cmd = pipecmd_new_argstr
(get_def ("nroff", NROFF));
@@ -1379,9 +1324,9 @@ static pipeline *make_roff_command (const char *dir, const char *file,
#endif /* TROFF_IS_GROFF || HEIRLOOM_NROFF */
#ifdef NROFF_WARNINGS
- for (cur = roff_warnings; cur;
- cur = cur->next)
- pipecmd_argf (cmd, "-w%s", cur->name);
+ GL_LIST_FOREACH_START (roff_warnings, warning)
+ pipecmd_argf (cmd, "-w%s", warning);
+ GL_LIST_FOREACH_END (roff_warnings);
#endif /* NROFF_WARNINGS */
#ifdef HEIRLOOM_NROFF
@@ -1478,7 +1423,7 @@ static pipeline *make_browser (const char *pattern, const char *file)
pipeline *p;
pipecmd *cmd;
char *browser = xmalloc (1);
- int found_percent_s = 0;
+ bool found_percent_s = false;
char *percent;
char *esc_file;
@@ -1502,7 +1447,7 @@ static pipeline *make_browser (const char *pattern, const char *file)
browser = appendstr (browser, esc_file,
(void *) 0);
free (esc_file);
- found_percent_s = 1;
+ found_percent_s = true;
break;
default:
len = strlen (browser); /* cannot be NULL */
@@ -2204,7 +2149,7 @@ static int display (const char *dir, const char *man_file,
int prefixes = 0;
pipeline *format_cmd; /* command to format man_file to stdout */
char *formatted_encoding = NULL;
- int display_to_stdout;
+ bool display_to_stdout;
pipeline *decomp = NULL;
int decomp_errno = 0;
@@ -2308,10 +2253,10 @@ static int display (const char *dir, const char *man_file,
display_to_stdout = troff;
#ifdef TROFF_IS_GROFF
if (htmlout)
- display_to_stdout = 0;
+ display_to_stdout = false;
#endif
if (recode)
- display_to_stdout = 1;
+ display_to_stdout = true;
if (display_to_stdout) {
/* If we're reading stdin via '-l -', man_file is "". See
@@ -2367,7 +2312,7 @@ static int display (const char *dir, const char *man_file,
|| local_man_file
|| recode
|| disable_cache)
- save_cat = 0;
+ save_cat = false;
if (!man_file) {
/* Stray cat. */
@@ -2375,7 +2320,7 @@ static int display (const char *dir, const char *man_file,
format = 0;
} else if (!cat_file) {
assert (man_file);
- save_cat = 0;
+ save_cat = false;
format = 1;
} else if (format && save_cat) {
char *cat_dir;
@@ -2419,7 +2364,7 @@ static int display (const char *dir, const char *man_file,
(format ? man_file : cat_file, R_OK);
debug ("format: %d, save_cat: %d, found: %d\n",
- format, save_cat, found);
+ format, (int) save_cat, found);
if (!found) {
pipeline_free (format_cmd);
@@ -2692,25 +2637,25 @@ static int get_ult_flags (char from_db, char id)
}
/* Is this candidate substantially a duplicate of a previous one?
- * Returns non-zero if so, otherwise zero.
+ * Returns true if so, otherwise false.
*/
-static int duplicate_candidates (struct candidate *left,
- struct candidate *right)
+static bool duplicate_candidates (struct candidate *left,
+ struct candidate *right)
{
const char *slash1, *slash2;
struct locale_bits bits1, bits2;
- int ret;
+ bool ret;
if (left->ult && right->ult && STREQ (left->ult, right->ult))
- return 1; /* same ultimate source file */
+ return true; /* same ultimate source file */
if (!STREQ (left->source->name, right->source->name) ||
!STREQ (left->source->sec, right->source->sec) ||
!STREQ (left->source->ext, right->source->ext))
- return 0; /* different name/section/extension */
+ return false; /* different name/section/extension */
if (STREQ (left->path, right->path))
- return 1; /* same path */
+ return true; /* same path */
/* Figure out if we've had a sufficiently similar candidate for this
* language already.
@@ -2720,7 +2665,7 @@ static int duplicate_candidates (struct candidate *left,
if (!slash1 || !slash2 ||
!STRNEQ (left->path, right->path,
MAX (slash1 - left->path, slash2 - right->path)))
- return 0; /* different path base */
+ return false; /* different path base */
unpack_locale_bits (++slash1, &bits1);
unpack_locale_bits (++slash2, &bits2);
@@ -2728,12 +2673,12 @@ static int duplicate_candidates (struct candidate *left,
if (!STREQ (bits1.language, bits2.language) ||
!STREQ (bits1.territory, bits2.territory) ||
!STREQ (bits1.modifier, bits2.modifier))
- ret = 0; /* different language/territory/modifier */
+ ret = false; /* different language/territory/modifier */
else
/* Everything seems to be the same; we can find nothing to
* choose between them.
*/
- ret = 1;
+ ret = true;
free_locale_bits (&bits1);
free_locale_bits (&bits2);
@@ -2744,7 +2689,6 @@ static int compare_candidates (const struct candidate *left,
const struct candidate *right)
{
const struct mandata *lsource = left->source, *rsource = right->source;
- int sec_left = 0, sec_right = 0;
int cmp;
const char *slash1, *slash2;
@@ -2771,7 +2715,7 @@ static int compare_candidates (const struct candidate *left,
* moved out of order with respect to their parent sections.
*/
if (strcmp (lsource->ext, rsource->ext)) {
- const char **sp;
+ size_t index_left, index_right;
/* If the user asked for an explicit section, sort exact
* matches first.
@@ -2787,24 +2731,30 @@ static int compare_candidates (const struct candidate *left,
}
/* Find out whether lsource->ext is ahead of rsource->ext in
- * section_list.
+ * section_list. Sections missing from section_list are
+ * sorted to the end.
*/
- for (sp = section_list; *sp; ++sp) {
- if (!*(*sp + 1)) {
- /* No extension */
- if (!sec_left && **sp == *(lsource->ext))
- sec_left = sp - section_list + 1;
- if (!sec_right && **sp == *(rsource->ext))
- sec_right = sp - section_list + 1;
- } else if (STREQ (*sp, lsource->ext)) {
- sec_left = sp - section_list + 1;
- } else if (STREQ (*sp, rsource->ext)) {
- sec_right = sp - section_list + 1;
- }
- /* Keep looking for a more specific match */
+ index_left = gl_list_indexof (section_list, lsource->ext);
+ if (index_left == (size_t) -1 && strlen (lsource->ext) > 1) {
+ char *sec_left = xstrndup (lsource->ext, 1);
+ index_left = gl_list_indexof (section_list, sec_left);
+ free (sec_left);
+ if (index_left == (size_t) -1)
+ index_left = gl_list_size (section_list);
+ }
+ index_right = gl_list_indexof (section_list, rsource->ext);
+ if (index_right == (size_t) -1 && strlen (rsource->ext) > 1) {
+ char *sec_right = xstrndup (rsource->ext, 1);
+ index_right = gl_list_indexof (section_list,
+ sec_right);
+ free (sec_right);
+ if (index_right == (size_t) -1)
+ index_right = gl_list_size (section_list);
}
- if (sec_left != sec_right)
- return sec_left - sec_right;
+ if (index_left < index_right)
+ return -1;
+ else if (index_left > index_right)
+ return 1;
cmp = strcmp (lsource->sec, rsource->sec);
if (cmp)
@@ -3086,8 +3036,8 @@ static int try_section (const char *path, const char *sec, const char *name,
struct candidate **cand_head)
{
int found = 0;
- char **names = NULL, **np;
- size_t names_len = 0;
+ gl_list_t names = NULL;
+ const char *found_name;
char cat = 0;
int lff_opts = (match_case ? LFF_MATCHCASE : 0) |
(regex_opt ? LFF_REGEX : 0) |
@@ -3101,7 +3051,7 @@ static int try_section (const char *path, const char *sec, const char *name,
*/
names = look_for_file (path, sec, name, 0, lff_opts);
- if (!names)
+ if (!gl_list_size (names))
/*
* No files match.
* See if there's a preformatted page around that
@@ -3113,18 +3063,17 @@ static int try_section (const char *path, const char *sec, const char *name,
return 1;
if (!troff && !want_encoding && !recode) {
+ gl_list_free (names);
names = look_for_file (path, sec, name, 1, lff_opts);
cat = 1;
}
}
- for (np = names; np && *np; np++)
- ++names_len;
- order_files (path, names, names_len);
+ order_files (path, &names);
- for (np = names; np && *np; np++) {
+ GL_LIST_FOREACH_START (names, found_name) {
struct mandata *info = infoalloc ();
- char *info_buffer = filename_info (*np, info, name);
+ char *info_buffer = filename_info (found_name, info, name);
const char *ult;
int f;
@@ -3138,16 +3087,16 @@ static int try_section (const char *path, const char *sec, const char *name,
* must be either ULT_MAN or SO_MAN. ult_src() can tell us
* which.
*/
- ult = ult_src (*np, path, NULL, ult_flags, NULL);
+ ult = ult_src (found_name, path, NULL, ult_flags, NULL);
if (!ult) {
/* already warned */
- debug ("try_section(): bad link %s\n", *np);
+ debug ("try_section(): bad link %s\n", found_name);
free (info_buffer);
info->addr = NULL;
free_mandata_struct (info);
continue;
}
- if (STREQ (ult, *np))
+ if (STREQ (ult, found_name))
info->id = ULT_MAN;
else
info->id = SO_MAN;
@@ -3164,8 +3113,9 @@ static int try_section (const char *path, const char *sec, const char *name,
free_mandata_struct (info);
}
/* Don't free info and info_buffer here. */
- }
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
return found;
}
@@ -3355,11 +3305,6 @@ static int display_database_check (struct candidate *candp)
return exists;
}
-static void db_hashtable_free (void *defn)
-{
- free_mandata_struct (defn);
-}
-
#ifdef MAN_DB_UPDATES
static int maybe_update_file (const char *manpath, const char *name,
struct mandata *info)
@@ -3418,16 +3363,26 @@ static int maybe_update_file (const char *manpath, const char *name,
#define TRY_DATABASE_UPDATED -3
#endif /* MAN_DB_UPDATES */
+static void db_map_value_free (const void *value)
+{
+ /* The value may be NULL to indicate that opening the database at
+ * this location already failed.
+ */
+ if (value)
+ gl_list_free ((gl_list_t) value);
+}
+
/* Look for a page in the database. If db not accessible, return -1,
otherwise return number of pages found. */
static int try_db (const char *manpath, const char *sec, const char *name,
struct candidate **cand_head)
{
- struct mandata *loc, *data;
+ gl_list_t matches;
+ struct mandata *loc;
char *catpath;
int found = 0;
#ifdef MAN_DB_UPDATES
- int found_stale = 0;
+ bool found_stale = false;
#endif /* MAN_DB_UPDATES */
/* find out where our db for this manpath should be */
@@ -3440,13 +3395,11 @@ static int try_db (const char *manpath, const char *sec, const char *name,
} else
database = mkdbname (manpath);
- if (!db_hash)
- db_hash = hashtable_create (&db_hashtable_free);
+ if (!db_map)
+ db_map = new_string_map (GL_HASH_MAP, db_map_value_free);
- /* Have we looked here already? */
- data = hashtable_lookup (db_hash, manpath, strlen (manpath));
-
- if (!data) {
+ /* If we haven't looked here already, do so now. */
+ if (!gl_map_search (db_map, manpath, (const void **) &matches)) {
MYDBM_FILE dbf;
dbf = MYDBM_RDOPEN (database);
@@ -3460,14 +3413,13 @@ static int try_db (const char *manpath, const char *sec, const char *name,
/* if section is set, only return those that match,
otherwise NULL retrieves all available */
if (regex_opt || wildcard)
- data = dblookup_pattern
+ matches = dblookup_pattern
(dbf, name, section, match_case,
regex_opt, !names_only);
else
- data = dblookup_all (dbf, name, section,
- match_case);
- hashtable_install (db_hash, manpath, strlen (manpath),
- data);
+ matches = dblookup_all (dbf, name, section,
+ match_case);
+ gl_map_put (db_map, xstrdup (manpath), matches);
MYDBM_CLOSE (dbf);
dbf = NULL;
#ifdef MAN_DB_CREATES
@@ -3475,60 +3427,50 @@ static int try_db (const char *manpath, const char *sec, const char *name,
/* create one */
debug ("Failed to open %s O_RDONLY\n", database);
if (run_mandb (1, manpath, NULL)) {
- data = infoalloc ();
- data->next = NULL;
- data->addr = NULL;
- hashtable_install (db_hash,
- manpath, strlen (manpath),
- data);
+ gl_map_put (db_map, xstrdup (manpath), NULL);
return TRY_DATABASE_OPEN_FAILED;
}
return TRY_DATABASE_CREATED;
#endif /* MAN_DB_CREATES */
} else {
debug ("Failed to open %s O_RDONLY\n", database);
- data = infoalloc ();
- data->next = (struct mandata *) NULL;
- data->addr = NULL;
- hashtable_install (db_hash, manpath, strlen (manpath),
- data);
+ gl_map_put (db_map, xstrdup (manpath), NULL);
return TRY_DATABASE_OPEN_FAILED;
}
+ assert (matches != NULL);
}
- /* if we already know that there is nothing here, get on with it */
- if (!data)
- return 0;
-
- /* We already tried (and failed) to open this db before */
- if (!data->addr)
+ /* We already tried (and failed) to open this db before. */
+ if (!matches)
return TRY_DATABASE_OPEN_FAILED;
#ifdef MAN_DB_UPDATES
/* Check that all the entries found are up to date. If not, the
* caller should try again.
*/
- for (loc = data; loc; loc = loc->next)
+ GL_LIST_FOREACH_START (matches, loc)
if (STREQ (sec, loc->sec) &&
(!extension || STREQ (extension, loc->ext)
|| STREQ (extension, loc->ext + strlen (sec))))
if (maybe_update_file (manpath, name, loc))
- found_stale = 1;
+ found_stale = true;
+ GL_LIST_FOREACH_END (matches);
if (found_stale) {
- hashtable_remove (db_hash, manpath, strlen (manpath));
+ gl_map_remove (db_map, manpath);
return TRY_DATABASE_UPDATED;
}
#endif /* MAN_DB_UPDATES */
/* cycle through the mandata structures (there's usually only
1 or 2) and see what we have w.r.t. the current section */
- for (loc = data; loc; loc = loc->next)
+ GL_LIST_FOREACH_START (matches, loc)
if (STREQ (sec, loc->sec) &&
(!extension || STREQ (extension, loc->ext)
|| STREQ (extension, loc->ext + strlen (sec))))
found += add_candidate (cand_head, CANDIDATE_DATABASE,
0, name, manpath, NULL, loc);
+ GL_LIST_FOREACH_END (matches);
return found;
}
@@ -3673,8 +3615,8 @@ static int do_global_apropos_section (const char *path, const char *sec,
const char *name)
{
int found = 0;
- char **names, **np;
- size_t names_len = 0;
+ gl_list_t names;
+ const char *found_name;
regex_t search;
global_manpath = is_global_mandir (path);
@@ -3684,6 +3626,7 @@ static int do_global_apropos_section (const char *path, const char *sec,
debug ("searching in %s, section %s\n", path, sec);
names = look_for_file (path, sec, "*", 0, LFF_WILDCARD);
+
if (regex_opt)
xregcomp (&search, name,
REG_EXTENDED | REG_NOSUB |
@@ -3691,33 +3634,31 @@ static int do_global_apropos_section (const char *path, const char *sec,
else
memset (&search, 0, sizeof search);
- for (np = names; np && *np; ++np)
- ++names_len;
- order_files (path, names, names_len);
+ order_files (path, &names);
- for (np = names; np && *np; ++np) {
+ GL_LIST_FOREACH_START (names, found_name) {
struct mandata *info;
char *info_buffer;
char *title = NULL;
const char *man_file;
char *cat_file = NULL;
- if (!grep (*np, name, &search))
+ if (!grep (found_name, name, &search))
continue;
info = infoalloc ();
- info_buffer = filename_info (*np, info, NULL);
+ info_buffer = filename_info (found_name, info, NULL);
if (!info_buffer)
goto next;
info->addr = info_buffer;
title = xasprintf ("%s(%s)", strchr (info_buffer, '\0') + 1,
info->ext);
- man_file = ult_src (*np, path, NULL, ult_flags, NULL);
+ man_file = ult_src (found_name, path, NULL, ult_flags, NULL);
if (!man_file)
goto next;
lang = lang_dir (man_file);
- cat_file = find_cat_file (path, *np, man_file);
+ cat_file = find_cat_file (path, found_name, man_file);
if (display (path, man_file, cat_file, title, NULL))
found = 1;
free (lang);
@@ -3727,7 +3668,9 @@ next:
free (cat_file);
free (title);
free_mandata_struct (info);
- }
+ } GL_LIST_FOREACH_END (names);
+
+ gl_list_free (names);
if (regex_opt)
regfree (&search);
@@ -3740,23 +3683,26 @@ next:
static int do_global_apropos (const char *name, int *found)
{
- const char **my_section_list;
- const char **sp;
- char **mp;
+ gl_list_t my_section_list;
+ const char *sec;
if (section) {
- my_section_list = XNMALLOC (2, const char *);
- my_section_list[0] = section;
- my_section_list[1] = NULL;
+ my_section_list = gl_list_create_empty (GL_ARRAY_LIST, NULL,
+ NULL, NULL, false);
+ gl_list_add_last (my_section_list, section);
} else
my_section_list = section_list;
- for (sp = my_section_list; *sp; sp++)
- for (mp = manpathlist; *mp; mp++)
- *found += do_global_apropos_section (*mp, *sp, name);
+ GL_LIST_FOREACH_START (my_section_list, sec) {
+ char *mp;
+
+ GL_LIST_FOREACH_START (manpathlist, mp)
+ *found += do_global_apropos_section (mp, sec, name);
+ GL_LIST_FOREACH_END (manpathlist);
+ } GL_LIST_FOREACH_END (my_section_list);
if (section)
- free (my_section_list);
+ gl_list_free (my_section_list);
return *found ? OK : NOT_FOUND;
}
@@ -3768,10 +3714,10 @@ static int man (const char *name, int *found);
static int local_man_loop (const char *argv)
{
int exit_status = OK;
- int local_mf = local_man_file;
+ bool local_mf = local_man_file;
drop_effective_privs ();
- local_man_file = 1;
+ local_man_file = true;
if (strcmp (argv, "-") == 0)
display (NULL, "", NULL, "(stdin)", NULL);
else {
@@ -3806,7 +3752,7 @@ static int local_man_loop (const char *argv)
if (directory_on_path (argv_dir)) {
char *argv_base = base_name (argv);
char *new_manp, *nm;
- char **old_manpathlist, **mp;
+ gl_list_t old_manpathlist;
debug ("recalculating manpath for executable "
"in %s\n", argv_dir);
@@ -3821,18 +3767,13 @@ static int local_man_loop (const char *argv)
free (new_manp);
new_manp = nm;
- old_manpathlist = XNMALLOC (MAXDIRS, char *);
- memcpy (old_manpathlist, manpathlist,
- MAXDIRS * sizeof (*manpathlist));
- create_pathlist (new_manp, manpathlist);
+ old_manpathlist = manpathlist;
+ manpathlist = create_pathlist (new_manp);
man (argv_base, &found);
- for (mp = manpathlist; *mp; ++mp)
- free (*mp);
- memcpy (manpathlist, old_manpathlist,
- MAXDIRS * sizeof (*manpathlist));
- free (old_manpathlist);
+ free_pathlist (manpathlist);
+ manpathlist = old_manpathlist;
executable_out:
free (new_manp);
free (argv_base);
@@ -3901,10 +3842,12 @@ static void locate_page_in_manpath (const char *page_section,
struct candidate **candidates,
int *found)
{
- char **mp;
+ char *mp;
- for (mp = manpathlist; *mp; mp++)
- *found += locate_page (*mp, page_section, page_name, candidates);
+ GL_LIST_FOREACH_START (manpathlist, mp)
+ *found += locate_page (mp, page_section, page_name,
+ candidates);
+ GL_LIST_FOREACH_END (manpathlist);
}
/*
@@ -3939,11 +3882,11 @@ static int man (const char *name, int *found)
if (section)
locate_page_in_manpath (section, name, &candidates, found);
else {
- const char **sp;
+ const char *sec;
- for (sp = section_list; *sp; sp++) {
- locate_page_in_manpath (*sp, name, &candidates, found);
- }
+ GL_LIST_FOREACH_START (section_list, sec)
+ locate_page_in_manpath (sec, name, &candidates, found);
+ GL_LIST_FOREACH_END (section_list);
}
split_page_name (name, &page_name, &page_section);
@@ -3969,20 +3912,20 @@ static int man (const char *name, int *found)
}
-static const char **get_section_list (void)
+static gl_list_t get_section_list (void)
{
- int i = 0;
- const char **config_sections;
- const char **sections = NULL;
+ gl_list_t config_sections, sections;
const char *sec;
/* Section list from configuration file, or STD_SECTIONS if it's
* empty.
*/
config_sections = get_sections ();
- if (!*config_sections) {
- free (config_sections);
- config_sections = std_sections;
+ if (!gl_list_size (config_sections)) {
+ int i;
+ for (i = 0; std_sections[i]; ++i)
+ gl_list_add_last (config_sections,
+ xstrdup (std_sections[i]));
}
if (colon_sep_section_list == NULL)
@@ -3994,17 +3937,16 @@ static const char **get_section_list (void)
* man's -s option takes a comma-separated list, so we accept that
* too for compatibility.
*/
+ sections = new_string_list (GL_ARRAY_LIST, true);
for (sec = strtok (colon_sep_section_list, ":,"); sec;
- sec = strtok (NULL, ":,")) {
- sections = xnrealloc (sections, i + 2, sizeof *sections);
- sections[i++] = sec;
- }
+ sec = strtok (NULL, ":,"))
+ gl_list_add_last (sections, xstrdup (sec));
- if (i > 0) {
- sections[i] = NULL;
+ if (gl_list_size (sections)) {
+ gl_list_free (config_sections);
return sections;
} else {
- free (sections);
+ gl_list_free (sections);
return config_sections;
}
}
@@ -4086,8 +4028,6 @@ int main (int argc, char *argv[])
set_program_name (argv[0]);
- check_standard_fds ();
-
init_debug ();
pipeline_install_post_fork (pop_all_cleanups);
sandbox = sandbox_init ();
@@ -4103,6 +4043,8 @@ int main (int argc, char *argv[])
multiple_locale = getenv ("LANGUAGE");
internal_locale = xstrdup (internal_locale ? internal_locale : "C");
+ xstdopen ();
+
/* export argv, it might be needed when invoking the vendor supplied browser */
#if defined _AIX || defined __sgi
global_argv = argv;
@@ -4114,6 +4056,10 @@ int main (int argc, char *argv[])
init_html_pager ();
#endif /* TROFF_IS_GROFF */
+#ifdef NROFF_WARNINGS
+ roff_warnings = new_string_list (GL_ARRAY_LIST, true);
+#endif /* NROFF_WARNINGS */
+
/* First of all, find out if $MANOPT is set. If so, put it in
*argv[] format for argp to play with. */
argv_env = manopt_to_env (&argc_env);
@@ -4226,7 +4172,7 @@ int main (int argc, char *argv[])
debug ("manpath search path (with duplicates) = %s\n", manp);
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
/* man issued with `-l' option */
if (local_man_file) {
@@ -4288,14 +4234,14 @@ int main (int argc, char *argv[])
if (global_apropos)
status = do_global_apropos (nextarg, &found);
else {
- int found_subpage = 0;
+ bool found_subpage = false;
if (subpages && first_arg < argc) {
char *subname = xasprintf (
"%s-%s", nextarg, argv[first_arg]);
status = man (subname, &found);
free (subname);
if (status == OK) {
- found_subpage = 1;
+ found_subpage = true;
++first_arg;
}
}
@@ -4305,7 +4251,7 @@ int main (int argc, char *argv[])
status = man (subname, &found);
free (subname);
if (status == OK) {
- found_subpage = 1;
+ found_subpage = true;
++first_arg;
}
}
@@ -4314,15 +4260,17 @@ int main (int argc, char *argv[])
}
/* clean out the cache of database lookups for each man page */
- hashtable_free (db_hash);
- db_hash = NULL;
+ if (db_map) {
+ gl_map_free (db_map);
+ db_map = NULL;
+ }
if (section && maybe_section) {
if (status != OK && !catman) {
/* Maybe the section wasn't a section after
* all? e.g. 'man 9wm fvwm'.
*/
- int found_subpage = 0;
+ bool found_subpage = false;
debug ("\nRetrying section %s as name\n",
section);
tmp = section;
@@ -4333,14 +4281,16 @@ int main (int argc, char *argv[])
status = man (subname, &found);
free (subname);
if (status == OK) {
- found_subpage = 1;
+ found_subpage = true;
++first_arg;
}
}
if (!found_subpage)
status = man (tmp, &found);
- hashtable_free (db_hash);
- db_hash = NULL;
+ if (db_map) {
+ gl_map_free (db_map);
+ db_map = NULL;
+ }
/* ... but don't gripe about it if it doesn't
* work!
*/
@@ -4385,13 +4335,17 @@ int main (int argc, char *argv[])
chkr_garbage_detector ();
}
- hashtable_free (db_hash);
- db_hash = NULL;
+ if (db_map) {
+ gl_map_free (db_map);
+ db_map = NULL;
+ }
drop_effective_privs ();
free (database);
+ gl_list_free (section_list);
free_pathlist (manpathlist);
free (internal_locale);
+ sandbox_free (sandbox);
exit (exit_status);
}
diff --git a/src/manconv_main.c b/src/manconv_main.c
index 75c08ab0..949c6b6f 100644
--- a/src/manconv_main.c
+++ b/src/manconv_main.c
@@ -24,6 +24,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -111,7 +112,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
(void *) 0);
return 0;
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'q':
quiet = 1;
@@ -178,5 +179,7 @@ int main (int argc, char *argv[])
pipeline_wait (p);
+ sandbox_free (sandbox);
+
return 0;
}
diff --git a/src/mandb.c b/src/mandb.c
index 90325d91..0a06c714 100644
--- a/src/mandb.c
+++ b/src/mandb.c
@@ -30,6 +30,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -48,6 +49,9 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_hash_map.h"
+#include "gl_list.h"
+#include "gl_xmap.h"
#include "progname.h"
#include "stat-time.h"
#include "timespec.h"
@@ -63,7 +67,7 @@
#include "error.h"
#include "cleanup.h"
-#include "hashtable.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "sandbox.h"
#include "security.h"
@@ -75,11 +79,11 @@
#include "manp.h"
int quiet = 1;
-extern int opt_test; /* don't update db */
+extern bool opt_test; /* don't update db */
char *manp;
char *database = NULL;
extern char *extension; /* for globbing.c */
-extern int force_rescan; /* for check_mandirs.c */
+extern bool force_rescan; /* for check_mandirs.c */
static char *single_filename = NULL;
extern char *user_config_file; /* for manp.c */
#ifdef MAN_OWNER
@@ -90,10 +94,10 @@ man_sandbox *sandbox;
static int purged = 0;
static int strays = 0;
-static int check_for_strays = 1;
-static int purge = 1;
-static int user;
-static int create;
+static bool check_for_strays = true;
+static bool purge = true;
+static bool user;
+static bool create;
static const char *arg_manp;
struct tried_catdirs_entry {
@@ -127,32 +131,32 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'q':
++quiet_temp;
return 0;
case 's':
- check_for_strays = 0;
+ check_for_strays = false;
return 0;
case 'p':
- purge = 0;
+ purge = false;
return 0;
case 'u':
- user = 1;
+ user = true;
return 0;
case 'c':
- create = 1;
- purge = 0;
+ create = true;
+ purge = false;
return 0;
case 't':
- opt_test = 1;
+ opt_test = true;
return 0;
case 'f':
single_filename = arg;
- create = 0;
- purge = 0;
- check_for_strays = 0;
+ create = false;
+ purge = false;
+ check_for_strays = false;
return 0;
case 'C':
user_config_file = arg;
@@ -202,7 +206,7 @@ extern uid_t ruid;
extern uid_t euid;
#endif /* MAN_OWNER */
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
extern int pages;
@@ -437,7 +441,8 @@ static void cleanup (void *arg)
/* sort out the database names */
static int mandb (struct dbpaths *dbpaths,
- const char *catpath, const char *manpath, int global_manpath)
+ const char *catpath, const char *manpath,
+ bool global_manpath)
{
int ret, amount;
char *dbname;
@@ -551,8 +556,8 @@ static int mandb (struct dbpaths *dbpaths,
return amount;
}
-static int process_manpath (const char *manpath, int global_manpath,
- struct hashtable *tried_catdirs)
+static int process_manpath (const char *manpath, bool global_manpath,
+ gl_map_t tried_catdirs)
{
char *catpath;
struct tried_catdirs_entry *tried;
@@ -572,7 +577,7 @@ static int process_manpath (const char *manpath, int global_manpath,
tried = XMALLOC (struct tried_catdirs_entry);
tried->manpath = xstrdup (manpath);
tried->seen = 0;
- hashtable_install (tried_catdirs, catpath, strlen (catpath), tried);
+ gl_map_put (tried_catdirs, xstrdup (catpath), tried);
if (stat (manpath, &st) < 0 || !S_ISDIR (st.st_mode))
goto out;
@@ -590,7 +595,7 @@ static int process_manpath (const char *manpath, int global_manpath,
} else
run_mandb = 1;
- force_rescan = 0;
+ force_rescan = false;
if (purge) {
database = mkdbname (catpath);
purged += purge_missing (manpath, catpath, run_mandb);
@@ -648,21 +653,21 @@ static int is_lang_dir (const char *base)
(!base[2] || base[2] < 'a' || base[2] > 'z');
}
-static void tried_catdirs_free (void *defn)
+static void tried_catdirs_free (const void *value)
{
- struct tried_catdirs_entry *tried = defn;
+ struct tried_catdirs_entry *tried =
+ (struct tried_catdirs_entry *) value;
free (tried->manpath);
free (tried);
}
-static void purge_catdir (const struct hashtable *tried_catdirs,
- const char *path)
+static void purge_catdir (gl_map_t tried_catdirs, const char *path)
{
struct stat st;
if (stat (path, &st) == 0 && S_ISDIR (st.st_mode) &&
- !hashtable_lookup (tried_catdirs, path, strlen (path))) {
+ !gl_map_get (tried_catdirs, path)) {
if (!quiet)
printf (_("Removing obsolete cat directory %s...\n"),
path);
@@ -714,14 +719,12 @@ static void purge_catsubdirs (const char *manpath, const char *catpath)
* the usual NLS pattern (two lower-case letters followed by nothing or a
* non-letter).
*/
-static void purge_catdirs (const struct hashtable *tried_catdirs)
+static void purge_catdirs (gl_map_t tried_catdirs)
{
- struct hashtable_iter *iter = NULL;
- const struct nlist *elt;
+ const char *path;
+ struct tried_catdirs_entry *tried;
- while ((elt = hashtable_iterate (tried_catdirs, &iter)) != NULL) {
- const char *path = elt->name;
- struct tried_catdirs_entry *tried = elt->defn;
+ GL_MAP_FOREACH_START (tried_catdirs, path, tried) {
char *base;
DIR *dir;
struct dirent *subdirent;
@@ -741,6 +744,7 @@ static void purge_catdirs (const struct hashtable *tried_catdirs)
continue;
while ((subdirent = readdir (dir)) != NULL) {
char *subdirpath;
+ const struct tried_catdirs_entry *subtried;
if (STREQ (subdirent->d_name, ".") ||
STREQ (subdirent->d_name, ".."))
@@ -753,30 +757,30 @@ static void purge_catdirs (const struct hashtable *tried_catdirs)
subdirpath = xasprintf ("%s/%s", path,
subdirent->d_name);
- tried = hashtable_lookup (tried_catdirs, subdirpath,
- strlen (subdirpath));
- if (tried && tried->seen) {
+ subtried = gl_map_get (tried_catdirs, subdirpath);
+ if (subtried && subtried->seen) {
debug ("Seen mandir for %s; not deleting\n",
subdirpath);
/* However, we may still need to purge cat*
* subdirectories.
*/
- purge_catsubdirs (tried->manpath, subdirpath);
+ purge_catsubdirs (subtried->manpath,
+ subdirpath);
} else
purge_catdir (tried_catdirs, subdirpath);
free (subdirpath);
}
closedir (dir);
- }
+ } GL_MAP_FOREACH_END (tried_catdirs);
}
int main (int argc, char *argv[])
{
char *sys_manp;
int amount = 0;
- char **mp;
- struct hashtable *tried_catdirs;
+ char *mp;
+ gl_map_t tried_catdirs;
#ifdef SIGPIPE
struct sigaction sa;
#endif /* SIGPIPE */
@@ -822,7 +826,7 @@ int main (int argc, char *argv[])
#ifdef MAN_OWNER
man_owner = get_man_owner ();
if (!user && euid != 0 && euid != man_owner->pw_uid)
- user = 1;
+ user = true;
#endif /* MAN_OWNER */
read_config_file (user);
@@ -848,16 +852,16 @@ int main (int argc, char *argv[])
debug ("manpath=%s\n", manp);
- /* get the manpath as an array of pointers */
- create_pathlist (manp, manpathlist);
+ /* get the manpath as a list of pointers */
+ manpathlist = create_pathlist (manp);
/* finished manpath processing, regain privs */
regain_effective_privs ();
- tried_catdirs = hashtable_create (tried_catdirs_free);
+ tried_catdirs = new_string_map (GL_HASH_MAP, tried_catdirs_free);
- for (mp = manpathlist; *mp; mp++) {
- int global_manpath = is_global_mandir (*mp);
+ GL_LIST_FOREACH_START (manpathlist, mp) {
+ bool global_manpath = is_global_mandir (mp);
int ret;
DIR *dir;
struct dirent *subdirent;
@@ -869,14 +873,14 @@ int main (int argc, char *argv[])
drop_effective_privs ();
}
- ret = process_manpath (*mp, global_manpath, tried_catdirs);
+ ret = process_manpath (mp, global_manpath, tried_catdirs);
if (ret < 0)
exit (FATAL);
amount += ret;
- dir = opendir (*mp);
+ dir = opendir (mp);
if (!dir) {
- error (0, errno, _("can't search directory %s"), *mp);
+ error (0, errno, _("can't search directory %s"), mp);
goto next_manpath;
}
@@ -890,7 +894,7 @@ int main (int argc, char *argv[])
if (STRNEQ (subdirent->d_name, "man", 3))
continue;
- subdirpath = xasprintf ("%s/%s", *mp,
+ subdirpath = xasprintf ("%s/%s", mp,
subdirent->d_name);
ret = process_manpath (subdirpath, global_manpath,
tried_catdirs);
@@ -907,10 +911,10 @@ next_manpath:
regain_effective_privs ();
chkr_garbage_detector ();
- }
+ } GL_LIST_FOREACH_END (manpathlist);
purge_catdirs (tried_catdirs);
- hashtable_free (tried_catdirs);
+ gl_map_free (tried_catdirs);
if (!quiet) {
printf (ngettext ("%d man subdirectory contained newer "
@@ -950,5 +954,6 @@ next_manpath:
if (must_create && STREQ (must_create, "1"))
exit (FAIL);
}
+ sandbox_free (sandbox);
exit (OK);
}
diff --git a/src/manp.c b/src/manp.c
index 5111be77..1dfecf38 100644
--- a/src/manp.c
+++ b/src/manp.c
@@ -47,6 +47,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
@@ -54,11 +55,15 @@
#include <assert.h>
#include <errno.h>
#include <dirent.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "canonicalize.h"
+#include "gl_array_list.h"
+#include "gl_linkedhash_list.h"
+#include "gl_xlist.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
@@ -69,77 +74,76 @@
#include "error.h"
#include "cleanup.h"
+#include "glcontainers.h"
#include "security.h"
#include "manp.h"
#include "globbing.h"
-struct list {
+enum config_flag {
+ MANDATORY,
+ MANPATH_MAP,
+ MANDB_MAP,
+ MANDB_MAP_USER,
+ DEFINE,
+ DEFINE_USER,
+ SECTION,
+ SECTION_USER
+};
+
+struct config_item {
char *key;
char *cont;
- int flag;
- struct list *next;
+ enum config_flag flag;
};
-static struct list *namestore, *tailstore;
-
-#define SECTION_USER -6
-#define SECTION -5
-#define DEFINE_USER -4
-#define DEFINE -3
-#define MANDB_MAP_USER -2
-#define MANDB_MAP -1
-#define MANPATH_MAP 0
-#define MANDATORY 1
-
-/* DIRLIST list[MAXDIRS]; */
-static char *tmplist[MAXDIRS];
+static gl_list_t config;
char *user_config_file = NULL;
-int disable_cache;
+bool disable_cache;
int min_cat_width = 80, max_cat_width = 80, cat_width = 0;
-static char *has_mandir (const char *p);
+static void add_man_subdirs (gl_list_t list, const char *p);
static char *fsstnd (const char *path);
-static char *def_path (int flag);
-static void add_dir_to_list (char **lp, const char *dir);
-static char **add_dir_to_path_list (char **mphead, char **mp, const char *p);
+static char *def_path (enum config_flag flag);
+static void add_dir_to_list (gl_list_t list, const char *dir);
+static void add_dir_to_path_list (gl_list_t list, const char *p);
-static void add_to_list (const char *key, const char *cont, int flag)
+static void config_item_free (const void *elt)
{
- struct list *list = XMALLOC (struct list);
- list->key = xstrdup (key);
- list->cont = xstrdup (cont);
- list->flag = flag;
- list->next = NULL;
- if (tailstore)
- tailstore->next = list;
- tailstore = list;
- if (!namestore)
- namestore = list;
+ /* gl_list declares the argument as const, but there doesn't seem to
+ * be a good reason for this.
+ */
+ struct config_item *item = (struct config_item *) elt;
+ free (item->key);
+ free (item->cont);
+ free (item);
}
-static const char *get_from_list (const char *key, int flag)
+static void add_config (const char *key, const char *cont,
+ enum config_flag flag)
{
- struct list *list;
-
- for (list = namestore; list; list = list->next)
- if (flag == list->flag && STREQ (key, list->key))
- return list->cont;
-
- return NULL;
+ struct config_item *item = XMALLOC (struct config_item);
+ item->key = xstrdup (key);
+ item->cont = xstrdup (cont);
+ item->flag = flag;
+ gl_list_add_last (config, item);
}
-static struct list *iterate_over_list (struct list *prev, char *key, int flag)
+static const char *get_config (const char *key, enum config_flag flag)
{
- struct list *list;
+ const struct config_item *item;
+ char *cont = NULL;
- for (list = prev ? prev->next : namestore; list; list = list->next)
- if (flag == list->flag && STREQ (key, list->key))
- return list;
+ GL_LIST_FOREACH_START (config, item)
+ if (flag == item->flag && STREQ (key, item->key)) {
+ cont = item->cont;
+ break;
+ }
+ GL_LIST_FOREACH_END (config);
- return NULL;
+ return cont;
}
/* Must not return DEFINEs set in ~/.manpath. This is used to fetch
@@ -154,25 +158,52 @@ const char *get_def (const char *thing, const char *def)
if (!running_setuid ())
return get_def_user (thing, def);
- config_def = get_from_list (thing, DEFINE);
+ config_def = get_config (thing, DEFINE);
return config_def ? config_def : def;
}
const char *get_def_user (const char *thing, const char *def)
{
- const char *config_def = get_from_list (thing, DEFINE_USER);
+ const char *config_def = get_config (thing, DEFINE_USER);
if (!config_def)
- config_def = get_from_list (thing, DEFINE);
+ config_def = get_config (thing, DEFINE);
return config_def ? config_def : def;
}
+static const char *describe_flag (enum config_flag flag)
+{
+ switch (flag) {
+ case MANDATORY:
+ return "MANDATORY";
+ case MANPATH_MAP:
+ return "MANPATH_MAP";
+ case MANDB_MAP:
+ return "MANDB_MAP";
+ case MANDB_MAP_USER:
+ return "MANDB_MAP_USER";
+ case DEFINE:
+ return "DEFINE";
+ case DEFINE_USER:
+ return "DEFINE_USER";
+ case SECTION:
+ return "SECTION";
+ case SECTION_USER:
+ return "SECTION_USER";
+ default:
+ error (FATAL, 0, "impossible config_flag value %d",
+ flag);
+ abort (); /* error should have exited */
+ }
+}
+
static void print_list (void)
{
- struct list *list;
+ const struct config_item *item;
- for (list = namestore; list; list = list->next)
- debug ("`%s'\t`%s'\t`%d'\n",
- list->key, list->cont, list->flag);
+ GL_LIST_FOREACH_START (config, item)
+ debug ("`%s'\t`%s'\t`%s'\n",
+ item->key, item->cont, describe_flag (item->flag));
+ GL_LIST_FOREACH_END (config);
}
static void add_sections (char *sections, int user)
@@ -182,44 +213,40 @@ static void add_sections (char *sections, int user)
for (sect = strtok (section_list, " "); sect;
sect = strtok (NULL, " ")) {
- add_to_list (sect, "", user ? SECTION_USER : SECTION);
+ add_config (sect, "", user ? SECTION_USER : SECTION);
debug ("Added section `%s'.\n", sect);
}
free (section_list);
}
-const char **get_sections (void)
+gl_list_t get_sections (void)
{
- struct list *list;
+ const struct config_item *item;
int length_user = 0, length = 0;
- const char **sections, **sectionp;
- int flag;
+ gl_list_t sections;
+ enum config_flag flag;
- for (list = namestore; list; list = list->next) {
- if (list->flag == SECTION_USER)
+ GL_LIST_FOREACH_START (config, item) {
+ if (item->flag == SECTION_USER)
length_user++;
- else if (list->flag == SECTION)
+ else if (item->flag == SECTION)
length++;
- }
- if (length_user) {
- sections = xnmalloc (length_user + 1, sizeof *sections);
+ } GL_LIST_FOREACH_END (config);
+ sections = new_string_list (GL_ARRAY_LIST, true);
+ if (length_user)
flag = SECTION_USER;
- } else {
- sections = xnmalloc (length + 1, sizeof *sections);
+ else
flag = SECTION;
- }
- sectionp = sections;
- for (list = namestore; list; list = list->next)
- if (list->flag == flag)
- *sectionp++ = list->key;
- *sectionp = NULL;
+ GL_LIST_FOREACH_START (config, item)
+ if (item->flag == flag)
+ gl_list_add_last (sections, xstrdup (item->key));
+ GL_LIST_FOREACH_END (config);
return sections;
}
-static void add_def (char *thing, char *config_def, int flag, int user)
+static void add_def (const char *thing, const char *config_def, int user)
{
- add_to_list (thing, flag == 2 ? config_def : "",
- user ? DEFINE_USER : DEFINE);
+ add_config (thing, config_def, user ? DEFINE_USER : DEFINE);
debug ("Defined `%s' as `%s'.\n", thing, config_def);
}
@@ -229,24 +256,19 @@ static void add_manpath_map (const char *path, const char *mandir)
if (!path || !mandir)
return;
- add_to_list (path, mandir, MANPATH_MAP);
+ add_config (path, mandir, MANPATH_MAP);
debug ("Path `%s' mapped to mandir `%s'.\n", path, mandir);
}
-static void add_mandb_map (const char *mandir, const char *catdir,
- int flag, int user)
+static void add_mandb_map (const char *mandir, const char *catdir, int user)
{
char *tmpcatdir;
- assert (flag > 0);
-
if (!mandir)
return;
- if (flag == 1)
- tmpcatdir = xstrdup (mandir);
- else if (STREQ (catdir, "FSSTND"))
+ if (STREQ (catdir, "FSSTND"))
tmpcatdir = fsstnd (mandir);
else
tmpcatdir = xstrdup (catdir);
@@ -254,7 +276,7 @@ static void add_mandb_map (const char *mandir, const char *catdir,
if (!tmpcatdir)
return;
- add_to_list (mandir, tmpcatdir, user ? MANDB_MAP_USER : MANDB_MAP);
+ add_config (mandir, tmpcatdir, user ? MANDB_MAP_USER : MANDB_MAP);
debug ("%s mandir `%s', catdir `%s'.\n",
user ? "User" : "Global", mandir, tmpcatdir);
@@ -267,7 +289,7 @@ static void add_mandatory (const char *mandir)
if (!mandir)
return;
- add_to_list (mandir, "", MANDATORY);
+ add_config (mandir, "", MANDATORY);
debug ("Mandatory mandir `%s'.\n", mandir);
}
@@ -339,11 +361,6 @@ static void gripe_not_directory (const char *dir)
error (0, 0, _("warning: %s isn't a directory"), dir);
}
-static void gripe_overlong_list (void)
-{
- error (FAIL, 0, _("manpath list too long"));
-}
-
/* accept a manpath list, separated with ':', return the associated
catpath list */
char *cat_manpath (char *manp)
@@ -352,9 +369,9 @@ char *cat_manpath (char *manp)
const char *path, *catdir;
for (path = strsep (&manp, ":"); path; path = strsep (&manp, ":")) {
- catdir = get_from_list (path, MANDB_MAP_USER);
+ catdir = get_config (path, MANDB_MAP_USER);
if (!catdir)
- catdir = get_from_list (path, MANDB_MAP);
+ catdir = get_config (path, MANDB_MAP);
catp = catdir ? pathappend (catp, catdir)
: pathappend (catp, path);
}
@@ -697,7 +714,7 @@ char *get_manpath (const char *systems)
char *manpathlist;
/* need to read config file even if MANPATH set, for mandb(8) */
- read_config_file (0);
+ read_config_file (false);
manpathlist = getenv ("MANPATH");
if (manpathlist && *manpathlist) {
@@ -756,7 +773,7 @@ char *get_manpath (const char *systems)
}
/* Parse the manpath.config file, extracting appropriate information. */
-static void add_to_dirlist (FILE *config, int user)
+static void add_to_dirlist (FILE *config_file, int user)
{
char *bp;
char *buf = NULL;
@@ -765,7 +782,7 @@ static void add_to_dirlist (FILE *config, int user)
int val;
int c;
- while (getline (&buf, &n, config) >= 0) {
+ while (getline (&buf, &n, config_file) >= 0) {
bp = buf;
while (CTYPE (isspace, *bp))
@@ -778,7 +795,7 @@ static void add_to_dirlist (FILE *config, int user)
if (*bp == '#' || *bp == '\0')
goto next;
else if (strncmp (bp, "NOCACHE", 7) == 0)
- disable_cache = 1;
+ disable_cache = true;
else if (strncmp (bp, "NO", 2) == 0)
goto next; /* match any word starting with NO */
else if (sscanf (bp, "MANBIN %*s") == 1)
@@ -790,10 +807,10 @@ static void add_to_dirlist (FILE *config, int user)
add_manpath_map (key, cont);
else if ((c = sscanf (bp, "MANDB_MAP %511s %511s",
key, cont)) > 0)
- add_mandb_map (key, cont, c, user);
+ add_mandb_map (key, c == 2 ? cont : key, user);
else if ((c = sscanf (bp, "DEFINE %511s %511[^\n]",
key, cont)) > 0)
- add_def (key, cont, c, user);
+ add_def (key, c == 2 ? cont : "", user);
else if (sscanf (bp, "SECTION %511[^\n]", cont) == 1)
add_sections (cont, user);
else if (sscanf (bp, "SECTIONS %511[^\n]", cont) == 1)
@@ -820,28 +837,20 @@ next:
static void free_config_file (void *unused ATTRIBUTE_UNUSED)
{
- struct list *list = namestore, *prev;
-
- while (list) {
- free (list->key);
- free (list->cont);
- prev = list;
- list = list->next;
- free (prev);
- }
-
- namestore = tailstore = NULL;
+ gl_list_free (config);
}
-void read_config_file (int optional)
+void read_config_file (bool optional)
{
static int done = 0;
char *dotmanpath = NULL;
- FILE *config;
+ FILE *config_file;
if (done)
return;
+ config = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL,
+ config_item_free, true);
push_cleanup (free_config_file, NULL, 0);
if (user_config_file)
@@ -852,18 +861,18 @@ void read_config_file (int optional)
dotmanpath = xasprintf ("%s/.manpath", home);
}
if (dotmanpath) {
- config = fopen (dotmanpath, "r");
- if (config != NULL) {
+ config_file = fopen (dotmanpath, "r");
+ if (config_file != NULL) {
debug ("From the config file %s:\n\n", dotmanpath);
- add_to_dirlist (config, 1);
- fclose (config);
+ add_to_dirlist (config_file, 1);
+ fclose (config_file);
}
free (dotmanpath);
}
if (getenv ("MAN_TEST_DISABLE_SYSTEM_CONFIG") == NULL) {
- config = fopen (CONFIG_FILE, "r");
- if (config == NULL) {
+ config_file = fopen (CONFIG_FILE, "r");
+ if (config_file == NULL) {
if (optional)
debug ("can't open %s; continuing anyway\n",
CONFIG_FILE);
@@ -875,8 +884,8 @@ void read_config_file (int optional)
} else {
debug ("From the config file %s:\n\n", CONFIG_FILE);
- add_to_dirlist (config, 0);
- fclose (config);
+ add_to_dirlist (config_file, 0);
+ fclose (config_file);
}
}
@@ -890,34 +899,34 @@ void read_config_file (int optional)
* Construct the default manpath. This picks up mandatory manpaths
* only.
*/
-static char *def_path (int flag)
+static char *def_path (enum config_flag flag)
{
char *manpath = NULL;
- struct list *list;
+ const struct config_item *item;
- for (list = namestore; list; list = list->next)
- if (list->flag == flag) {
- char **expanded_dirs;
- int i;
+ GL_LIST_FOREACH_START (config, item)
+ if (item->flag == flag) {
+ gl_list_t expanded_dirs;
+ const char *expanded_dir;
- expanded_dirs = expand_path (list->key);
- for (i = 0; expanded_dirs[i]; i++) {
- int status = is_directory (expanded_dirs[i]);
+ expanded_dirs = expand_path (item->key);
+ GL_LIST_FOREACH_START (expanded_dirs, expanded_dir) {
+ int status = is_directory (expanded_dir);
if (status < 0)
- gripe_stat_file (expanded_dirs[i]);
+ gripe_stat_file (expanded_dir);
else if (status == 0 && !quiet)
error (0, 0,
_("warning: mandatory "
"directory %s doesn't exist"),
- expanded_dirs[i]);
+ expanded_dir);
else if (status == 1)
- manpath = pathappend
- (manpath, expanded_dirs[i]);
- free (expanded_dirs[i]);
- }
- free (expanded_dirs);
+ manpath = pathappend (manpath,
+ expanded_dir);
+ } GL_LIST_FOREACH_END (expanded_dirs);
+ gl_list_free (expanded_dirs);
}
+ GL_LIST_FOREACH_END (config);
/* If we have complete config file failure... */
if (!manpath)
@@ -928,9 +937,9 @@ static char *def_path (int flag)
/*
* If specified with configure, append OVERRIDE_DIR to dir param and add it
- * to the lp list.
+ * to list.
*/
-static void insert_override_dir (char **lp, const char *dir)
+static void insert_override_dir (gl_list_t list, const char *dir)
{
char *override_dir = NULL;
@@ -938,7 +947,7 @@ static void insert_override_dir (char **lp, const char *dir)
return;
if ((override_dir = xasprintf ("%s/%s", dir, OVERRIDE_DIR))) {
- add_dir_to_list (lp, override_dir);
+ add_dir_to_list (list, override_dir);
free (override_dir);
}
}
@@ -956,19 +965,20 @@ static void insert_override_dir (char **lp, const char *dir)
*/
char *get_manpath_from_path (const char *path, int mandatory)
{
+ gl_list_t tmplist;
+ const struct config_item *config_item;
int len;
char *tmppath;
- char *t;
char *p;
- char **lp;
char *end;
char *manpathlist;
- struct list *list;
+ char *item;
+ tmplist = new_string_list (GL_LINKEDHASH_LIST, false);
tmppath = xstrdup (path);
for (end = p = tmppath; end; p = end + 1) {
- struct list *mandir_list;
+ bool manpath_map_found = false;
end = strchr (p, ':');
if (end)
@@ -980,43 +990,28 @@ char *get_manpath_from_path (const char *path, int mandatory)
debug ("\npath directory %s ", p);
- mandir_list = iterate_over_list (NULL, p, MANPATH_MAP);
-
- /*
- * The directory we're working on is in the config file.
- * If we haven't added it to the list yet, do.
- */
-
- if (mandir_list) {
- debug ("is in the config file\n");
- while (mandir_list) {
- insert_override_dir (tmplist,
- mandir_list->cont);
- add_dir_to_list (tmplist, mandir_list->cont);
- mandir_list = iterate_over_list
- (mandir_list, p, MANPATH_MAP);
- }
-
- /* The directory we're working on isn't in the config file.
- See if it has ../man or man subdirectories.
- If so, and it hasn't been added to the list, do. */
-
- } else {
+ /* If the directory we're working on has MANPATH_MAP entries
+ * in the config file, add them to the list.
+ */
+ GL_LIST_FOREACH_START (config, config_item) {
+ if (MANPATH_MAP != config_item->flag ||
+ !STREQ (p, config_item->key))
+ continue;
+ if (!manpath_map_found)
+ debug ("is in the config file\n");
+ manpath_map_found = true;
+ insert_override_dir (tmplist, config_item->cont);
+ add_dir_to_list (tmplist, config_item->cont);
+ } GL_LIST_FOREACH_END (config);
+
+ /* The directory we're working on isn't in the config file.
+ See if it has ../man, man, ../share/man, or share/man
+ subdirectories. If so, and they haven't been added to
+ the list, do. */
+
+ if (!manpath_map_found) {
debug ("is not in the config file\n");
-
- t = has_mandir (p);
- if (t) {
- debug ("but does have a ../man, man, "
- "../share/man, or share/man "
- "subdirectory\n");
-
- insert_override_dir (tmplist, t);
- add_dir_to_list (tmplist, t);
- free (t);
- } else
- debug ("and doesn't have ../man, man, "
- "../share/man, or share/man "
- "subdirectories\n");
+ add_man_subdirs (tmplist, p);
}
}
@@ -1025,19 +1020,19 @@ char *get_manpath_from_path (const char *path, int mandatory)
if (mandatory) {
debug ("\nadding mandatory man directories\n\n");
- for (list = namestore; list; list = list->next)
- if (list->flag == MANDATORY) {
- insert_override_dir (tmplist, list->key);
- add_dir_to_list (tmplist, list->key);
+ GL_LIST_FOREACH_START (config, config_item) {
+ if (config_item->flag == MANDATORY) {
+ insert_override_dir (tmplist,
+ config_item->key);
+ add_dir_to_list (tmplist, config_item->key);
}
+ } GL_LIST_FOREACH_END (config);
}
len = 0;
- lp = tmplist;
- while (*lp != NULL) {
- len += strlen (*lp) + 1;
- lp++;
- }
+ GL_LIST_FOREACH_START (tmplist, item)
+ len += strlen (item) + 1;
+ GL_LIST_FOREACH_END (tmplist);
if (!len)
/* No path elements in configuration file or with
@@ -1048,38 +1043,29 @@ char *get_manpath_from_path (const char *path, int mandatory)
manpathlist = xmalloc (len);
*manpathlist = '\0';
- lp = tmplist;
p = manpathlist;
- while (*lp != NULL) {
- len = strlen (*lp);
- memcpy (p, *lp, len);
- free (*lp);
- *lp = NULL;
+ GL_LIST_FOREACH_START (tmplist, item) {
+ len = strlen (item);
+ memcpy (p, item, len);
p += len;
*p++ = ':';
- lp++;
- }
+ } GL_LIST_FOREACH_END (tmplist);
p[-1] = '\0';
+ gl_list_free (tmplist);
+
return manpathlist;
}
/* Add a directory to the manpath list if it isn't already there. */
-static void add_expanded_dir_to_list (char **lp, const char *dir)
+static void add_expanded_dir_to_list (gl_list_t list, const char *dir)
{
int status;
- int pos = 0;
-
- while (*lp != NULL) {
- if (pos > MAXDIRS - 1)
- gripe_overlong_list ();
- if (!strcmp (*lp, dir)) {
- debug ("%s is already in the manpath\n", dir);
- return;
- }
- lp++;
- pos++;
+
+ if (gl_list_search (list, dir)) {
+ debug ("%s is already in the manpath\n", dir);
+ return;
}
/* Not found -- add it. */
@@ -1092,8 +1078,7 @@ static void add_expanded_dir_to_list (char **lp, const char *dir)
gripe_not_directory (dir);
else if (status == 1) {
debug ("adding %s to manpath\n", dir);
-
- *lp = xstrdup (dir);
+ gl_list_add_last (list, xstrdup (dir));
}
}
@@ -1101,25 +1086,25 @@ static void add_expanded_dir_to_list (char **lp, const char *dir)
* Add a directory to the manpath list if it isn't already there, expanding
* wildcards.
*/
-static void add_dir_to_list (char **lp, const char *dir)
+static void add_dir_to_list (gl_list_t list, const char *dir)
{
- char **expanded_dirs;
- int i;
+ gl_list_t expanded_dirs;
+ const char *expanded_dir;
expanded_dirs = expand_path (dir);
- for (i = 0; expanded_dirs[i]; i++) {
- add_expanded_dir_to_list (lp, expanded_dirs[i]);
- free (expanded_dirs[i]);
- }
- free (expanded_dirs);
+ GL_LIST_FOREACH_START (expanded_dirs, expanded_dir)
+ add_expanded_dir_to_list (list, expanded_dir);
+ GL_LIST_FOREACH_END (expanded_dirs);
+ gl_list_free (expanded_dirs);
}
/* path does not exist in config file: check to see if path/../man,
- path/man, path/../share/man, or path/share/man exist. If so return
- it, if not return NULL. */
-static char *has_mandir (const char *path)
+ path/man, path/../share/man, or path/share/man exist, and add them to the
+ list if they do. */
+static void add_man_subdirs (gl_list_t list, const char *path)
{
char *newpath;
+ int found = 0;
/* don't assume anything about path, especially that it ends in
"bin" or even has a '/' in it! */
@@ -1127,113 +1112,126 @@ static char *has_mandir (const char *path)
char *subdir = strrchr (path, '/');
if (subdir) {
newpath = xasprintf ("%.*s/man", (int) (subdir - path), path);
- if (is_directory (newpath) == 1)
- return newpath;
+ if (is_directory (newpath) == 1) {
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
+ found = 1;
+ }
free (newpath);
}
newpath = xasprintf ("%s/man", path);
- if (is_directory (newpath) == 1)
- return newpath;
+ if (is_directory (newpath) == 1) {
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
+ found = 1;
+ }
free (newpath);
if (subdir) {
newpath = xasprintf ("%.*s/share/man",
(int) (subdir - path), path);
- if (is_directory (newpath) == 1)
- return newpath;
+ if (is_directory (newpath) == 1) {
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
+ found = 1;
+ }
free (newpath);
}
newpath = xasprintf ("%s/share/man", path);
- if (is_directory (newpath) == 1)
- return newpath;
+ if (is_directory (newpath) == 1) {
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
+ found = 1;
+ }
free (newpath);
- return NULL;
+ if (!found)
+ debug ("and doesn't have ../man, man, ../share/man, or "
+ "share/man subdirectories\n");
}
-static char **add_dir_to_path_list (char **mphead, char **mp, const char *p)
+static void add_dir_to_path_list (gl_list_t list, const char *p)
{
- int status, i;
- char *cwd, *d, **expanded_dirs;
-
- if (mp - mphead > MAXDIRS - 1)
- gripe_overlong_list ();
+ gl_list_t expanded_dirs;
+ char *expanded_dir;
expanded_dirs = expand_path (p);
- for (i = 0; expanded_dirs[i]; i++) {
- d = expanded_dirs[i];
-
- status = is_directory (d);
+ GL_LIST_FOREACH_START (expanded_dirs, expanded_dir) {
+ int status = is_directory (expanded_dir);
if (status < 0)
- gripe_stat_file (d);
+ gripe_stat_file (expanded_dir);
else if (status == 0)
- gripe_not_directory (d);
+ gripe_not_directory (expanded_dir);
else {
+ char *path;
+
/* deal with relative paths */
- if (*d != '/') {
- cwd = xgetcwd ();
+ if (*expanded_dir != '/') {
+ char *cwd = xgetcwd ();
if (!cwd)
error (FATAL, errno,
_("can't determine current directory"));
- *mp = appendstr (cwd, "/", d, (void *) 0);
+ path = appendstr (cwd, "/", expanded_dir,
+ (void *) 0);
} else
- *mp = xstrdup (d);
+ path = xstrdup (expanded_dir);
- debug ("adding %s to manpathlist\n", *mp);
- mp++;
+ debug ("adding %s to manpathlist\n", path);
+ gl_list_add_last (list, path);
}
- free (d);
- }
- free (expanded_dirs);
-
- return mp;
+ } GL_LIST_FOREACH_END (expanded_dirs);
+ gl_list_free (expanded_dirs);
}
-void create_pathlist (const char *manp, char **mp)
+gl_list_t create_pathlist (const char *manp)
{
+ gl_list_t list;
+ gl_list_iterator_t iter;
+ gl_list_node_t node;
const char *p, *end;
- char **mphead = mp;
/* Expand the manpath into a list for easier handling. */
+ list = new_string_list (GL_LINKEDHASH_LIST, true);
for (p = manp;; p = end + 1) {
end = strchr (p, ':');
if (end) {
char *element = xstrndup (p, end - p);
- mp = add_dir_to_path_list (mphead, mp, element);
+ add_dir_to_path_list (list, element);
free (element);
} else {
- mp = add_dir_to_path_list (mphead, mp, p);
+ add_dir_to_path_list (list, p);
break;
}
}
- *mp = NULL;
/* Eliminate duplicates due to symlinks. */
- mp = mphead;
- while (*mp) {
+ iter = gl_list_iterator (list);
+ while (gl_list_iterator_next (&iter, (const void **) &p, &node)) {
char *target;
- char **dupcheck;
- int found_dup = 0;
+ gl_list_iterator_t dupcheck_iter;
+ const char *dupcheck;
+ gl_list_node_t dupcheck_node;
/* After resolving all symlinks, is the target also in the
* manpath?
*/
- target = canonicalize_file_name (*mp);
- if (!target) {
- ++mp;
+ target = canonicalize_file_name (p);
+ if (!target)
continue;
- }
/* Only check up to the current list position, to keep item
* order stable across deduplication.
*/
- for (dupcheck = mphead; *dupcheck && dupcheck != mp;
- ++dupcheck) {
+ dupcheck_iter = gl_list_iterator (list);
+ while (gl_list_iterator_next (&dupcheck_iter,
+ (const void **) &dupcheck,
+ &dupcheck_node) &&
+ dupcheck_node != node) {
char *dupcheck_target = canonicalize_file_name
- (*dupcheck);
+ (dupcheck);
if (!dupcheck_target)
continue;
if (!STREQ (target, dupcheck_target)) {
@@ -1241,54 +1239,48 @@ void create_pathlist (const char *manp, char **mp)
continue;
}
free (dupcheck_target);
- debug ("Removing duplicate manpath entry %s (%td) -> "
- "%s (%td)\n",
- *mp, mp - mphead,
- *dupcheck, dupcheck - mphead);
- free (*mp);
- for (dupcheck = mp; *(dupcheck + 1); ++dupcheck)
- *dupcheck = *(dupcheck + 1);
- *dupcheck = NULL;
- found_dup = 1;
+ debug ("Removing duplicate manpath entry %s -> %s\n",
+ p, dupcheck);
+ gl_list_remove_node (list, node);
break;
}
+ gl_list_iterator_free (&dupcheck_iter);
free (target);
- if (!found_dup)
- ++mp;
}
+ gl_list_iterator_free (&iter);
if (debug_level) {
- int first = 1;
+ bool first = true;
debug ("final search path = ");
- for (mp = mphead; *mp; ++mp) {
+ GL_LIST_FOREACH_START (list, p) {
if (first) {
- debug ("%s", *mp);
- first = 0;
+ debug ("%s", p);
+ first = false;
} else
- debug (":%s", *mp);
- }
+ debug (":%s", p);
+ } GL_LIST_FOREACH_END (list);
debug ("\n");
}
+
+ return list;
}
-void free_pathlist (char **mp)
+void free_pathlist (gl_list_t list)
{
- while (*mp) {
- free (*mp);
- *mp++ = NULL;
- }
+ gl_list_free (list);
}
/* Routine to get list of named system and user manpaths (in reverse order). */
char *get_mandb_manpath (void)
{
char *manpath = NULL;
- struct list *list;
+ const struct config_item *item;
- for (list = namestore; list; list = list->next)
- if (list->flag == MANDB_MAP || list->flag == MANDB_MAP_USER)
- manpath = pathappend (manpath, list->key);
+ GL_LIST_FOREACH_START (config, item)
+ if (item->flag == MANDB_MAP || item->flag == MANDB_MAP_USER)
+ manpath = pathappend (manpath, item->key);
+ GL_LIST_FOREACH_END (config);
return manpath;
}
@@ -1308,16 +1300,17 @@ char *get_mandb_manpath (void)
*/
char *get_catpath (const char *name, int cattype)
{
- struct list *list;
-
- for (list = namestore; list; list = list->next)
- if (((cattype & SYSTEM_CAT) && list->flag == MANDB_MAP) ||
- ((cattype & USER_CAT) && list->flag == MANDB_MAP_USER)) {
- size_t manlen = strlen (list->key);
- if (STRNEQ (name, list->key, manlen)) {
+ const struct config_item *item;
+ char *ret = NULL;
+
+ GL_LIST_FOREACH_START (config, item)
+ if (((cattype & SYSTEM_CAT) && item->flag == MANDB_MAP) ||
+ ((cattype & USER_CAT) && item->flag == MANDB_MAP_USER)) {
+ size_t manlen = strlen (item->key);
+ if (STRNEQ (name, item->key, manlen)) {
const char *suffix;
char *infix;
- char *catpath = xstrdup (list->cont);
+ char *catpath = xstrdup (item->cont);
/* For NLS subdirectories (e.g.
* /usr/share/man/de -> /var/cache/man/de),
@@ -1325,10 +1318,12 @@ char *get_catpath (const char *name, int cattype)
* long as this strictly follows the key.
*/
suffix = strrchr (name, '/');
- if (!suffix)
- return appendstr (catpath,
- name + manlen,
- (void *) 0);
+ if (!suffix) {
+ ret = appendstr (catpath,
+ name + manlen,
+ (void *) 0);
+ break;
+ }
while (suffix > name + manlen)
if (*--suffix == '/')
@@ -1349,25 +1344,32 @@ char *get_catpath (const char *name, int cattype)
}
catpath = appendstr (catpath, suffix,
(void *) 0);
- return catpath;
+ ret = catpath;
+ break;
}
}
+ GL_LIST_FOREACH_END (config);
- return NULL;
+ return ret;
}
/* Check to see if the supplied man directory is a system-wide mandir.
* Obviously, user directories must not be included here.
*/
-int is_global_mandir (const char *dir)
+bool is_global_mandir (const char *dir)
{
- struct list *list;
+ const struct config_item *item;
+ bool ret = false;
+
+ GL_LIST_FOREACH_START (config, item)
+ if (item->flag == MANDB_MAP &&
+ STRNEQ (dir, item->key, strlen (item->key))) {
+ ret = true;
+ break;
+ }
+ GL_LIST_FOREACH_END (config);
- for (list = namestore; list; list = list->next)
- if (list->flag == MANDB_MAP &&
- STRNEQ (dir, list->key, strlen (list->key)))
- return 1;
- return 0;
+ return ret;
}
/* Accept a manpath (not a full pathname to a file) and return an FSSTND
diff --git a/src/manp.h b/src/manp.h
index 529bfa6f..676891b2 100644
--- a/src/manp.h
+++ b/src/manp.h
@@ -22,6 +22,10 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdbool.h>
+
+#include "gl_list.h"
+
struct locale_bits {
char *language;
char *territory;
@@ -36,12 +40,12 @@ extern void free_locale_bits (struct locale_bits *bits);
extern char *add_nls_manpaths (const char *manpathlist, const char *locales);
extern char *get_manpath (const char *systems);
extern char *get_manpath_from_path (const char *path, int mandatory);
-extern void create_pathlist (const char *manp, char **mp);
-extern void free_pathlist (char **mp);
+extern gl_list_t create_pathlist (const char *manp);
+extern void free_pathlist (gl_list_t list);
extern char *get_mandb_manpath (void);
extern char *get_catpath (const char *name, int cattype);
-extern int is_global_mandir (const char *dir);
-extern void read_config_file (int optional);
+extern bool is_global_mandir (const char *dir);
+extern void read_config_file (bool optional);
extern const char *get_def (const char *thing, const char *def);
extern const char *get_def_user (const char *thing, const char *def);
-extern const char **get_sections (void);
+extern gl_list_t get_sections (void);
diff --git a/src/manpath.c b/src/manpath.c
index de3a2948..97e27376 100644
--- a/src/manpath.c
+++ b/src/manpath.c
@@ -27,6 +27,7 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -51,8 +52,8 @@
int quiet = 0;
man_sandbox *sandbox; /* unused, but needed by libman */
-static int cat = 0;
-static int global = 0;
+static bool cat = false;
+static bool global = false;
static const char *alt_system = "";
extern char *user_config_file;
@@ -75,14 +76,14 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'c':
- cat = 1;
+ cat = true;
return 0;
case 'g':
- global = 1;
+ global = true;
quiet = 1;
return 0;
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'q':
quiet = 1;
diff --git a/src/straycats.c b/src/straycats.c
index 51f66170..0f4c50ee 100644
--- a/src/straycats.c
+++ b/src/straycats.c
@@ -28,6 +28,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -40,6 +41,8 @@
#include "canonicalize.h"
#include "dirname.h"
+#include "gl_array_list.h"
+#include "gl_xlist.h"
#include "gettext.h"
#define _(String) gettext (String)
@@ -47,6 +50,7 @@
#include "manconfig.h"
#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "decompress.h"
#include "encodings.h"
@@ -70,8 +74,8 @@ static int check_for_stray (MYDBM_FILE dbf)
{
DIR *cdir;
struct dirent *catlist;
- char **names;
- size_t names_len, names_max, i;
+ gl_list_t names;
+ const char *name;
size_t lenman, lencat;
int strays = 0;
@@ -81,30 +85,24 @@ static int check_for_stray (MYDBM_FILE dbf)
return 0;
}
- names_len = 0;
- names_max = 1024;
- names = XNMALLOC (names_max, char *);
+ names = new_string_list (GL_ARRAY_LIST, false);
while ((catlist = readdir (cdir)) != NULL) {
if (*catlist->d_name == '.' &&
strlen (catlist->d_name) < (size_t) 3)
continue;
- if (names_len >= names_max) {
- names_max *= 2;
- names = xnrealloc (names, names_max, sizeof (char *));
- }
- names[names_len++] = xstrdup (catlist->d_name);
+ gl_list_add_last (names, xstrdup (catlist->d_name));
}
closedir (cdir);
- order_files (catdir, names, names_len);
+ order_files (catdir, &names);
mandir = appendstr (mandir, "/", (void *) 0);
catdir = appendstr (catdir, "/", (void *) 0);
lenman = strlen (mandir);
lencat = strlen (catdir);
- for (i = 0; i < names_len; ++i) {
+ GL_LIST_FOREACH_START (names, name) {
struct mandata info;
char *ext, *section;
short found;
@@ -116,8 +114,8 @@ static int check_for_stray (MYDBM_FILE dbf)
memset (&info, 0, sizeof (struct mandata));
*(mandir + lenman) = *(catdir + lencat) = '\0';
- mandir = appendstr (mandir, names[i], (void *) 0);
- catdir = appendstr (catdir, names[i], (void *) 0);
+ mandir = appendstr (mandir, name, (void *) 0);
+ catdir = appendstr (catdir, name, (void *) 0);
ext = strrchr (mandir, '.');
if (!ext) {
@@ -126,7 +124,7 @@ static int check_for_stray (MYDBM_FILE dbf)
_("warning: %s: "
"ignoring bogus filename"),
catdir);
- goto next_name;
+ continue;
#if defined(COMP_SRC) || defined(COMP_CAT)
@@ -197,13 +195,9 @@ static int check_for_stray (MYDBM_FILE dbf)
further */
mandir_base = base_name (mandir);
exists = dblookup_exact (dbf, mandir_base, info.ext,
- 1);
-#ifndef FAVOUR_STRAYCATS
- if (exists && exists->id != WHATIS_CAT)
-#else /* FAVOUR_STRAYCATS */
- if (exists && exists->id != WHATIS_CAT &&
- exists->id != WHATIS_MAN)
-#endif /* !FAVOUR_STRAYCATS */
+ true);
+ if (exists &&
+ compare_ids (STRAY_CAT, exists->id, 0) >= 0)
goto next_exists;
debug ("%s(%s) is not in the db.\n",
mandir_base, info.ext);
@@ -270,17 +264,14 @@ static int check_for_stray (MYDBM_FILE dbf)
if (find_name_decompressed (decomp,
catdir_base,
&lg)) {
- struct page_description *descs;
+ gl_list_t descs;
strays++;
descs = parse_descriptions
(mandir_base, lg.whatis);
- if (descs) {
- store_descriptions
- (dbf, descs, &info,
- NULL, mandir_base,
- NULL);
- free_descriptions (descs);
- }
+ store_descriptions (dbf, descs, &info,
+ NULL, mandir_base,
+ NULL);
+ gl_list_free (descs);
} else if (quiet < 2)
error (0, 0, _("warning: %s: whatis parse for %s(%s) failed"),
catdir, mandir_base, info.sec);
@@ -295,10 +286,8 @@ next_exists:
}
next_section:
free (section);
-next_name:
- free (names[i]);
- }
- free (names);
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
return strays;
}
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 3c56222a..74cae23b 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -98,6 +98,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/m4/man-arg-db.m4 \
$(top_srcdir)/m4/man-arg-device.m4 \
$(top_srcdir)/m4/man-arg-mandirs.m4 \
+ $(top_srcdir)/m4/man-arg-manual.m4 \
$(top_srcdir)/m4/man-arg-override-dir.m4 \
$(top_srcdir)/m4/man-arg-sections.m4 \
$(top_srcdir)/m4/man-arg-setuid.m4 \
@@ -120,7 +121,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/gl/m4/btowc.m4 \
$(top_srcdir)/gl/m4/builtin-expect.m4 \
$(top_srcdir)/gl/m4/canonicalize.m4 \
- $(top_srcdir)/gl/m4/chdir-long.m4 \
+ $(top_srcdir)/gl/m4/chdir-long.m4 $(top_srcdir)/gl/m4/chown.m4 \
$(top_srcdir)/gl/m4/clock_time.m4 $(top_srcdir)/gl/m4/close.m4 \
$(top_srcdir)/gl/m4/closedir.m4 $(top_srcdir)/gl/m4/codeset.m4 \
$(top_srcdir)/gl/m4/d-ino.m4 $(top_srcdir)/gl/m4/d-type.m4 \
@@ -164,7 +165,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/man-arg-automatic-create.m4 \
$(top_srcdir)/gl/m4/intmax_t.m4 \
$(top_srcdir)/gl/m4/inttypes_h.m4 $(top_srcdir)/gl/m4/ioctl.m4 \
$(top_srcdir)/gl/m4/langinfo_h.m4 \
- $(top_srcdir)/gl/m4/largefile.m4 \
+ $(top_srcdir)/gl/m4/largefile.m4 $(top_srcdir)/gl/m4/lchown.m4 \
$(top_srcdir)/gl/m4/lib-ignore.m4 \
$(top_srcdir)/gl/m4/lib-ld.m4 $(top_srcdir)/gl/m4/lib-link.m4 \
$(top_srcdir)/gl/m4/lib-prefix.m4 \
diff --git a/src/ult_src.c b/src/ult_src.c
index 15c2e52b..2b0ba278 100644
--- a/src/ult_src.c
+++ b/src/ult_src.c
@@ -46,6 +46,7 @@
#include "canonicalize.h"
#include "dirname.h"
#include "error.h"
+#include "gl_xlist.h"
#include "xvasprintf.h"
#include "gettext.h"
@@ -205,43 +206,24 @@ static char *find_include (const char *name, const char *path,
} else {
/* Try globbing - the file suffix might be missing. */
char *temp_file_asterisk = xasprintf ("%s*", temp_file);
- char **candidate_files = expand_path (temp_file_asterisk);
- int i;
+ gl_list_t candidate_files = expand_path (temp_file_asterisk);
free (temp_file_asterisk);
- if (CAN_ACCESS (candidate_files[0], F_OK)) {
- free (ret);
- ret = canonicalize_file_name (candidate_files[0]);
+ if (gl_list_size (candidate_files)) {
+ const char *candidate_file = gl_list_get_at
+ (candidate_files, 0);
+ if (CAN_ACCESS (candidate_file, F_OK)) {
+ free (ret);
+ ret = canonicalize_file_name (candidate_file);
+ }
}
- for (i = 0; candidate_files[i]; i++)
- free (candidate_files[i]);
- free (candidate_files);
+ gl_list_free (candidate_files);
}
free (temp_file);
return ret;
}
-static void ult_trace (struct ult_trace *trace, const char *s)
-{
- if (!trace)
- return;
- if (trace->len >= trace->max) {
- trace->max *= 2;
- trace->names = xnrealloc (trace->names, trace->max,
- sizeof (char *));
- }
- trace->names[trace->len++] = xstrdup (s);
-}
-
-void free_ult_trace (struct ult_trace *trace)
-{
- size_t i;
- for (i = 0; i < trace->len; ++i)
- free (trace->names[i]);
- free (trace->names);
-}
-
/*
* recursive function which finds the ultimate source file by following
* any ".so filename" directives in the first line of the man pages.
@@ -251,21 +233,15 @@ void free_ult_trace (struct ult_trace *trace)
* flags is a combination of SO_LINK | SOFT_LINK | HARD_LINK
*/
const char *ult_src (const char *name, const char *path,
- struct stat *buf, int flags, struct ult_trace *trace)
+ struct stat *buf, int flags, gl_list_t trace)
{
static char *base; /* must be static */
static short recurse; /* must be static */
/* initialise the function */
- if (trace) {
- if (!trace->names) {
- trace->len = 0;
- trace->max = 16;
- trace->names = XNMALLOC (trace->max, char *);
- }
- ult_trace (trace, name);
- }
+ if (trace)
+ gl_list_add_last (trace, name);
/* as ult_softlink() & ult_hardlink() do all of their respective
* resolving in one call, only need to sort them out once
@@ -400,6 +376,6 @@ const char *ult_src (const char *name, const char *path,
/* We have the ultimate source */
if (trace)
- ult_trace (trace, base);
+ gl_list_add_last (trace, base);
return base;
}
diff --git a/src/ult_src.h b/src/ult_src.h
index 6fad4706..857700d4 100644
--- a/src/ult_src.h
+++ b/src/ult_src.h
@@ -22,22 +22,18 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "gl_list.h"
+
#define SO_LINK 0001
#define SOFT_LINK 0002
#define HARD_LINK 0004
-/* Trace of the link chain from a given file. Any names listed here should
- * not have WHATIS_MAN entries created for them.
- */
-struct ult_trace {
- char **names;
- size_t len;
- size_t max;
-};
-
struct stat;
+/* If ult_trace is non-NULL, it should be a gl_list_t of const char * which
+ * ult_src populates with the trace of the link chain from a given file.
+ * Any names listed here should not have WHATIS_MAN entries created for
+ * them.
+ */
extern const char *ult_src (const char *name, const char *path,
- struct stat *buf, int flags,
- struct ult_trace *trace);
-extern void free_ult_trace (struct ult_trace *trace);
+ struct stat *buf, int flags, gl_list_t trace);
diff --git a/src/whatis.c b/src/whatis.c
index ee43f10a..8b648121 100644
--- a/src/whatis.c
+++ b/src/whatis.c
@@ -34,6 +34,7 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -56,6 +57,9 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_hash_set.h"
+#include "gl_list.h"
+#include "gl_xset.h"
#include "fnmatch.h"
#include "progname.h"
#include "xvasprintf.h"
@@ -64,11 +68,10 @@
#include "cleanup.h"
#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "pathsearch.h"
#include "linelength.h"
-#include "hashtable.h"
-#include "lower.h"
#include "wordfnmatch.h"
#include "xregcomp.h"
#include "encodings.h"
@@ -79,13 +82,13 @@
#include "manp.h"
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
extern char *user_config_file;
static char **keywords;
static int num_keywords;
-int am_apropos;
+bool am_apropos;
char *database;
int quiet = 1;
man_sandbox *sandbox;
@@ -95,14 +98,14 @@ iconv_t conv_to_locale;
#endif /* HAVE_ICONV */
static regex_t *preg;
-static int regex_opt;
-static int exact;
+static bool regex_opt;
+static bool exact;
-static int wildcard;
+static bool wildcard;
-static int require_all;
+static bool require_all;
-static int long_output;
+static bool long_output;
static char **sections;
@@ -111,7 +114,7 @@ static const char *alt_systems = "";
static const char *locale = NULL;
static char *multiple_locale = NULL, *internal_locale;
-static struct hashtable *display_seen = NULL;
+static gl_set_t display_seen = NULL;
const char *argp_program_version; /* initialised in main */
const char *argp_program_bug_address = PACKAGE_BUGREPORT;
@@ -167,33 +170,33 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'v':
quiet = 0;
return 0;
case 'r':
- regex_opt = 1;
+ regex_opt = true;
return 0;
case 'e':
/* Only makes sense for apropos, but has
* historically been accepted by whatis anyway.
*/
- regex_opt = 0;
- exact = 1;
+ regex_opt = false;
+ exact = true;
return 0;
case 'w':
- regex_opt = 0;
- wildcard = 1;
+ regex_opt = false;
+ wildcard = true;
return 0;
case 'a':
if (am_apropos)
- require_all = 1;
+ require_all = true;
else
argp_usage (state);
return 0;
case 'l':
- long_output = 1;
+ long_output = true;
return 0;
case 's':
sections = split_sections (arg);
@@ -212,11 +215,11 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
return 0;
case 'f':
/* helpful override if program name detection fails */
- am_apropos = 0;
+ am_apropos = false;
return 0;
case 'k':
/* helpful override if program name detection fails */
- am_apropos = 1;
+ am_apropos = true;
return 0;
case 'h':
argp_state_help (state, state->out_stream,
@@ -233,7 +236,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
exit (FAIL);
case ARGP_KEY_SUCCESS:
if (am_apropos && !exact && !wildcard)
- regex_opt = 1;
+ regex_opt = true;
return 0;
}
return ARGP_ERR_UNKNOWN;
@@ -321,7 +324,7 @@ static char *simple_convert (iconv_t conv, char *string)
* legacy mechanism.
*/
static void use_grep (const char * const *pages, int num_pages, char *manpath,
- int *found)
+ bool *found)
{
char *whatis_file = xasprintf ("%s/whatis", manpath);
@@ -361,7 +364,7 @@ static void use_grep (const char * const *pages, int num_pages, char *manpath,
grep_pl = pipeline_new_commands (grep_cmd, (void *) 0);
if (pipeline_run (grep_pl) == 0)
- found[i] = 1;
+ found[i] = true;
free (anchored_page);
}
@@ -387,7 +390,7 @@ static struct mandata *resolve_pointers (MYDBM_FILE dbf, struct mandata *info,
* arbitrary: it's just there to avoid an infinite loop.
*/
newpage = info->pointer;
- info = dblookup_exact (dbf, newpage, info->ext, 1);
+ info = dblookup_exact (dbf, newpage, info->ext, true);
for (rounds = 0; rounds < 10; rounds++) {
struct mandata *newinfo;
@@ -400,7 +403,7 @@ static struct mandata *resolve_pointers (MYDBM_FILE dbf, struct mandata *info,
STREQ (info->pointer, newpage)))
return info;
- newinfo = dblookup_exact (dbf, info->pointer, info->ext, 1);
+ newinfo = dblookup_exact (dbf, info->pointer, info->ext, true);
free_mandata_struct (info);
info = newinfo;
}
@@ -451,9 +454,9 @@ static void display (MYDBM_FILE dbf, struct mandata *info, const char *page)
page_name = page;
key = xasprintf ("%s (%s)", page_name, newinfo->ext);
- if (hashtable_lookup_structure (display_seen, key, strlen (key)))
+ if (gl_set_search (display_seen, key))
goto out;
- hashtable_install (display_seen, key, strlen (key), NULL);
+ gl_set_add (display_seen, xstrdup (key));
line_len = get_line_length ();
@@ -499,56 +502,45 @@ out:
static int do_whatis_section (MYDBM_FILE dbf,
const char *page, const char *section)
{
+ gl_list_t infos;
struct mandata *info;
int count = 0;
- info = dblookup_all (dbf, page, section, 0);
- while (info) {
- struct mandata *pinfo;
-
+ infos = dblookup_all (dbf, page, section, false);
+ GL_LIST_FOREACH_START (infos, info) {
display (dbf, info, page);
count++;
- pinfo = info->next; /* go on to next structure */
- free_mandata_elements (info);
- free (info);
- info = pinfo;
- }
+ } GL_LIST_FOREACH_END (infos);
+ gl_list_free (infos);
return count;
}
-static int suitable_manpath (const char *manpath, const char *page_dir)
+static bool suitable_manpath (const char *manpath, const char *page_dir)
{
char *page_manp, *pm;
- char *page_manpathlist[MAXDIRS], **mp;
- int ret;
+ gl_list_t page_manpathlist;
+ bool ret;
page_manp = get_manpath_from_path (page_dir, 0);
if (!page_manp || !*page_manp) {
free (page_manp);
- return 0;
+ return false;
}
pm = locale_manpath (page_manp);
free (page_manp);
page_manp = pm;
- create_pathlist (page_manp, page_manpathlist);
+ page_manpathlist = create_pathlist (page_manp);
- ret = 0;
- for (mp = page_manpathlist; *mp; ++mp) {
- if (STREQ (*mp, manpath)) {
- ret = 1;
- break;
- }
- }
+ ret = gl_list_search (page_manpathlist, manpath) ? true : false;
- for (mp = page_manpathlist; *mp; ++mp)
- free (*mp);
+ free_pathlist (page_manpathlist);
free (page_manp);
return ret;
}
static void do_whatis (MYDBM_FILE dbf,
const char * const *pages, int num_pages,
- const char *manpath, int *found)
+ const char *manpath, bool *found)
{
int i;
@@ -586,39 +578,39 @@ static void do_whatis (MYDBM_FILE dbf,
for (section = sections; *section; ++section) {
if (do_whatis_section (dbf, page, *section))
- found[i] = 1;
+ found[i] = true;
}
} else {
if (do_whatis_section (dbf, page, NULL))
- found[i] = 1;
+ found[i] = true;
}
free (page);
}
}
-static int any_set (int num_pages, int *found_here)
+static bool any_set (int num_pages, bool *found_here)
{
int i;
for (i = 0; i < num_pages; ++i)
if (found_here[i])
- return 1;
- return 0;
+ return true;
+ return false;
}
-static int all_set (int num_pages, int *found_here)
+static bool all_set (int num_pages, bool *found_here)
{
int i;
for (i = 0; i < num_pages; ++i)
if (!found_here[i])
- return 0;
- return 1;
+ return false;
+ return true;
}
static void parse_name (const char * const *pages, int num_pages,
- const char *dbname, int *found, int *found_here)
+ const char *dbname, bool *found, bool *found_here)
{
int i;
@@ -626,57 +618,50 @@ static void parse_name (const char * const *pages, int num_pages,
for (i = 0; i < num_pages; ++i) {
if (regexec (&preg[i], dbname, 0,
(regmatch_t *) 0, 0) == 0)
- found[i] = found_here[i] = 1;
+ found[i] = found_here[i] = true;
}
return;
}
if (am_apropos && !wildcard) {
- char *lowdbname = lower (dbname);
-
for (i = 0; i < num_pages; ++i) {
- if (STREQ (lowdbname, pages[i]))
- found[i] = found_here[i] = 1;
+ if (strcasecmp (dbname, pages[i]) == 0)
+ found[i] = found_here[i] = true;
}
- free (lowdbname);
return;
}
for (i = 0; i < num_pages; ++i) {
- if (fnmatch (pages[i], dbname, 0) == 0)
- found[i] = found_here[i] = 1;
+ if (fnmatch (pages[i], dbname, FNM_CASEFOLD) == 0)
+ found[i] = found_here[i] = true;
}
}
-/* return 1 on word match */
-static int match (const char *lowpage, const char *whatis)
+/* return true on word match */
+static bool match (const char *page, const char *whatis)
{
- char *lowwhatis = lower (whatis);
- size_t len = strlen (lowpage);
- char *p, *begin;
+ size_t len = strlen (page);
+ const char *begin;
+ char *p;
- begin = lowwhatis;
+ begin = whatis;
/* check for string match, then see if it is a _word_ */
- while (lowwhatis && (p = strstr (lowwhatis, lowpage))) {
+ while (whatis && (p = strcasestr (whatis, page))) {
char *left = p - 1;
char *right = p + len;
- if ((p == begin || (!CTYPE (islower, *left) && *left != '_')) &&
- (!*right || (!CTYPE (islower, *right) && *right != '_'))) {
- free (begin);
- return 1;
- }
- lowwhatis = p + 1;
+ if ((p == begin || (!CTYPE (isalpha, *left) && *left != '_')) &&
+ (!*right || (!CTYPE (isalpha, *right) && *right != '_')))
+ return true;
+ whatis = p + 1;
}
- free (begin);
- return 0;
+ return false;
}
-static void parse_whatis (const char * const *pages, char * const *lowpages,
- int num_pages, const char *whatis,
- int *found, int *found_here)
+static void parse_whatis (const char * const *pages, int num_pages,
+ const char *whatis, bool *found, bool *found_here)
{
int i;
@@ -684,7 +669,7 @@ static void parse_whatis (const char * const *pages, char * const *lowpages,
for (i = 0; i < num_pages; ++i) {
if (regexec (&preg[i], whatis, 0,
(regmatch_t *) 0, 0) == 0)
- found[i] = found_here[i] = 1;
+ found[i] = found_here[i] = true;
}
return;
}
@@ -693,18 +678,18 @@ static void parse_whatis (const char * const *pages, char * const *lowpages,
for (i = 0; i < num_pages; ++i) {
if (exact) {
if (fnmatch (pages[i], whatis, 0) == 0)
- found[i] = found_here[i] = 1;
+ found[i] = found_here[i] = true;
} else {
if (word_fnmatch (pages[i], whatis))
- found[i] = found_here[i] = 1;
+ found[i] = found_here[i] = true;
}
}
return;
}
for (i = 0; i < num_pages; ++i) {
- if (match (lowpages[i], whatis))
- found[i] = found_here[i] = 1;
+ if (match (pages[i], whatis))
+ found[i] = found_here[i] = true;
}
}
@@ -715,25 +700,18 @@ static void parse_whatis (const char * const *pages, char * const *lowpages,
/* scan for the page, print any matches */
static void do_apropos (MYDBM_FILE dbf,
- const char * const *pages, int num_pages, int *found)
+ const char * const *pages, int num_pages, bool *found)
{
datum key, cont;
- char **lowpages;
- int *found_here;
- int (*combine) (int, int *);
- int i;
+ bool *found_here;
+ bool (*combine) (int, bool *);
#ifndef BTREE
datum nextkey;
#else /* BTREE */
int end;
#endif /* !BTREE */
- lowpages = XNMALLOC (num_pages, char *);
- for (i = 0; i < num_pages; ++i) {
- lowpages[i] = lower (pages[i]);
- debug ("lower(%s) = \"%s\"\n", pages[i], lowpages[i]);
- }
- found_here = XNMALLOC (num_pages, int);
+ found_here = XNMALLOC (num_pages, bool);
combine = require_all ? all_set : any_set;
#ifndef BTREE
@@ -797,19 +775,17 @@ static void do_apropos (MYDBM_FILE dbf,
*tab = '\0';
memset (found_here, 0, num_pages * sizeof (*found_here));
+ parse_name (pages, num_pages,
+ MYDBM_DPTR (key), found, found_here);
if (am_apropos) {
char *whatis;
- parse_name ((const char **) lowpages, num_pages,
- MYDBM_DPTR (key), found, found_here);
whatis = info.whatis ? xstrdup (info.whatis) : NULL;
if (!combine (num_pages, found_here) && whatis)
- parse_whatis (pages, lowpages, num_pages,
+ parse_whatis (pages, num_pages,
whatis, found, found_here);
free (whatis);
- } else
- parse_name (pages, num_pages,
- MYDBM_DPTR (key), found, found_here);
+ }
if (combine (num_pages, found_here))
display (dbf, &info, MYDBM_DPTR (key));
@@ -831,31 +807,28 @@ nextpage:
}
free (found_here);
-
- for (i = 0; i < num_pages; ++i)
- free (lowpages[i]);
- free (lowpages);
}
/* loop through the man paths, searching for a match */
-static int search (const char * const *pages, int num_pages)
+static bool search (const char * const *pages, int num_pages)
{
- int *found = XCALLOC (num_pages, int);
- char *catpath, **mp;
- int any_found, i;
+ bool *found = XCALLOC (num_pages, bool);
+ char *catpath, *mp;
+ bool any_found;
+ int i;
- for (mp = manpathlist; *mp; mp++) {
+ GL_LIST_FOREACH_START (manpathlist, mp) {
MYDBM_FILE dbf;
- catpath = get_catpath (*mp, SYSTEM_CAT | USER_CAT);
+ catpath = get_catpath (mp, SYSTEM_CAT | USER_CAT);
if (catpath) {
database = mkdbname (catpath);
free (catpath);
} else
- database = mkdbname (*mp);
+ database = mkdbname (mp);
- debug ("path=%s\n", *mp);
+ debug ("path=%s\n", mp);
dbf = MYDBM_RDOPEN (database);
if (dbf && dbver_rd (dbf)) {
@@ -863,7 +836,7 @@ static int search (const char * const *pages, int num_pages)
dbf = NULL;
}
if (!dbf) {
- use_grep (pages, num_pages, *mp, found);
+ use_grep (pages, num_pages, mp, found);
continue;
}
@@ -873,19 +846,19 @@ static int search (const char * const *pages, int num_pages)
if (regex_opt || wildcard)
do_apropos (dbf, pages, num_pages, found);
else
- do_whatis (dbf, pages, num_pages, *mp, found);
+ do_whatis (dbf, pages, num_pages, mp, found);
}
free (database);
database = NULL;
MYDBM_CLOSE (dbf);
- }
+ } GL_LIST_FOREACH_END (manpathlist);
chkr_garbage_detector ();
- any_found = 0;
+ any_found = false;
for (i = 0; i < num_pages; ++i) {
if (found[i])
- any_found = 1;
+ any_found = true;
else
fprintf (stderr, _("%s: nothing appropriate.\n"),
pages[i]);
@@ -906,11 +879,11 @@ int main (int argc, char *argv[])
set_program_name (argv[0]);
program_base_name = base_name (program_name);
if (STREQ (program_base_name, APROPOS_NAME)) {
- am_apropos = 1;
+ am_apropos = true;
argp_program_version = "apropos " PACKAGE_VERSION;
} else {
struct argp_option *optionp;
- am_apropos = 0;
+ am_apropos = false;
argp_program_version = "whatis " PACKAGE_VERSION;
for (optionp = (struct argp_option *) whatis_argp.options;
optionp->name || optionp->key || optionp->arg ||
@@ -969,9 +942,9 @@ int main (int argc, char *argv[])
else
free (get_manpath (NULL));
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
- display_seen = hashtable_create (&null_hashtable_free);
+ display_seen = new_string_set (GL_HASH_SET);
#ifdef HAVE_ICONV
locale_charset = xasprintf ("%s//IGNORE", get_locale_charset ());
@@ -1001,9 +974,10 @@ int main (int argc, char *argv[])
if (conv_to_locale != (iconv_t) -1)
iconv_close (conv_to_locale);
#endif /* HAVE_ICONV */
- hashtable_free (display_seen);
+ gl_set_free (display_seen);
free_pathlist (manpathlist);
free (manp);
free (internal_locale);
+ sandbox_free (sandbox);
exit (status);
}
diff --git a/src/zsoelim.c b/src/zsoelim.c
index a7225f64..b2e62052 100644
--- a/src/zsoelim.c
+++ b/src/zsoelim.c
@@ -816,6 +816,8 @@ char *yytext;
#define PIPE so_pipe[so_stack_ptr]
#include "dirname.h"
+#include "gl_linkedhash_list.h"
+#include "gl_xlist.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
@@ -826,6 +828,7 @@ char *yytext;
#include "manconfig.h"
#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "decompress.h"
@@ -845,12 +848,12 @@ static int so_line[MAX_SO_DEPTH];
static pipeline *so_pipe[MAX_SO_DEPTH];
static int so_stack_ptr;
static int no_newline;
-static char * const *so_manpathlist;
+static gl_list_t so_manpathlist;
static const char *so_parent_path;
struct zsoelim_stdin_data {
char *path;
- char * const *manpathlist;
+ gl_list_t manpathlist;
};
/* The flex documentation says that yyin is only used by YY_INPUT, so we
@@ -868,9 +871,9 @@ struct zsoelim_stdin_data {
result = YY_NULL; \
}
#define YY_NO_INPUT
-#line 872 "zsoelim.c"
+#line 875 "zsoelim.c"
-#line 874 "zsoelim.c"
+#line 877 "zsoelim.c"
#define INITIAL 0
#define so 1
@@ -1093,10 +1096,10 @@ YY_DECL
}
{
-#line 128 "zsoelim.l"
+#line 131 "zsoelim.l"
-#line 1100 "zsoelim.c"
+#line 1103 "zsoelim.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -1144,7 +1147,7 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 130 "zsoelim.l"
+#line 133 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1153,7 +1156,7 @@ YY_RULE_SETUP
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 136 "zsoelim.l"
+#line 139 "zsoelim.l"
{
no_newline = 1;
BEGIN (so); /* Now we're in the .so environment */
@@ -1161,7 +1164,7 @@ YY_RULE_SETUP
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 141 "zsoelim.l"
+#line 144 "zsoelim.l"
{
no_newline = 1;
ECHO; /* Now we're in the .lf environment */
@@ -1169,26 +1172,26 @@ YY_RULE_SETUP
}
YY_BREAK
case 4:
-#line 148 "zsoelim.l"
+#line 151 "zsoelim.l"
case 5:
/* rule 5 can match eol */
-#line 149 "zsoelim.l"
+#line 152 "zsoelim.l"
case 6:
/* rule 6 can match eol */
-#line 150 "zsoelim.l"
+#line 153 "zsoelim.l"
case 7:
/* rule 7 can match eol */
-#line 151 "zsoelim.l"
+#line 154 "zsoelim.l"
case 8:
/* rule 8 can match eol */
-#line 152 "zsoelim.l"
+#line 155 "zsoelim.l"
case 9:
/* rule 9 can match eol */
-#line 153 "zsoelim.l"
+#line 156 "zsoelim.l"
case 10:
/* rule 10 can match eol */
YY_RULE_SETUP
-#line 153 "zsoelim.l"
+#line 156 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1197,7 +1200,7 @@ YY_RULE_SETUP
case 11:
/* rule 11 can match eol */
YY_RULE_SETUP
-#line 158 "zsoelim.l"
+#line 161 "zsoelim.l"
{
no_newline = 0;
putchar ('\n');
@@ -1206,7 +1209,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 165 "zsoelim.l"
+#line 168 "zsoelim.l"
{ /* file names including whitespace ? */
if (so_stack_ptr == MAX_SO_DEPTH - 1)
error (FATAL, 0,
@@ -1242,7 +1245,7 @@ YY_RULE_SETUP
case 13:
/* rule 13 can match eol */
YY_RULE_SETUP
-#line 197 "zsoelim.l"
+#line 200 "zsoelim.l"
{
no_newline = 0;
BEGIN (INITIAL);
@@ -1251,7 +1254,7 @@ YY_RULE_SETUP
case 14:
/* rule 14 can match eol */
YY_RULE_SETUP
-#line 202 "zsoelim.l"
+#line 205 "zsoelim.l"
{
no_newline = 0;
error (OK, 0,
@@ -1265,7 +1268,7 @@ YY_RULE_SETUP
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 213 "zsoelim.l"
+#line 216 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1274,7 +1277,7 @@ YY_RULE_SETUP
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 219 "zsoelim.l"
+#line 222 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1283,7 +1286,7 @@ YY_RULE_SETUP
case 17:
/* rule 17 can match eol */
YY_RULE_SETUP
-#line 224 "zsoelim.l"
+#line 227 "zsoelim.l"
{
no_newline = 0;
putchar ('\n');
@@ -1292,7 +1295,7 @@ YY_RULE_SETUP
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 231 "zsoelim.l"
+#line 234 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1303,7 +1306,7 @@ YY_RULE_SETUP
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 239 "zsoelim.l"
+#line 242 "zsoelim.l"
{ /* file names including whitespace ?? */
no_newline = 1;
ECHO;
@@ -1317,7 +1320,7 @@ YY_RULE_SETUP
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 250 "zsoelim.l"
+#line 253 "zsoelim.l"
{
no_newline = 1;
ECHO;
@@ -1326,7 +1329,7 @@ YY_RULE_SETUP
case 21:
/* rule 21 can match eol */
YY_RULE_SETUP
-#line 255 "zsoelim.l"
+#line 258 "zsoelim.l"
{
no_newline = 0;
putchar ('\n');
@@ -1336,7 +1339,7 @@ YY_RULE_SETUP
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 262 "zsoelim.l"
+#line 265 "zsoelim.l"
{
no_newline = 1;
error (OK, 0,
@@ -1350,7 +1353,7 @@ YY_RULE_SETUP
case 23:
/* rule 23 can match eol */
YY_RULE_SETUP
-#line 272 "zsoelim.l"
+#line 275 "zsoelim.l"
{
no_newline = 0;
error (OK, 0,
@@ -1368,14 +1371,13 @@ case YY_STATE_EOF(de):
case YY_STATE_EOF(end_request):
case YY_STATE_EOF(lfnumber):
case YY_STATE_EOF(lfname):
-#line 283 "zsoelim.l"
+#line 286 "zsoelim.l"
{
pipeline_wait (PIPE);
pipeline_free (PIPE);
PIPE = NULL;
free (NAME);
NAME = NULL;
- so_manpathlist = NULL;
if (no_newline)
putchar ('\n');
@@ -1393,10 +1395,10 @@ case YY_STATE_EOF(lfname):
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 304 "zsoelim.l"
+#line 306 "zsoelim.l"
ECHO;
YY_BREAK
-#line 1400 "zsoelim.c"
+#line 1402 "zsoelim.c"
case YY_END_OF_BUFFER:
{
@@ -2355,7 +2357,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 304 "zsoelim.l"
+#line 306 "zsoelim.l"
#ifdef ACCEPT_QUOTES
@@ -2375,7 +2377,7 @@ static void zap_quotes (void)
#endif
/* initialise the stack and call the parser */
-void zsoelim_parse_file (char * const *manpathlist, const char *parent_path)
+void zsoelim_parse_file (gl_list_t manpathlist, const char *parent_path)
{
#ifdef PP_COOKIE
const char *line;
@@ -2432,11 +2434,10 @@ static pipeline *try_compressed (char **filename)
/* This routine is used to open the specified file or uncompress a compressed
version and open that instead */
-int zsoelim_open_file (const char *filename, char * const *manpathlist,
+int zsoelim_open_file (const char *filename, gl_list_t manpathlist,
const char *parent_path)
{
pipeline *decomp;
- char * const *mp;
if (parent_path)
debug ("opening %s (parent path: %s)\n",
@@ -2449,6 +2450,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
NAME = xstrdup (filename);
} else {
char *compfile;
+ const char *mp;
/* If there is no parent path, try opening directly first. */
if (!parent_path) {
@@ -2462,7 +2464,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- if (manpathlist && strchr (filename, '/')) {
+ if (strchr (filename, '/')) {
/* File name with a directory part. Try looking it
* up within each manpath entry.
*/
@@ -2479,11 +2481,11 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ GL_LIST_FOREACH_START (manpathlist, mp) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- compfile = xasprintf ("%s/%s.", *mp, filename);
+ compfile = xasprintf ("%s/%s.", mp, filename);
decomp = try_compressed (&compfile);
if (decomp) {
@@ -2492,14 +2494,14 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
}
free (compfile);
- }
- } else if (manpathlist) {
+ } GL_LIST_FOREACH_END (manpathlist);
+ } else {
/* File name with no directory part. Try searching
* the manpath.
*/
char *name, *sec, *dot;
- char **names;
- char **np;
+ gl_list_t names;
+ const char *found_name;
name = xstrdup (filename);
dot = strchr (name, '.');
@@ -2516,29 +2518,34 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
if (parent_path) {
names = look_for_file (parent_path, sec, name,
0, LFF_MATCHCASE);
- for (np = names; np && *np; ++np) {
- decomp = decompress_open (*np);
+ GL_LIST_FOREACH_START (names, found_name) {
+ decomp = decompress_open (found_name);
if (decomp) {
- NAME = xstrdup (*np);
+ NAME = xstrdup (found_name);
+ gl_list_free (names);
goto out;
}
- }
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ GL_LIST_FOREACH_START (manpathlist, mp) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- names = look_for_file (*mp, sec, name,
+ names = look_for_file (mp, sec, name,
0, LFF_MATCHCASE);
- for (np = names; np && *np; ++np) {
- decomp = decompress_open (*np);
+ GL_LIST_FOREACH_START (names, found_name) {
+ decomp = decompress_open (found_name);
if (decomp) {
- NAME = xstrdup (*np);
+ NAME = xstrdup (found_name);
+ gl_list_free (names);
+ free (name);
goto out;
}
- }
- }
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
+ } GL_LIST_FOREACH_END (manpathlist);
free (name);
}
@@ -2575,13 +2582,17 @@ out:
void zsoelim_stdin (void *data)
{
struct zsoelim_stdin_data *zsoelim_data = data;
+ gl_list_t empty;
- zsoelim_open_file ("-", NULL, zsoelim_data->path);
+ empty = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, NULL,
+ true);
+ zsoelim_open_file ("-", empty, zsoelim_data->path);
+ gl_list_free (empty);
zsoelim_parse_file (zsoelim_data->manpathlist, zsoelim_data->path);
}
struct zsoelim_stdin_data *zsoelim_stdin_data_new (const char *path,
- char * const *manpathlist)
+ gl_list_t manpathlist)
{
struct zsoelim_stdin_data *data = XMALLOC (struct zsoelim_stdin_data);
diff --git a/src/zsoelim.h b/src/zsoelim.h
index f17c08e8..4aaf53d6 100644
--- a/src/zsoelim.h
+++ b/src/zsoelim.h
@@ -20,13 +20,15 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-int zsoelim_open_file (const char *filename, char * const *manpathlist,
+#include "gl_list.h"
+
+int zsoelim_open_file (const char *filename, gl_list_t manpathlist,
const char *parent_path);
-void zsoelim_parse_file (char * const *manpathlist, const char *parent_path);
+void zsoelim_parse_file (gl_list_t manpathlist, const char *parent_path);
struct zsoelim_stdin_data;
void zsoelim_stdin (void *data);
struct zsoelim_stdin_data *zsoelim_stdin_data_new (const char *path,
- char * const *manpathlist);
+ gl_list_t manpathlist);
void zsoelim_stdin_data_free (void *data);
diff --git a/src/zsoelim.l b/src/zsoelim.l
index b3dc7807..346dfbd3 100644
--- a/src/zsoelim.l
+++ b/src/zsoelim.l
@@ -59,6 +59,8 @@
#define PIPE so_pipe[so_stack_ptr]
#include "dirname.h"
+#include "gl_linkedhash_list.h"
+#include "gl_xlist.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
@@ -69,6 +71,7 @@
#include "manconfig.h"
#include "error.h"
+#include "glcontainers.h"
#include "pipeline.h"
#include "decompress.h"
@@ -88,12 +91,12 @@ static int so_line[MAX_SO_DEPTH];
static pipeline *so_pipe[MAX_SO_DEPTH];
static int so_stack_ptr;
static int no_newline;
-static char * const *so_manpathlist;
+static gl_list_t so_manpathlist;
static const char *so_parent_path;
struct zsoelim_stdin_data {
char *path;
- char * const *manpathlist;
+ gl_list_t manpathlist;
};
/* The flex documentation says that yyin is only used by YY_INPUT, so we
@@ -286,7 +289,6 @@ W [ \t]
PIPE = NULL;
free (NAME);
NAME = NULL;
- so_manpathlist = NULL;
if (no_newline)
putchar ('\n');
@@ -320,7 +322,7 @@ static void zap_quotes (void)
#endif
/* initialise the stack and call the parser */
-void zsoelim_parse_file (char * const *manpathlist, const char *parent_path)
+void zsoelim_parse_file (gl_list_t manpathlist, const char *parent_path)
{
#ifdef PP_COOKIE
const char *line;
@@ -377,11 +379,10 @@ static pipeline *try_compressed (char **filename)
/* This routine is used to open the specified file or uncompress a compressed
version and open that instead */
-int zsoelim_open_file (const char *filename, char * const *manpathlist,
+int zsoelim_open_file (const char *filename, gl_list_t manpathlist,
const char *parent_path)
{
pipeline *decomp;
- char * const *mp;
if (parent_path)
debug ("opening %s (parent path: %s)\n",
@@ -394,6 +395,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
NAME = xstrdup (filename);
} else {
char *compfile;
+ const char *mp;
/* If there is no parent path, try opening directly first. */
if (!parent_path) {
@@ -407,7 +409,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- if (manpathlist && strchr (filename, '/')) {
+ if (strchr (filename, '/')) {
/* File name with a directory part. Try looking it
* up within each manpath entry.
*/
@@ -424,11 +426,11 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ GL_LIST_FOREACH_START (manpathlist, mp) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- compfile = xasprintf ("%s/%s.", *mp, filename);
+ compfile = xasprintf ("%s/%s.", mp, filename);
decomp = try_compressed (&compfile);
if (decomp) {
@@ -437,14 +439,14 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
}
free (compfile);
- }
- } else if (manpathlist) {
+ } GL_LIST_FOREACH_END (manpathlist);
+ } else {
/* File name with no directory part. Try searching
* the manpath.
*/
char *name, *sec, *dot;
- char **names;
- char **np;
+ gl_list_t names;
+ const char *found_name;
name = xstrdup (filename);
dot = strchr (name, '.');
@@ -461,29 +463,34 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
if (parent_path) {
names = look_for_file (parent_path, sec, name,
0, LFF_MATCHCASE);
- for (np = names; np && *np; ++np) {
- decomp = decompress_open (*np);
+ GL_LIST_FOREACH_START (names, found_name) {
+ decomp = decompress_open (found_name);
if (decomp) {
- NAME = xstrdup (*np);
+ NAME = xstrdup (found_name);
+ gl_list_free (names);
goto out;
}
- }
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ GL_LIST_FOREACH_START (manpathlist, mp) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- names = look_for_file (*mp, sec, name,
+ names = look_for_file (mp, sec, name,
0, LFF_MATCHCASE);
- for (np = names; np && *np; ++np) {
- decomp = decompress_open (*np);
+ GL_LIST_FOREACH_START (names, found_name) {
+ decomp = decompress_open (found_name);
if (decomp) {
- NAME = xstrdup (*np);
+ NAME = xstrdup (found_name);
+ gl_list_free (names);
+ free (name);
goto out;
}
- }
- }
+ } GL_LIST_FOREACH_END (names);
+ gl_list_free (names);
+ } GL_LIST_FOREACH_END (manpathlist);
free (name);
}
@@ -520,13 +527,17 @@ out:
void zsoelim_stdin (void *data)
{
struct zsoelim_stdin_data *zsoelim_data = data;
+ gl_list_t empty;
- zsoelim_open_file ("-", NULL, zsoelim_data->path);
+ empty = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, NULL,
+ true);
+ zsoelim_open_file ("-", empty, zsoelim_data->path);
+ gl_list_free (empty);
zsoelim_parse_file (zsoelim_data->manpathlist, zsoelim_data->path);
}
struct zsoelim_stdin_data *zsoelim_stdin_data_new (const char *path,
- char * const *manpathlist)
+ gl_list_t manpathlist)
{
struct zsoelim_stdin_data *data = XMALLOC (struct zsoelim_stdin_data);
diff --git a/src/zsoelim_main.c b/src/zsoelim_main.c
index ef6d1b67..da0b0fa0 100644
--- a/src/zsoelim_main.c
+++ b/src/zsoelim_main.c
@@ -27,9 +27,11 @@
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <stdbool.h>
#include <stdlib.h>
#include "argp.h"
+#include "gl_list.h"
#include "progname.h"
#include "xvasprintf.h"
@@ -52,7 +54,7 @@
int quiet = 1;
man_sandbox *sandbox;
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
static char **files;
static int num_files;
@@ -75,7 +77,7 @@ static error_t parse_opt (int key, char *arg ATTRIBUTE_UNUSED,
{
switch (key) {
case 'd':
- debug_level = 1;
+ debug_level = true;
return 0;
case 'C':
return 0; /* compatibility with GNU soelim */
@@ -140,7 +142,7 @@ int main (int argc, char *argv[])
manp = add_nls_manpaths (get_manpath (NULL), all_locales);
free (all_locales);
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
/* parse files in command line order */
for (i = 0; i < num_files; ++i) {
@@ -152,6 +154,7 @@ int main (int argc, char *argv[])
free_pathlist (manpathlist);
free (manp);
free (internal_locale);
+ sandbox_free (sandbox);
return OK;
}