]> git.sur5r.net Git - openldap/blob - libraries/liblutil/getopt.c
Merge remote-tracking branch 'origin/mdb.RE/0.9'
[openldap] / libraries / liblutil / getopt.c
1 /* getopt.c -- replacement getopt(3) routines */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2014 The OpenLDAP Foundation.
6  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* This work is based upon the public-domain getopt(3) routines
18  * developed by AT&T.  Modified by Kurt D. Zeilenga for inclusion
19  * into OpenLDAP Software.  Significant contributors include:
20  *   Howard Chu
21  */
22
23 #include "portable.h"
24
25 #ifndef HAVE_GETOPT
26
27 #include <stdio.h>
28
29 #include <ac/string.h>
30 #include <ac/unistd.h>
31
32 #ifdef HAVE_IO_H
33 #include <io.h>
34 #endif
35
36 #include "lutil.h"
37
38 #ifndef STDERR_FILENO
39 #define STDERR_FILENO 2
40 #endif
41
42 int opterr = 1;
43 int optind = 1;
44 int optopt;
45 char * optarg;
46
47 #ifdef HAVE_EBCDIC
48 extern int _trans_argv;
49 #endif
50
51 static void ERR (char * const argv[], const char * s, char c)
52 {
53 #ifdef DF_TRACE_DEBUG
54 printf("DF_TRACE_DEBUG:         static void ERR () in getopt.c\n");
55 #endif
56         if (opterr)
57         {
58                 char *ptr, outbuf[4096];
59
60                 ptr = lutil_strncopy(outbuf, argv[0], sizeof(outbuf) - 2);
61                 ptr = lutil_strncopy(ptr, s, sizeof(outbuf)-2 -(ptr-outbuf));
62                 *ptr++ = c;
63                 *ptr++ = '\n';
64 #ifdef HAVE_EBCDIC
65                 __atoe_l(outbuf, ptr - outbuf);
66 #endif
67                 (void) write(STDERR_FILENO,outbuf,ptr - outbuf);
68         }
69 }
70
71 int getopt (int argc, char * const argv [], const char * opts)
72 {
73         static int sp = 1, error = (int) '?';
74         static char sw = '-', eos = '\0', arg = ':';
75         register char c, * cp;
76
77 #ifdef DF_TRACE_DEBUG
78 printf("DF_TRACE_DEBUG:         int getopt () in getopt.c\n");
79 #endif
80
81 #ifdef HAVE_EBCDIC
82         if (_trans_argv) {
83                 int i;
84                 for (i=0; i<argc; i++) __etoa(argv[i]);
85                 _trans_argv = 0;
86         }
87 #endif
88         if (sp == 1)
89         {
90                 if (optind >= argc || argv[optind][0] != sw
91                 || argv[optind][1] == eos)
92                         return EOF;
93                 else if (strcmp(argv[optind],"--") == 0)
94                 {
95                         optind++;
96                         return EOF;
97                 }
98         }
99         c = argv[optind][sp];
100         optopt = (int) c;
101         if (c == arg || (cp = strchr(opts,c)) == NULL)
102         {
103                 ERR(argv,_(": illegal option--"),c);
104                 if (argv[optind][++sp] == eos)
105                 {
106                         optind++;
107                         sp = 1;
108                 }
109                 return error;
110         }
111         else if (*++cp == arg)
112         {
113                 if (argv[optind][sp + 1] != eos)
114                         optarg = &argv[optind++][sp + 1];
115                 else if (++optind >= argc)
116                 {
117                         ERR(argv,_(": option requires an argument--"),c);
118                         sp = 1;
119                         return error;
120                 }
121                 else
122                         optarg = argv[optind++];
123                 sp = 1;
124         }
125         else
126         {
127                 if (argv[optind][++sp] == eos)
128                 {
129                         sp = 1;
130                         optind++;
131                 }
132                 optarg = NULL;
133         }
134         return (int) c;
135 }
136 #endif /* HAVE_GETOPT */