From 5280f9a0cd1f9ba200422ebba65d1e0133410995 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 13 Sep 2014 09:43:21 -0700 Subject: Initial. --- src/man-getopt.c | 322 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 src/man-getopt.c (limited to 'src/man-getopt.c') diff --git a/src/man-getopt.c b/src/man-getopt.c new file mode 100644 index 0000000..07aecdb --- /dev/null +++ b/src/man-getopt.c @@ -0,0 +1,322 @@ +#include +#include +#include +#include + +#include "defs.h" +#include "gripes.h" +#include "man.h" +#include "man-config.h" +#include "man-getopt.h" +#include "util.h" +#include "version.h" + +int alt_system; +char *alt_system_name; +char *opt_manpath; +int global_apropos = 0; + +static void +print_version (void) { + gripe (VERSION, progname, version); +} + +static void +usage (void) { + print_version(); + gripe (USAGE1, progname); + + gripe (USAGE2); /* only for alt_systems */ + + gripe (USAGE3); + gripe (USAGE4); + gripe (USAGE5); /* maybe only if troff found? */ + gripe (USAGE6); + + gripe (USAGE7); /* only for alt_systems */ + + gripe (USAGE8); + exit(1); +} + +static char short_opts[] = "B:C:H:xM:P:S:acdDfFhkKm:p:s:tvVwW?"; + +#ifndef NOGETOPT +#undef _GNU_SOURCE +#define _GNU_SOURCE +#include + +static const struct option long_opts[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { "path", no_argument, NULL, 'w' }, + { "preformat", no_argument, NULL, 'F' }, + { NULL, 0, NULL, 0 } +}; +#endif + +/* + * Read options, return count. + */ +static int +get_options_from_argvec(int argc, char **argv, char **config_file, + char **manpath) { + char *s; + int c; + int optct = 0; + +#ifndef NOGETOPT + while ((c = getopt_long (argc, argv, short_opts, long_opts, NULL)) != -1){ +#else + while ((c = getopt (argc, argv, short_opts)) != -1) { +#endif + switch (c) { + case 'C': + no_privileges (); + if (config_file) + *config_file = my_strdup (optarg); + break; + case'F': + preformat = 1; + break; + case 'M': + if (manpath) + *manpath = my_strdup (optarg); + break; + case 'P': + pager = my_strdup (optarg); + break; + case 'B': + browser = my_strdup (optarg); + break; + case 'H': + htmlpager = my_strdup (optarg); + break; + case 'S': + colon_sep_section_list = my_strdup (optarg); + break; + case 's': + /* undocumented; compatibility with Sun */ + s = colon_sep_section_list = my_strdup (optarg); + while (*s) { + if (*s == ',') + *s = ':'; + s++; + } + break; + case 'a': + findall++; + break; + case 'c': + nocats++; + break; + case 'D': + debug++; + case 'd': + debug++; + break; + case 'f': + if (do_troff) + fatal (INCOMPAT, "-f", "-t"); + if (apropos) + fatal (INCOMPAT, "-f", "-k"); + if (print_where) + fatal (INCOMPAT, "-f", "-w"); + whatis++; + break; + case 'k': + if (do_troff) + fatal (INCOMPAT, "-k", "-t"); + if (whatis) + fatal (INCOMPAT, "-k", "-f"); + if (print_where) + fatal (INCOMPAT, "-k", "-w"); + apropos++; + break; + case 'K': + global_apropos++; + break; + case 'm': + alt_system++; + alt_system_name = my_strdup (optarg); + break; + /* or: gripe (NO_ALTERNATE); exit(1); */ + case 'p': + roff_directive = my_strdup (optarg); + break; + case 't': + if (apropos) + fatal (INCOMPAT, "-t", "-k"); + if (whatis) + fatal (INCOMPAT, "-t", "-f"); + if (print_where) + fatal (INCOMPAT, "-t", "-w"); + do_troff++; + break; + case 'v': + case 'V': + print_version(); + exit(0); + case 'W': + one_per_line++; + /* fall through */ + case 'w': + if (apropos) + fatal (INCOMPAT, "-w", "-k"); + if (whatis) + fatal (INCOMPAT, "-w", "-f"); + if (do_troff) + fatal (INCOMPAT, "-w", "-t"); + print_where++; + break; + case 'h': + case '?': + default: + usage(); + break; + } + optct++; + } + + return optct; +} + +static void +get_options_from_string(const char *s) { + char *s0, *ss; + int argct; + char **argvec; + int optindsv; + + if (!s || *s == 0) + return; + + /* In order to avoid having a list of options in two places, + massage the string so that it can be fed to getopt() */ + + s0 = my_strdup(s); + + /* count arguments */ + argct = 0; + ss = s0; + while (*ss) { + while (*ss == ' ') + ss++; + if (*ss) { + argct++; + while (*ss && *ss != ' ') + ss++; + } + } + + /* allocate argvec */ + argvec = (char **) my_malloc((argct+2)*sizeof(char *)); + argct = 0; + argvec[argct++] = "dummy"; + ss = s0; + while (*ss) { + while (*ss == ' ') + *ss++ = 0; + if (*ss) { + argvec[argct++] = ss; + while (*ss && *ss != ' ') + ss++; + } + } + argvec[argct] = 0; + + optindsv = optind; + optind = 1; + get_options_from_argvec(argct, argvec, NULL, NULL); + optind = optindsv; +} + +static void +mysetenv(const char *name, const char *value) { +#if defined(__sgi__) || defined(__sun__) || defined(sun) + int len = strlen(value)+1+strlen(value)+1; + char *str = my_malloc(len); + sprintf(str, "%s=%s", name, value); + putenv(str); +#else + setenv(name, value, 1); +#endif +} + +/* + * Get options from the command line and user environment. + * Also reads the configuration file. + */ + +void +man_getopt (int argc, char **argv) { + char *config_file = NULL; + char *manp = NULL; + int optct = 0; + + optct = get_options_from_argvec(argc, argv, &config_file, &manp); + + read_config_file (config_file); + + /* If no options were given and MANDEFOPTIONS is set, use that */ + if (optct == 0) { + const char *defopts = getval ("MANDEFOPTIONS"); + get_options_from_string(defopts); + } + + /* In case an explicit -P option was given, put it in the + environment for possible use with -k or -K. + Ignore errors (out of memory?) */ + + if (pager && (global_apropos || apropos || whatis)) + mysetenv("PAGER", pager); + + if (pager == NULL || *pager == '\0') + if (((pager = getenv ("MANPAGER")) == NULL) || (*pager == '\0')) + if (((pager = getenv ("PAGER")) == NULL) || (*pager == '\0')) + pager = getval ("PAGER"); + + if (debug) + gripe (PAGER_IS, pager); + + /* Ditto for BROWSER and -B */ + if (browser && (global_apropos || apropos || whatis)) + mysetenv("BROWSER", browser); + + if (browser == NULL || *browser == '\0') + if ((browser = getenv ("BROWSER")) == NULL) + browser = getval ("BROWSER"); + + if (debug) + gripe (BROWSER_IS, browser); + + /* Ditto for HTMLHTMLPAGER and -H */ + if (htmlpager && (global_apropos || apropos || whatis)) + mysetenv("HTMLPAGER", htmlpager); + + if (htmlpager == NULL || *htmlpager == '\0') + if ((htmlpager = getenv ("HTMLPAGER")) == NULL) + htmlpager = getval ("HTMLPAGER"); + + if (debug) + gripe (HTMLPAGER_IS, htmlpager); + + if (do_compress && !*getval ("COMPRESS")) { + if (debug) + gripe (NO_COMPRESS); + do_compress = 0; + } + + if (do_troff && !*getval ("TROFF")) { + gripe (NO_TROFF, configuration_file); + exit (1); + } + + opt_manpath = manp; /* do not yet expand manpath - + maybe it is not needed */ + + if (alt_system_name == NULL || *alt_system_name == '\0') + if ((alt_system_name = getenv ("SYSTEM")) != NULL) + alt_system_name = my_strdup (alt_system_name); + +} -- cgit v1.2.3