"Fossies" - the Fresh Open Source Software Archive

Member "udns-0.4/getopt.c" (5 Jul 2011, 3948 Bytes) of package /linux/misc/dns/udns-0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "getopt.c" see the Fossies "Dox" file reference documentation.

    1 /* getopt.c
    2  * Simple getopt() implementation.
    3  *
    4  * Standard interface:
    5  *  extern int getopt(int argc, char *const *argv, const char *opts);
    6  *  extern int optind;    current index in argv[]
    7  *  extern char *optarg;  argument for the current option
    8  *  extern int optopt;    the current option
    9  *  extern int opterr;    to control error printing
   10  *
   11  * Some minor extensions:
   12  *  ignores leading `+' sign in opts[] (unemplemented GNU extension)
   13  *  handles optional arguments, in form "x::" in opts[]
   14  *  if opts[] starts with `:', will return `:' in case of missing required
   15  *    argument, instead of '?'.
   16  *
   17  * Compile with -DGETOPT_NO_OPTERR to never print errors internally.
   18  * Compile with -DGETOPT_NO_STDIO to use write() calls instead of fprintf() for
   19  *  error reporting (ignored with -DGETOPT_NO_OPTERR).
   20  * Compile with -DGETOPT_CLASS=static to get static linkage.
   21  * Compile with -DGETOPT_MY to redefine all visible symbols to be prefixed
   22  *  with "my_", like my_getopt instead of getopt.
   23  * Compile with -DTEST to get a test executable.
   24  *
   25  * Written by Michael Tokarev.  Public domain.
   26  */
   27 
   28 #include <string.h>
   29 
   30 #ifndef GETOPT_CLASS
   31 # define GETOPT_CLASS
   32 #endif
   33 #ifdef GETOPT_MY
   34 # define optarg my_optarg
   35 # define optind my_optind
   36 # define opterr my_opterr
   37 # define optopt my_optopt
   38 # define getopt my_getopt
   39 #endif
   40 
   41 GETOPT_CLASS char *optarg /* = NULL */;
   42 GETOPT_CLASS int optind = 1;
   43 GETOPT_CLASS int opterr = 1;
   44 GETOPT_CLASS int optopt;
   45 
   46 static char *nextc /* = NULL */;
   47 
   48 #if defined(GETOPT_NO_OPTERR)
   49 
   50 #define printerr(argv, msg)
   51 
   52 #elif defined(GETOPT_NO_STDIO)
   53 
   54 extern int write(int, void *, int);
   55 
   56 static void printerr(char *const *argv, const char *msg) {
   57   if (opterr) {
   58     char buf[64];
   59     unsigned pl = strlen(argv[0]);
   60     unsigned ml = strlen(msg);
   61     char *p;
   62     if (pl + /*": "*/2 + ml + /*" -- c\n"*/6 > sizeof(buf)) {
   63       write(2, argv[0], pl);
   64       p = buf;
   65     }
   66     else {
   67       memcpy(buf, argv[0], ml);
   68       p = buf + pl;
   69     }
   70     *p++ = ':'; *p++ = ' ';
   71     memcpy(p, msg, ml); p += ml;
   72     *p++ = ' '; *p++ = '-'; *p++ = '-'; *p++ = ' ';
   73     *p++ = optopt;
   74     *p++ = '\n';
   75     write(2, buf, p - buf);
   76   }
   77 }
   78 
   79 #else
   80 
   81 #include <stdio.h>
   82 static void printerr(char *const *argv, const char *msg) {
   83   if (opterr)
   84      fprintf(stderr, "%s: %s -- %c\n", argv[0], msg, optopt);
   85 }
   86 
   87 #endif
   88 
   89 GETOPT_CLASS int getopt(int argc, char *const *argv, const char *opts) {
   90   char *p;
   91 
   92   optarg = 0;
   93   if (*opts == '+') /* GNU extension (permutation) - isn't supported */
   94     ++opts;
   95 
   96   if (!optind) {  /* a way to reset things */
   97     nextc = 0;
   98     optind = 1;
   99   }
  100 
  101   if (!nextc || !*nextc) {   /* advance to the next argv element */
  102     /* done scanning? */
  103     if (optind >= argc)
  104       return -1;
  105     /* not an optional argument */
  106     if (argv[optind][0] != '-')
  107       return -1;
  108     /* bare `-' */
  109     if (argv[optind][1] == '\0')
  110       return -1;
  111     /* special case `--' argument */
  112     if (argv[optind][1] == '-' && argv[optind][2] == '\0') {
  113       ++optind;
  114       return -1;
  115     }
  116     nextc = argv[optind] + 1;
  117   }
  118 
  119   optopt = *nextc++;
  120   if (!*nextc)
  121     ++optind;
  122   p = strchr(opts, optopt);
  123   if (!p || optopt == ':') {
  124     printerr(argv, "illegal option");
  125     return '?';
  126   }
  127   if (p[1] == ':') {
  128     if (*nextc) {
  129       optarg = nextc;
  130       nextc = NULL;
  131       ++optind;
  132     }
  133     else if (p[2] != ':') { /* required argument */
  134       if (optind >= argc) {
  135         printerr(argv, "option requires an argument");
  136         return *opts == ':' ? ':' : '?';
  137       }
  138       else
  139         optarg = argv[optind++];
  140     }
  141   }
  142   return optopt;
  143 }
  144 
  145 #ifdef TEST
  146 
  147 #include <stdio.h>
  148 
  149 int main(int argc, char **argv) {
  150   int c;
  151   while((c = getopt(argc, argv, "ab:c::")) != -1) switch(c) {
  152   case 'a':
  153   case 'b':
  154   case 'c':
  155     printf("option %c %s\n", c, optarg ? optarg : "(none)");
  156     break;
  157   default:
  158     return -1;
  159   }
  160   for(c = optind; c < argc; ++c)
  161     printf("non-opt: %s\n", argv[c]);
  162   return 0;
  163 }
  164 
  165 #endif