Lely core libraries  2.3.4
getopt.c
Go to the documentation of this file.
1 
23 #include "libc.h"
24 #include <lely/libc/unistd.h>
25 
26 #if !LELY_HAVE_UNISTD_H
27 
28 #include <assert.h>
29 #include <stddef.h>
30 #if !LELY_NO_STDIO
31 #include <stdio.h>
32 #endif
33 
34 char *optarg;
35 int optind = 1;
36 int opterr = 1;
37 int optopt;
38 
43 static int optoff;
44 
45 int
46 getopt(int argc, char *const argv[], const char *optstring)
47 {
48  assert(argv);
49  assert(optstring);
50 
51  optarg = NULL;
52 
53  // Check whether any arguments remain.
54  if (optind >= argc || !argv[optind])
55  return -1;
56  // Continue with the next option in the current argument.
57  char *cp = argv[optind] + optoff;
58  // If this is a new argument, check if it is an option argument.
59  if (!optoff) {
60  // An option argument begins with '-'.
61  if (*cp++ != '-' || !*cp)
62  return -1;
63  // A double dash ("--") denotes the end of option arguments.
64  if (*cp == '-' && !cp[1]) {
65  optind++;
66  return -1;
67  }
68  optoff = 1;
69  }
70  int c = *cp++;
71  // Update the index and offset of the next option.
72  if (*cp) {
73  optoff++;
74  } else {
75  optind++;
76  optoff = 0;
77  }
78 
79  // Check if the option character occurs in `optstring`.
80  const char *op = optstring;
81  while (*op && (*op == ':' || *op == '?' || *op != c))
82  op++;
83  if (!*op) {
84  optopt = c;
85 #if !LELY_NO_STDIO
86  if (opterr && *optstring != ':')
87  fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
88  optopt);
89 #endif
90  return '?';
91  }
92 
93  // If the option does not take an argument, we are done.
94  if (*++op != ':')
95  return c;
96 
97  optind++;
98  optoff = 0;
99  if (*cp) {
100  // If any characters remain in the current argument, they form
101  // the argument for the option...
102  optarg = cp;
103  } else {
104  // ... otherwise, the next argument is used, if it exists.
105  if (optind > argc) {
106  optopt = c;
107 #if !LELY_NO_STDIO
108  if (opterr && *optstring != ':')
109  fprintf(stderr,
110  "%s: option requires an "
111  "argument -- %c\n",
112  argv[0], optopt);
113 #endif
114  return *optstring == ':' ? ':' : '?';
115  }
116  optarg = argv[optind - 1];
117  }
118  return c;
119 }
120 
121 #endif // !LELY_HAVE_UNISTD_H
libc.h
stdio.h
unistd.h
stddef.h