Added SILC Server library.
[silc.git] / lib / contrib / getopti.c
1 /* Our own convenience getopt.  Public Domain. */
2 #include "silc.h"
3
4 #ifndef SILC_EPOC
5 #if !defined(HAVE_GETOPT) && !defined(HAVE_GETOPT_H)
6 int     opterr = 1;
7 int     optind = 1;
8 int     optopt;
9 char    *optarg;
10
11 #define GETOPT_ERR(s, c)                        \
12 do {                                            \
13   if (opterr) {                                 \
14     char errbuf[2];                             \
15     errbuf[0] = c;                              \
16     errbuf[1] = '\n';                           \
17     (void) write(2, argv[0], strlen(argv[0]));  \
18     (void) write(2, s, strlen(s));              \
19     (void) write(2, errbuf, 2);                 \
20   }                                             \
21 } while(0)
22
23 int getopt(int argc, char * const *argv, const char *optstring)
24 {
25   static int sp = 1;
26   register int c;
27   register char *cp;
28
29   if (sp == 1) {
30     if (optind >= argc ||
31         argv[optind][0] != '-' || argv[optind][1] == '\0') {
32       return EOF;
33     } else if (strcmp(argv[optind], "--") == 0) {
34       optind++;
35       return EOF;
36     }
37   }
38   optopt = c = argv[optind][sp];
39
40   if (c == ':' || (cp=strchr(optstring, c)) == NULL) {
41     GETOPT_ERR(": illegal option -- ", c);
42     if (argv[optind][++sp] == '\0') {
43       optind++;
44       sp = 1;
45     }
46     return '?';
47   }
48
49   if (*++cp == ':') {
50     if (argv[optind][sp+1] != '\0')
51       optarg = &argv[optind++][sp+1];
52     else if (++optind >= argc) {
53       GETOPT_ERR(": option requires an argument -- ", c);
54       sp = 1;
55       return '?';
56     } else
57       optarg = argv[optind++];
58     sp = 1;
59   } else {
60     if (argv[optind][++sp] == '\0') {
61       sp = 1;
62       optind++;
63     }
64     optarg = NULL;
65   }
66
67   return c;
68 }
69 #endif /* !HAVE_GETOPT && !HAVE_GETOPT_H */
70 #endif /* !SILC_EPOC */