1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1999-2011 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
21
22 #include <ast.h>
23 #include <ctype.h>
24 #include <error.h>
25 #include <debug.h>
26
27 #if OPT_VERSION >= 20000101L
28 #define NEW 1
29 #else
30 #define NEW 0
31 #endif
32
33 #if !NEW
34 #define name option
35 #endif
36
37 typedef struct Info_s Info_t;
38
39 struct Info_s
40 {
41 Info_t* next;
42 char* name;
43 char* value;
44 };
45
46 static Info_t* info;
47
48 #if NEW
49 static int
infof(Opt_t * op,Sfio_t * sp,const char * s,Optdisc_t * dp)50 infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
51 {
52 Info_t* ip;
53
54 for (ip = info; ip; ip = ip->next)
55 if (streq(s, ip->name))
56 return sfprintf(sp, "%s", ip->value);
57 if (*s == ':')
58 return sfprintf(sp, "%s", *(s + 1) == 'n' ? "" : (s + 2));
59 if (streq(s, "options"))
60 return sfprintf(sp, "[Z:zoom?Do it as fast as possible.]\fmore#1\f\fmore#2\f[B:boom?Dump into \afile\a.]:[file]");
61 if (streq(s, "zero"))
62 return sfprintf(sp, "[+yabba?dabba][+doo?aroni]");
63 if (streq(s, "more#1"))
64 return sfprintf(sp, "[C:cram?Cram as much as possible.]\fmore#3\f");
65 if (streq(s, "more#2"))
66 return sfprintf(sp, "\fmore#4\f[D:dump?Dump as much as possible.]");
67 if (streq(s, "more#3"))
68 return sfprintf(sp, "[K:kill?kill all processes.]");
69 if (streq(s, "more#4"))
70 return sfprintf(sp, "[F:fudge?Fudge the statistics to satisfy everyone.]");
71 if (streq(s, "more#5"))
72 return sfprintf(sp, "\bred\b, \borange\b, \byellow\b, \bgreen\b, \bblue\b, \bindigo\b, \bviolet\b");
73 if (streq(s, "more#6"))
74 return sfprintf(sp, "\bred\b");
75 return sfprintf(sp, "<* %s info ok *>", s);
76 }
77
78 static char*
translate(const char * locale,const char * id,const char * catalog,const char * msg)79 translate(const char* locale, const char* id, const char* catalog, const char* msg)
80 {
81 register int c;
82 register int i;
83 register char* s;
84 register char* t;
85 register char* e;
86 register char* r;
87
88 static char buf[8 * 1024];
89
90 static char rot[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMabcdefghijklmnopqrstuvwxyzabcdefghijklm";
91
92 sfprintf(sfstdout, "id=%s catalog=%s text=\"%s\"\n", id, catalog, msg);
93 i = !catalog;
94 s = (char*)msg;
95 t = buf;
96 e = buf + sizeof(buf) - 1;
97 while ((c = *s++) && t < e)
98 {
99 switch (c)
100 {
101 case '\\':
102 if (t < e)
103 *t++ = c;
104 if (!(c = *s++))
105 s--;
106 break;
107 case '%':
108 do
109 {
110 if (t >= e)
111 break;
112 *t++ = c;
113 if (!(c = *s++))
114 {
115 s--;
116 break;
117 }
118 } while (!isalpha(c) || (!islower(c) || c == 'h' || c == 'l') && (t < e) && isalpha(*s));
119 break;
120 case '\b':
121 do
122 {
123 if (t >= e)
124 break;
125 *t++ = c;
126 if (!(c = *s++))
127 {
128 s--;
129 break;
130 }
131 } while (c != '\b');
132 break;
133 default:
134 if (r = strchr(rot, c))
135 {
136 c = *(r + 13);
137 if (i)
138 c = isupper(c) ? tolower(c) : toupper(c);
139 }
140 break;
141 }
142 *t++ = c;
143 }
144 *t = 0;
145 return streq(buf, msg) ? (char*)msg : buf;
146 }
147 #endif
148
149 int
main(int argc,char ** argv)150 main(int argc, char** argv)
151 {
152 int n;
153 int ext;
154 int ostr;
155 int str;
156 int loop;
157 Info_t* ip;
158 char* s;
159 char* command;
160 char* usage;
161 char** extra;
162 char** oargv;
163 #if NEW
164 Optdisc_t disc;
165 #endif
166
167 error_info.id = "opt";
168 setlocale(LC_ALL, "");
169 error(-1, "test");
170 extra = 0;
171 ext = 0;
172 str = 0;
173 while (command = *(argv + 1))
174 {
175 if (*command == '=' && (s = strchr(command + 1, '=')))
176 {
177 argv++;
178 *s++ = 0;
179 command++;
180 if (ip = newof(0, Info_t, 1, 0))
181 {
182 ip->name = command;
183 ip->value = s;
184 ip->next = info;
185 info = ip;
186 }
187 }
188 else if (streq(command, "-"))
189 {
190 argv++;
191 str = NEW;
192 }
193 else if (streq(command, "-+"))
194 {
195 argv++;
196 #if NEW
197 ast.locale.set |= (1<<AST_LC_MESSAGES);
198 error_info.translate = translate;
199 #endif
200 }
201 else if (streq(command, "+") && *(argv + 2))
202 {
203 ext += 2;
204 argv += 2;
205 if (!extra)
206 extra = argv;
207 }
208 else
209 break;
210 }
211 if (!(command = *++argv) || !(usage = *++argv))
212 error(ERROR_USAGE|4, "[ - | + usage ... ] command-name usage-string [ arg ... ]");
213 argv += str;
214 error_info.id = command;
215 #if NEW
216 memset(&disc, 0, sizeof(disc));
217 disc.version = OPT_VERSION;
218 disc.infof = infof;
219 opt_info.disc = &disc;
220 #else
221 memset(&opt_info, 0, sizeof(opt_info));
222 #endif
223 loop = strncmp(usage, "[-1c", 4) ? 0 : 3;
224 oargv= argv;
225 ostr = str;
226 for (;;)
227 {
228 for (;;)
229 {
230 if (!str)
231 {
232 if (!(n = optget(argv, usage)))
233 break;
234 }
235 else if (!(n = optstr(*argv, usage)))
236 {
237 if (!*++argv)
238 break;
239 continue;
240 }
241 if (loop)
242 sfprintf(sfstdout, "[%d] ", loop);
243 if (n == '?')
244 {
245 sfprintf(sfstdout, "return=%c option=%s name=%s num=%I*d\n", n, opt_info.option, opt_info.name, sizeof(opt_info.number), opt_info.number);
246 error(ERROR_USAGE|4, "%s", opt_info.arg);
247 }
248 else if (n == ':')
249 {
250 sfprintf(sfstdout, "return=%c option=%s name=%s num=%I*d", n, opt_info.option, opt_info.name, sizeof(opt_info.number), opt_info.number);
251 if (!opt_info.option[0])
252 sfprintf(sfstdout, " str=%s", argv[opt_info.index - 1]);
253 sfputc(sfstdout, '\n');
254 error(2, "%s", opt_info.arg);
255 }
256 else if (n > 0)
257 sfprintf(sfstdout, "return=%c option=%s name=%s arg%-.1s=%s num=%I*d\n", n, opt_info.option, opt_info.name, &opt_info.assignment, opt_info.arg, sizeof(opt_info.number), opt_info.number);
258 else
259 sfprintf(sfstdout, "return=%d option=%s name=%s arg%-.1s=%s num=%I*d\n", n, opt_info.option, opt_info.name, &opt_info.assignment, opt_info.arg, sizeof(opt_info.number), opt_info.number);
260 if (extra)
261 {
262 for (n = 0; n < ext; n += 2)
263 optget(NiL, extra[n]);
264 extra = 0;
265 }
266 }
267 if (!str && *(argv += opt_info.index))
268 while (command = *argv++)
269 {
270 if (loop)
271 sfprintf(sfstdout, "[%d] ", loop);
272 sfprintf(sfstdout, "argument=%d value=\"%s\"\n", ++str, command);
273 }
274 if (--loop <= 0)
275 break;
276 argv = oargv;
277 str = ostr;
278 opt_info.index = 0;
279 }
280 return error_info.errors != 0;
281 }
282