[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/main.c between version 1.178 and 1.182

version 1.178, 2014/08/10 23:54:41 version 1.182, 2014/08/21 00:32:15
Line 32 
Line 32 
 #include "main.h"  #include "main.h"
 #include "mdoc.h"  #include "mdoc.h"
 #include "man.h"  #include "man.h"
   #include "manpath.h"
   #include "mansearch.h"
   
 #if !defined(__GNUC__) || (__GNUC__ < 2)  #if !defined(__GNUC__) || (__GNUC__ < 2)
 # if !defined(lint)  # if !defined(lint)
Line 39 
Line 41 
 # endif  # endif
 #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */  #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
   
   enum    outmode {
           OUTMODE_DEF = 0,
           OUTMODE_FLN,
           OUTMODE_LST,
           OUTMODE_ALL,
           OUTMODE_INT,
           OUTMODE_ONE
   };
   
 typedef void            (*out_mdoc)(void *, const struct mdoc *);  typedef void            (*out_mdoc)(void *, const struct mdoc *);
 typedef void            (*out_man)(void *, const struct man *);  typedef void            (*out_man)(void *, const struct man *);
 typedef void            (*out_free)(void *);  typedef void            (*out_free)(void *);
Line 74  static void    mmsg(enum mandocerr, enum mandoclevel,
Line 85  static void    mmsg(enum mandocerr, enum mandoclevel,
 static  void              parse(struct curparse *, int,  static  void              parse(struct curparse *, int,
                                 const char *, enum mandoclevel *);                                  const char *, enum mandoclevel *);
 static  int               toptions(struct curparse *, char *);  static  int               toptions(struct curparse *, char *);
 static  void              usage(void) __attribute__((noreturn));  static  void              usage(enum argmode) __attribute__((noreturn));
 static  void              version(void) __attribute__((noreturn));  static  void              version(void) __attribute__((noreturn));
 static  int               woptions(struct curparse *, char *);  static  int               woptions(struct curparse *, char *);
   
   static  const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
 static  const char       *progname;  static  const char       *progname;
   
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int              c;  
         struct curparse  curp;          struct curparse  curp;
         int              options;          struct mansearch search;
         enum mandoclevel rc;          struct manpaths  paths;
           char            *conf_file, *defpaths, *auxpaths;
         char            *defos;          char            *defos;
   #if HAVE_SQLITE3
           struct manpage  *res;
           char            **auxargv;
           size_t           isec, i, sz;
           int              prio, best_prio;
           char             sec;
   #endif
           enum mandoclevel rc;
           enum outmode     outmode;
           int              show_usage;
           int              options;
           int              c;
   
         progname = strrchr(argv[0], '/');          progname = strrchr(argv[0], '/');
         if (progname == NULL)          if (progname == NULL)
Line 96  main(int argc, char *argv[])
Line 120  main(int argc, char *argv[])
         else          else
                 ++progname;                  ++progname;
   
         memset(&curp, 0, sizeof(struct curparse));          /* Search options. */
   
         options = MPARSE_SO;          memset(&paths, 0, sizeof(struct manpaths));
           conf_file = defpaths = auxpaths = NULL;
   
           memset(&search, 0, sizeof(struct mansearch));
           search.outkey = "Nd";
   
           if (strcmp(progname, "man") == 0)
                   search.argmode = ARG_NAME;
           else if (strncmp(progname, "apropos", 7) == 0)
                   search.argmode = ARG_EXPR;
           else if (strncmp(progname, "whatis", 6) == 0)
                   search.argmode = ARG_WORD;
           else
                   search.argmode = ARG_FILE;
   
           /* Parser and formatter options. */
   
           memset(&curp, 0, sizeof(struct curparse));
         curp.outtype = OUTT_ASCII;          curp.outtype = OUTT_ASCII;
         curp.wlevel  = MANDOCLEVEL_FATAL;          curp.wlevel  = MANDOCLEVEL_FATAL;
           options = MPARSE_SO;
         defos = NULL;          defos = NULL;
   
         while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))          show_usage = 0;
           outmode = OUTMODE_DEF;
           while (-1 != (c = getopt(argc, argv, "aC:fI:ikM:m:O:S:s:T:VW:w"))) {
                 switch (c) {                  switch (c) {
                   case 'a':
                           outmode = OUTMODE_ALL;
                           break;
                   case 'C':
                           conf_file = optarg;
                           break;
                   case 'f':
                           search.argmode = ARG_WORD;
                           break;
                 case 'I':                  case 'I':
                         if (strncmp(optarg, "os=", 3)) {                          if (strncmp(optarg, "os=", 3)) {
                                 fprintf(stderr,                                  fprintf(stderr,
Line 120  main(int argc, char *argv[])
Line 173  main(int argc, char *argv[])
                         }                          }
                         defos = mandoc_strdup(optarg + 3);                          defos = mandoc_strdup(optarg + 3);
                         break;                          break;
                   case 'i':
                           outmode = OUTMODE_INT;
                           break;
                   case 'k':
                           search.argmode = ARG_EXPR;
                           break;
                   case 'M':
                           defpaths = optarg;
                           break;
                 case 'm':                  case 'm':
                         if ( ! moptions(&options, optarg))                          auxpaths = optarg;
                                 return((int)MANDOCLEVEL_BADARG);  
                         break;                          break;
                 case 'O':                  case 'O':
                           search.outkey = optarg;
                         (void)strlcat(curp.outopts, optarg, BUFSIZ);                          (void)strlcat(curp.outopts, optarg, BUFSIZ);
                         (void)strlcat(curp.outopts, ",", BUFSIZ);                          (void)strlcat(curp.outopts, ",", BUFSIZ);
                         break;                          break;
                   case 'S':
                           search.arch = optarg;
                           break;
                   case 's':
                           search.sec = optarg;
                           break;
                 case 'T':                  case 'T':
                         if ( ! toptions(&curp, optarg))                          if ( ! toptions(&curp, optarg))
                                 return((int)MANDOCLEVEL_BADARG);                                  return((int)MANDOCLEVEL_BADARG);
Line 136  main(int argc, char *argv[])
Line 204  main(int argc, char *argv[])
                         if ( ! woptions(&curp, optarg))                          if ( ! woptions(&curp, optarg))
                                 return((int)MANDOCLEVEL_BADARG);                                  return((int)MANDOCLEVEL_BADARG);
                         break;                          break;
                   case 'w':
                           outmode = OUTMODE_FLN;
                           break;
                 case 'V':                  case 'V':
                         version();                          version();
                         /* NOTREACHED */                          /* NOTREACHED */
                 default:                  default:
                         usage();                          show_usage = 1;
                         /* NOTREACHED */                          break;
                 }                  }
           }
   
           if (show_usage)
                   usage(search.argmode);
   
           if (outmode == OUTMODE_DEF) {
                   switch (search.argmode) {
                   case ARG_FILE:
                           outmode = OUTMODE_ALL;
                           break;
                   case ARG_NAME:
                           outmode = OUTMODE_ONE;
                           break;
                   default:
                           outmode = OUTMODE_LST;
                           break;
                   }
           }
   
           argc -= optind;
           argv += optind;
   #if HAVE_SQLITE3
           auxargv = NULL;
   #endif
   
           rc = MANDOCLEVEL_OK;
   
           /* man(1), whatis(1), apropos(1) */
   
           if (search.argmode != ARG_FILE) {
   #if HAVE_SQLITE3
                   if (argc == 0)
                           usage(search.argmode);
   
                   /* Access the mandoc database. */
   
                   manpath_parse(&paths, conf_file, defpaths, auxpaths);
                   mansearch_setup(1);
                   if( ! mansearch(&search, &paths, argc, argv, &res, &sz))
                           usage(search.argmode);
                   manpath_free(&paths);
   
                   /*
                    * For standard man(1) and -a output mode,
                    * prepare for copying filename pointers
                    * into the program parameter array.
                    */
   
                   if (outmode == OUTMODE_ONE) {
                           argc = 1;
                           argv[0] = res[0].file;
                           argv[1] = NULL;
                           best_prio = 10;
                   } else if (outmode == OUTMODE_ALL) {
                           argc = (int)sz;
                           argv = auxargv = mandoc_reallocarray(
                               NULL, sz + 1, sizeof(char *));
                           argv[argc] = NULL;
                   }
   
                   /* Iterate all matching manuals. */
   
                   for (i = 0; i < sz; i++) {
                           if (outmode == OUTMODE_FLN)
                                   puts(res[i].file);
                           else if (outmode == OUTMODE_LST)
                                   printf("%s - %s\n", res[i].names,
                                       res[i].output == NULL ? "" :
                                       res[i].output);
                           else if (outmode == OUTMODE_ALL)
                                   argv[i] = res[i].file;
                           else {
                                   /* Search for the best section. */
                                   isec = strcspn(res[i].file, "123456789");
                                   sec = res[i].file[isec];
                                   if ('\0' == sec)
                                           continue;
                                   prio = sec_prios[sec - '1'];
                                   if (prio >= best_prio)
                                           continue;
                                   best_prio = prio;
                                   argv[0] = res[i].file;
                           }
                   }
   
                   /*
                    * For man(1), -a and -i output mode, fall through
                    * to the main mandoc(1) code iterating files
                    * and running the parsers on each of them.
                    */
   
                   if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST)
                           goto out;
   #else
                   fputs("mandoc: database support not compiled in\n",
                       stderr);
                   return((int)MANDOCLEVEL_BADARG);
   #endif
           }
   
           /* mandoc(1) */
   
           if ( ! moptions(&options, auxpaths))
                   return((int)MANDOCLEVEL_BADARG);
   
         curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);          curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
   
         /*          /*
Line 152  main(int argc, char *argv[])
Line 327  main(int argc, char *argv[])
         if (OUTT_MAN == curp.outtype)          if (OUTT_MAN == curp.outtype)
                 mparse_keep(curp.mp);                  mparse_keep(curp.mp);
   
         argc -= optind;  
         argv += optind;  
   
         rc = MANDOCLEVEL_OK;  
   
         if (NULL == *argv)          if (NULL == *argv)
                 parse(&curp, STDIN_FILENO, "<stdin>", &rc);                  parse(&curp, STDIN_FILENO, "<stdin>", &rc);
   
Line 171  main(int argc, char *argv[])
Line 341  main(int argc, char *argv[])
                 (*curp.outfree)(curp.outdata);                  (*curp.outfree)(curp.outdata);
         if (curp.mp)          if (curp.mp)
                 mparse_free(curp.mp);                  mparse_free(curp.mp);
   
   #if HAVE_SQLITE3
   out:
           if (search.argmode != ARG_FILE) {
                   mansearch_free(res, sz);
                   mansearch_setup(0);
                   free(auxargv);
           }
   #endif
   
         free(defos);          free(defos);
   
         return((int)rc);          return((int)rc);
Line 180  static void
Line 360  static void
 version(void)  version(void)
 {  {
   
         printf("%s %s\n", progname, VERSION);          printf("mandoc %s\n", VERSION);
         exit((int)MANDOCLEVEL_OK);          exit((int)MANDOCLEVEL_OK);
 }  }
   
 static void  static void
 usage(void)  usage(enum argmode argmode)
 {  {
   
         fprintf(stderr, "usage: %s "          switch (argmode) {
                         "[-V] "          case ARG_FILE:
                         "[-Ios=name] "                  fputs("usage: mandoc [-V] [-Ios=name] [-mformat]"
                         "[-mformat] "                      " [-Ooption] [-Toutput] [-Wlevel]\n"
                         "[-Ooption] "                      "\t      [file ...]\n", stderr);
                         "[-Toutput] "                  break;
                         "[-Wlevel]\n"          case ARG_NAME:
                         "\t      [file ...]\n",                  fputs("usage: man [-acfhkVw] [-C file] "
                         progname);                      "[-M path] [-m path] [-S arch] [-s section]\n"
                       "\t   [section] name ...\n", stderr);
                   break;
           case ARG_WORD:
                   fputs("usage: whatis [-V] [-C file] [-M path] [-m path] "
                       "[-S arch] [-s section] name ...\n", stderr);
                   break;
           case ARG_EXPR:
                   fputs("usage: apropos [-V] [-C file] [-M path] [-m path] "
                       "[-O outkey] [-S arch]\n"
                       "\t       [-s section] expression ...\n", stderr);
                   break;
           }
         exit((int)MANDOCLEVEL_BADARG);          exit((int)MANDOCLEVEL_BADARG);
 }  }
   
Line 318  static int
Line 509  static int
 moptions(int *options, char *arg)  moptions(int *options, char *arg)
 {  {
   
         if (0 == strcmp(arg, "doc"))          if (arg == NULL)
                   /* nothing to do */;
           else if (0 == strcmp(arg, "doc"))
                 *options |= MPARSE_MDOC;                  *options |= MPARSE_MDOC;
         else if (0 == strcmp(arg, "andoc"))          else if (0 == strcmp(arg, "andoc"))
                 /* nothing to do */;                  /* nothing to do */;

Legend:
Removed from v.1.178  
changed lines
  Added in v.1.182

CVSweb