Hint added.
[AROS.git] / workbench / c / Shell / convertLineDot.c
blobaa8055cc55c9b5b5395320e1d9cca566fee71d5e
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/memory.h>
7 #include <proto/dos.h>
8 #include <proto/exec.h>
10 #include <string.h>
12 #include "Shell.h"
14 static LONG getArgumentIdx(ShellState *ss, STRPTR name, LONG len)
16 struct SArg *a;
17 LONG i;
19 for (i = 0; i < ss->argcount; ++i)
21 a = ss->args + i;
23 if (strncmp(a->name, name, len) == 0)
24 return i;
27 if (ss->argcount >= MAXARGS)
28 return -1;
30 ss->argcount++;
31 a = ss->args + i;
32 CopyMem(name, a->name, len);
33 a->name[len] = '\0';
34 a->namelen = len;
35 a->type = NORMAL;
36 return i;
39 static LONG dotDef(ShellState *ss, STRPTR szz, Buffer *in, LONG len)
41 struct SArg *a;
42 LONG i, result;
43 TEXT buf[256];
45 in->cur += len;
46 i = in->cur;
48 if ((result = bufferReadItem(buf, sizeof(buf), in, DOSBase)) == ITEM_UNQUOTED)
50 len = in->cur - i;
52 i = getArgumentIdx(ss, buf, len);
53 if (i < 0)
54 return ERROR_TOO_MANY_ARGS;
56 a = ss->args + i;
57 i = ++in->cur;
59 switch (bufferReadItem(buf, sizeof(buf), in, DOSBase))
61 case ITEM_QUOTED:
62 case ITEM_UNQUOTED:
63 break;
64 default:
65 return ERROR_REQUIRED_ARG_MISSING;
68 len = in->cur - i;
70 if (a->def)
71 FreeMem((APTR) a->def, a->deflen + 1);
73 a->def = (IPTR) AllocMem(len + 1, MEMF_LOCAL);
74 CopyMem(buf, (APTR) a->def, len);
75 ((STRPTR) a->def)[len] = '\0';
76 a->deflen = len;
77 return 0;
80 return ERROR_REQUIRED_ARG_MISSING;
83 static LONG dotKey(ShellState *ss, STRPTR s, Buffer *in)
85 LONG i, j, len;
86 struct SArg *a;
87 TEXT t[256];
89 /* modify the template to read numbers as strings! */
90 for (i = 0, j = 0; s[j] != '\0' && s[j] != '\n' && i < sizeof(t); ++j)
92 if (s[j] == '/' && s[j + 1] == 'N')
93 ++j;
94 else
95 t[i++] = s[j];
98 if (i >= sizeof(t))
99 return ERROR_LINE_TOO_LONG;
101 t[i] = '\0';
103 /* Free the old ReadArgs value */
104 if (ss->arg_rd)
105 FreeDosObject(DOS_RDARGS, ss->arg_rd);
107 memset(ss->arg, 0, sizeof(IPTR) * MAXARGS);
108 if ((ss->arg_rd = ReadArgs(t, ss->arg, NULL)) == NULL)
109 return IoErr();
111 ss->argcount = 0;
113 for (i = 0; i < MAXARGS; ++i)
115 STRPTR arg;
117 for (len = 0; *s != '/' && *s != ',' && *s != '\n' && *s != '\0'; ++s)
118 ++len;
120 j = getArgumentIdx(ss, s - len, len);
121 arg = (STRPTR) ss->arg[j];
122 a = ss->args + j;
124 while (*s == '/')
126 switch (*++s)
128 case 'a': case 'A': a->type |= REQUIRED; break;
129 case 'f': case 'F': a->type |= REST; break;
130 case 'k': case 'K': a->type |= KEYWORD; break;
131 case 'm': case 'M': a->type |= MULTIPLE; break;
132 case 'n': case 'N': a->type |= NUMERIC; break;
133 case 's': case 'S': a->type |= SWITCH; break;
134 case 't': case 'T': a->type |= TOGGLE; break;
135 default:
136 return ERROR_BAD_TEMPLATE;
138 ++s;
141 if (arg && !(a->type & (SWITCH | TOGGLE)))
142 a->len = cliLen(arg);
144 if (arg && a->type & NUMERIC) /* verify numbers' validity */
146 if (a->type & MULTIPLE)
148 STRPTR *m = (STRPTR *) arg;
150 while (*m)
151 if (cliNan(*m++))
152 return ERROR_BAD_NUMBER;
154 else if (cliNan(arg))
155 return ERROR_BAD_NUMBER;
158 if (*s++ != ',')
159 break;
162 in->cur = in->len;
163 return 0;
166 LONG convertLineDot(ShellState *ss, Buffer *in)
168 STRPTR s = in->buf + in->cur;
169 TEXT *res = NULL;
171 #if 0 /* version using libc */
172 if (*++s == ' ') /* dot comment */
173 res = s;
174 else if (strncasecmp(s, "bra ", 4) == 0)
176 res = &ss->bra;
177 s += 4;
179 else if (strncasecmp(s, "ket ", 4) == 0)
181 res = &ss->ket;
182 s += 4;
184 else if (strncasecmp(s, "key ", 4) == 0)
185 return dotKey(ss, s + 4, in);
186 else if (strncasecmp(s, "k ", 2) == 0)
187 return dotKey(ss, s + 2, in);
188 else if (strncasecmp(s, "def ", 4) == 0)
189 return dotDef(ss, s + 4, in, 5);
190 else if (strncasecmp(s, "default ", 8) == 0)
191 return dotDef(ss, s + 4, in, 9);
192 else if (strncasecmp(s, "dol ", 4) == 0)
194 res = &ss->dollar;
195 s += 4;
197 else if (strncasecmp(s, "dollar ", 7) == 0)
199 res = &ss->dollar;
200 s += 7;
202 else if (strncasecmp(s, "dot ", 4) == 0)
204 res = &ss->dot;
205 s += 4;
207 else if (strncasecmp(s, "popis", 5) == 0)
209 popInterpreterState(ss);
210 res = s;
212 else if (strncasecmp(s, "pushis", 6) == 0)
214 pushInterpreterState(ss);
215 res = s;
217 #else /* this ugly version is 424 bytes smaller on x64 */
218 if (*++s == ' ') /* dot comment */
219 res = s;
220 else if (*s == 'b' || *s == 'B') /* .bra */
222 if (*++s == 'r' || *s == 'R')
223 if (*++s == 'a' || *s == 'A')
224 if (*++s == ' ')
225 res = &ss->bra;
227 else if (*s == 'k' || *s == 'K')
229 if (*++s == ' ') /* .k */
230 return dotKey(ss, ++s, in);
232 if (*s == 'e' || *s == 'E')
234 if (*++s == 'y' || *s == 'Y') /* .key */
236 if (*++s == ' ')
237 return dotKey(ss, ++s, in);
239 else if (*s == 't' || *s == 'T') /* .ket */
240 if (*++s == ' ')
241 res = &ss->ket;
244 else if (*s == 'd' || *s == 'D')
246 if (*++s == 'e' || *s == 'E')
248 if (*++s == 'f' || *s == 'F')
250 if (*++s == ' ') /* .def */
251 return dotDef(ss, ++s, in, 5);
253 if (*s == 'a' || *s == 'A')
254 if (*++s == 'u' || *s == 'U')
255 if (*++s == 'l' || *s == 'L')
256 if (*++s == 't' || *s == 'T')
257 if (*++s == ' ') /* .default */
258 return dotDef(ss, ++s, in, 9);
261 else if (*s == 'o' || *s == 'O')
263 if (*++s == 'l' || *s == 'L')
265 if (*++s == ' ') /* .dol */
266 res = &ss->dollar;
267 else if (*s == 'l' || *s == 'L')
268 if (*++s == 'a' || *s == 'A')
269 if (*++s == 'r' || *s == 'R')
270 if (*++s == ' ') /* .dollar */
271 res = &ss->dollar;
273 else if (*s == 't' || *s == 'T')
274 if (*++s == ' ') /* .dot */
275 res = &ss->dot;
278 else if (*s == 'p')
280 if (*++s == 'o' && s[1] == 'p') /* .popis */
282 popInterpreterState(ss);
283 res = s;
285 else if (*s == 'u' && s[1] == 's' && s[2] == 'h') /* .pushis */
287 pushInterpreterState(ss);
288 res = s;
291 #endif
293 if (res)
295 if (*s == '\0')
296 return ERROR_REQUIRED_ARG_MISSING;
298 *res = s[1]; /* FIXME skip spaces */
299 in->cur = in->len;
300 return 0;
303 return ERROR_ACTION_NOT_KNOWN;