[PATCH] man: allow multiple paths in MANPATH

walter harms wharms at bfs.de
Thu Nov 27 08:28:27 UTC 2014


wow, fast response.

the glibc has a group of functions for handling argz vectors.
Maybe this is a way to save some bytes ? (see: man 3 argz_create).
Note this is a GNU extension.

re,
 wh

Am 27.11.2014 01:32, schrieb Marcel Rodrigues:
> Thanks for the feedback.
> 
> The patch below unifies the code in a separated function. I have considered
> using the strchr() approach, but ended up using strtok() because it is
> simpler and both approaches required a writable buffer anyway. While it's
> possible to refactor the new function to work with read-only buffers (such
> as the one directly returned by getenv()), I don't know if it is worth the
> trouble -- that would only remove one xstrdup()+free() pair.
> 
> Maybe it's also worth mentioning that this patch makes it simple (in
> theory) to add a GNU-like option -M to man, which is just another way to
> specify a path list. That may be overkill, though.
> 
> Signed-off-by: Marcel Rodrigues <marcelgmr at gmail.com>
> ---
>  miscutils/man.c | 67
> ++++++++++++++++++++++++++-------------------------------
>  1 file changed, 31 insertions(+), 36 deletions(-)
> 
> diff --git a/miscutils/man.c b/miscutils/man.c
> index 5c1fa2c..8959f5e 100644
> --- a/miscutils/man.c
> +++ b/miscutils/man.c
> @@ -147,12 +147,37 @@ static int show_manpage(const char *pager, char
> *man_filename, int man, int leve
>   return run_pipe(pager, man_filename, man, level);
>  }
> 
> +static int add_man_paths(char ***man_path_list, int idx, char *man_paths)
> +{
> + char *path;
> + if (man_paths == NULL)
> + return idx;
> + path = strtok(man_paths, ":");
> + while (path) {
> + char **path_element;
> + /* Do we already have path? */
> + path_element = *man_path_list;
> + while (*path_element) {
> + if (strcmp(*path_element, path) == 0)
> + goto next;
> + path_element++;
> + }
> + *man_path_list = xrealloc_vector(*man_path_list, 4, idx);
> + (*man_path_list)[idx] = xstrdup(path);
> + idx++;
> + next:
> + path = strtok(NULL, ":");
> + }
> + return idx;
> +}
> +
>  int man_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
>  int man_main(int argc UNUSED_PARAM, char **argv)
>  {
>   parser_t *parser;
>   const char *pager = ENABLE_LESS ? "less" : "more";
>   char **man_path_list;
> + char *man_paths;
>   char *sec_list;
>   char *cur_path, *cur_sect;
>   int count_mp, cur_mp;
> @@ -165,13 +190,12 @@ int man_main(int argc UNUSED_PARAM, char **argv)
> 
>   sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9");
>   /* Last valid man_path_list[] is [0x10] */
> - count_mp = 0;
>   man_path_list = xzalloc(0x11 * sizeof(man_path_list[0]));
> - man_path_list[0] = getenv("MANPATH");
> - if (!man_path_list[0]) /* default, may be overridden by /etc/man.conf */
> + man_paths = xstrdup(getenv("MANPATH"));
> + count_mp = add_man_paths(&man_path_list, 0, man_paths);
> + free(man_paths);
> + if (!count_mp) /* default, may be overridden by /etc/man.conf */
>   man_path_list[0] = (char*)"/usr/man";
> - else
> - count_mp++;
> 
>   /* Parse man.conf[ig] or man_db.conf */
>   /* man version 1.6f uses man.config */
> @@ -192,37 +216,8 @@ int man_main(int argc UNUSED_PARAM, char **argv)
>   } else
>   if (strcmp("MANDATORY_MANPATH"+10, token[0]) == 0 /* "MANPATH"? */
>   || strcmp("MANDATORY_MANPATH", token[0]) == 0
> - ) {
> - char *path = token[1];
> - while (*path) {
> - char *next_path;
> - char **path_element;
> -
> - next_path = strchr(path, ':');
> - if (next_path) {
> - *next_path = '\0';
> - if (next_path++ == path) /* "::"? */
> - goto next;
> - }
> - /* Do we already have path? */
> - path_element = man_path_list;
> - while (*path_element) {
> - if (strcmp(*path_element, path) == 0)
> - goto skip;
> - path_element++;
> - }
> - man_path_list = xrealloc_vector(man_path_list, 4, count_mp);
> - man_path_list[count_mp] = xstrdup(path);
> - count_mp++;
> - /* man_path_list is NULL terminated */
> - /*man_path_list[count_mp] = NULL; - xrealloc_vector did it */
> - skip:
> - if (!next_path)
> - break;
> - next:
> - path = next_path;
> - }
> - }
> + )
> + count_mp = add_man_paths(&man_path_list, count_mp, token[1]);
>   if (strcmp("MANSECT", token[0]) == 0) {
>   free(sec_list);
>   sec_list = xstrdup(token[1]);
> 
> 
> 
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list