source: trunk/sys/dietlibc/getopt_long.c @ 353

Last change on this file since 353 was 1, checked in by alain, 7 years ago

First import

File size: 2.9 KB
Line 
1#include <string.h>
2#include <getopt.h>
3
4static void getopterror(int which) {
5  static char error1[]="Unknown option `-x'.\n";
6  static char error2[]="Missing argument for `-x'.\n";
7  if (opterr) {
8    if (which) {
9      error2[23]=optopt;
10      write(2,error2,28);
11    } else {
12      error1[17]=optopt;
13      write(2,error1,22);
14    }
15  }
16}
17
18int getopt_long(int argc, char * const argv[], const char *optstring,
19                const struct option *longopts, int *longindex) {
20  static int lastidx,lastofs;
21  char *tmp;
22  if (optind==0) { optind=1; lastidx=0; }       /* whoever started setting optind to 0 should be shot */
23again:
24  if (*optstring == '-' && optind<argc && *argv[optind]!='-') {
25    optarg=argv[optind];
26    ++optind;
27    return 1;
28  }
29  if (optind>=argc || !argv[optind] || *argv[optind]!='-' || argv[optind][1]==0)
30    return -1;
31  if (argv[optind][1]=='-' && argv[optind][2]==0) {
32    ++optind;
33    return -1;
34  }
35  if (argv[optind][1]=='-') {   /* long option */
36    char* arg=argv[optind]+2;
37    char* max=strchr(arg,'=');
38    const struct option* o;
39    const struct option* match=0;
40    if (!max) max=arg+strlen(arg);
41    for (o=longopts; o->name; ++o) {
42      size_t tlen=max-arg;
43      if (!strncmp(o->name,arg,tlen)) { /* match */
44        if (strlen(o->name)==tlen) {
45          match=o;      /* perfect match, not just prefix */
46          break;
47        }
48        if (!match)
49          match=o;
50        else
51          /* Another imperfect match. */
52          match=(struct option*)-1;
53      }
54    }
55    if (match!=(struct option*)-1 && (o=match)) {
56      if (longindex) *longindex=o-longopts;
57      if (o->has_arg>0) {
58        if (*max=='=')
59          optarg=max+1;
60        else {
61          optarg=argv[optind+1];
62          if (!optarg && o->has_arg==1) {       /* no argument there */
63            if (*optstring==':') return ':';
64            write(2,"argument required: `",20);
65            write(2,arg,(size_t)(max-arg));
66            write(2,"'.\n",3);
67            ++optind;
68            return '?';
69          }
70          ++optind;
71        }
72      }
73      ++optind;
74      if (o->flag)
75        *(o->flag)=o->val;
76      else
77        return o->val;
78      return 0;
79    }
80    if (*optstring==':') return ':';
81    write(2,"invalid option `",16);
82    write(2,arg,(size_t)(max-arg));
83    write(2,"'.\n",3);
84    ++optind;
85    return '?';
86  }
87  if (lastidx!=optind) {
88    lastidx=optind; lastofs=0;
89  }
90  optopt=argv[optind][lastofs+1];
91  if ((tmp=strchr(optstring,optopt))) {
92    if (*tmp==0) {      /* apparently, we looked for \0, i.e. end of argument */
93      ++optind;
94      goto again;
95    }
96    if (tmp[1]==':') {  /* argument expected */
97      if (tmp[2]==':' || argv[optind][lastofs+2]) {     /* "-foo", return "oo" as optarg */
98        if (!*(optarg=argv[optind]+lastofs+2)) optarg=0;
99        goto found;
100      }
101      optarg=argv[optind+1];
102      if (!optarg) {    /* missing argument */
103        ++optind;
104        if (*optstring==':') return ':';
105        getopterror(1);
106        return ':';
107      }
108      ++optind;
109    } else {
110      ++lastofs;
111      return optopt;
112    }
113found:
114    ++optind;
115    return optopt;
116  } else {      /* not found */
117    getopterror(0);
118    ++optind;
119    return '?';
120  }
121}
Note: See TracBrowser for help on using the repository browser.