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