Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | mjames | 1 | /********** $Header: c:\\cygwin\\cvsroot/Vert03/cmdparse_nonTCL.c,v 1.1.1.1 2003/11/04 23:34:56 |
2 | mjames Exp $ ********** |
||
3 | |||
4 | Author: Kevin Ross (x6143) |
||
5 | Philips Semiconductors Limited. |
||
6 | Millbrook Industrial Estate, Southampton, SO9 7BH. England. |
||
7 | |||
8 | Date: 13th May 1993 |
||
9 | |||
10 | Comment: This program parses the input commands for the SFC3 evaluation software |
||
11 | $Log: cmdparse_nonTCL.c,v $ |
||
12 | Revision 1.1.1.1 2003/11/04 23:34:56 mjames |
||
13 | Imported into local repositrory |
||
14 | |||
15 | Revision 1.1.1.1 2002/09/09 15:06:18 mjames |
||
16 | no message |
||
17 | |||
18 | Revision 1.1.1.1 2000/10/19 21:58:35 mjames |
||
19 | Mike put it here |
||
20 | |||
21 | |||
22 | * Revision 1.30 2000/10/04 10:37:03 10:37:03 mjames (Mike James) |
||
23 | * Modified to support VHDL components and SIGNALS |
||
24 | * |
||
25 | * Revision 1.30 2000/10/04 10:37:03 10:37:03 mjames (Mike James) |
||
26 | * Part of Release PSAVAT01 |
||
27 | * |
||
28 | * Revision 1.29 2000/10/02 11:04:09 11:04:09 mjames (Mike James) |
||
29 | * new_vhdl |
||
30 | * |
||
31 | * Revision 1.28 2000/09/27 14:42:10 14:42:10 mjames (Mike James) |
||
32 | * Part of Release Sep_27_ST_2000 |
||
33 | * |
||
34 | * Revision 1.27 2000/09/21 10:19:57 10:19:57 mjames (Mike James) |
||
35 | * removed diagnostics |
||
36 | * |
||
37 | * Revision 1.26 2000/09/21 10:15:39 10:15:39 mjames (Mike James) |
||
38 | * Part of Release Sep21Alpha |
||
39 | * |
||
40 | * Revision 1.25 2000/09/21 09:43:27 09:43:27 mjames (Mike James) |
||
41 | * Corrected a few mistakes to do with argument expansion. |
||
42 | * Also removed <cr> characters from a DOS edit session |
||
43 | * |
||
44 | * Revision 1.24 2000/08/25 09:57:09 09:57:09 mjames (Mike James) |
||
45 | * Part of Release Aug25_alpha |
||
46 | * |
||
47 | * Revision 1.23 2000/08/16 08:57:25 08:57:25 mjames (Mike James) |
||
48 | * Part of Release CD01_Aug2000 |
||
49 | * |
||
50 | * Revision 1.22 2000/08/14 14:45:07 14:45:07 mjames (Mike James) |
||
51 | * Part of Release Aug_14_2000 |
||
52 | * |
||
53 | * Revision 1.21 2000/08/11 08:30:27 08:30:27 mjames (Mike James) |
||
54 | * Part of Release Aug_11_2000 |
||
55 | * |
||
56 | * Revision 1.20 2000/08/11 08:28:39 08:28:39 mjames (Mike James) |
||
57 | * Modified string expansion to occur once only to |
||
58 | * permit the preservation of escaped sequences |
||
59 | * |
||
60 | * Revision 1.19 2000/08/09 10:31:41 10:31:41 mjames (Mike James) |
||
61 | * Part of Release Aug__9_2000 |
||
62 | * |
||
63 | * Revision 1.18 2000/08/09 10:28:26 10:28:26 mjames (Mike James) |
||
64 | * Altered variable expansion to work consistently and return |
||
65 | * $(name) if the variable 'name' is not known. |
||
66 | * |
||
67 | * Revision 1.17 2000/05/31 11:42:47 11:42:47 mjames (Mike James) |
||
68 | * Part of Release May_31_2000 |
||
69 | * |
||
70 | * Revision 1.16 2000/05/08 17:01:32 17:01:32 mjames (Mike James) |
||
71 | * Part of Release May__8_2000 |
||
72 | * |
||
73 | * Revision 1.15 2000/05/08 16:59:25 16:59:25 mjames (Mike James) |
||
74 | * Part of Release May__8_2000 |
||
75 | * |
||
76 | * Revision 1.14 2000/05/08 16:57:02 16:57:02 mjames (Mike James) |
||
77 | * Part of Release May__8_2000 |
||
78 | * |
||
79 | * Revision 1.13 2000/05/08 16:41:40 16:41:40 mjames (Mike James) |
||
80 | * Altered null pointer references in both PC and HP |
||
81 | * versions |
||
82 | * |
||
83 | * Revision 1.11 2000/05/03 15:25:19 15:25:19 mjames (Mike James) |
||
84 | * Command handler updated to avoid memory trashing by |
||
85 | * allocating exactly enough memory for expanded command |
||
86 | * line strings rather than the unexpanded version |
||
87 | * , |
||
88 | * |
||
89 | * Revision 1.10 2000/03/08 16:18:42 16:18:42 mjames (Mike James) |
||
90 | * New version including PC |
||
91 | * |
||
92 | * Revision 1.7 2000/02/18 15:45:22 15:45:22 mjames (Mike James) |
||
93 | * Amended to support PC |
||
94 | * |
||
95 | * Revision 1.6 2000/01/20 15:58:41 15:58:41 mjames (Mike James) |
||
96 | * Part of Release R22 |
||
97 | * |
||
98 | * Revision 1.5 99/12/22 11:15:21 11:15:21 mjames (Mike James) |
||
99 | * Part of Release Dec_22_1999 |
||
100 | * |
||
101 | * Revision 1.4 99/11/23 13:51:54 13:51:54 mjames (Mike James) |
||
102 | * Addded syntax to support special generics for Certify support |
||
103 | * |
||
104 | * Revision 1.3 99/06/25 14:34:39 14:34:39 mjames (Mike James) |
||
105 | * Added in reference to expression.h, but no changes made |
||
106 | * to the function of acfread yet. |
||
107 | * |
||
108 | * Revision 1.2 99/06/18 09:22:59 09:22:59 mjames (Mike James) |
||
109 | * |
||
110 | * Revision 1.1 1999/06/14 10:47:18 mjames |
||
111 | * Initial revision |
||
112 | * |
||
113 | * Revision 1.1 1999/06/14 10:47:18 mjames |
||
114 | * Initial revision |
||
115 | * |
||
116 | * Revision 1.20 98/10/01 15:30:35 15:30:35 mjames (Mike James) |
||
117 | * Printout of help had 100 dots as this was longest string expected after macro |
||
118 | * expansion.. Now has a separate limit of around 20 (CMDWIDTH) |
||
119 | * |
||
120 | * Revision 1.19 98/08/12 14:19:33 14:19:33 mjames (Mike James) |
||
121 | * Added correct header file list |
||
122 | * |
||
123 | * Revision 1.18 98/07/14 13:23:05 13:23:05 mjames (Mike James) |
||
124 | * added $1 or $(env_var) expansion on command line |
||
125 | * |
||
126 | * Revision 1.17 98/03/16 11:36:57 11:36:57 mjames (Mike James) |
||
127 | * Added LOG_ERROR to logging system . All7ws output of serious errors to stderr |
||
128 | * |
||
129 | * Revision 1.16 98/02/71 11:25:42 11:25:42 mjames (Mike James) |
||
130 | * Checked in for version 6.2a |
||
131 | * |
||
132 | * Revision 1.15 97/04/23 08:42:46 08:42:46 mjames (Mike James) |
||
133 | * CHecked in for release rel23041997 |
||
134 | * |
||
135 | * Revision 1.14 96/07/19 14:37:50 14:37:50 mjames (Mike James) |
||
136 | * Added list of objects to SET DEL EXT commands |
||
137 | * |
||
138 | * Revision 1.13 1996/07/12 15:52:12 mjames |
||
139 | * Sorted out things like Alias and Jumpers |
||
140 | * Work Correctly |
||
141 | * Print COrrectly |
||
142 | * |
||
143 | * Revision 1.12 96/06/17 10:51:56 10:51:56 mjames (Mike James) |
||
144 | * Added fix_pins command |
||
145 | * |
||
146 | * Revision 1.11 96/04/15 14:19:21 14:19:21 mjames (Mike James) |
||
147 | * Checkin before datatype printing |
||
148 | * modifications |
||
149 | * |
||
150 | * Revision 1.10 96/03/29 14:46:01 14:46:01 mjames (Mike James) |
||
151 | * Added VHDL netlist writing to the capabilities of ACFREAD |
||
152 | * |
||
153 | * Revision 1.9 96/03/26 07:20:29 07:20:29 mjames (Mike James) |
||
154 | * Added LIST XREF socket-name command |
||
155 | * |
||
156 | * Revision 1.8 96/03/18 13:50:25 13:50:25 mjames (Mike James) |
||
157 | * Real Revision 2.1 |
||
158 | * |
||
159 | * Revision 1.5 96/03/13 15:35:20 15:35:20 mjames (Mike James) |
||
160 | * *** empty log message *** |
||
161 | * |
||
162 | * Revision 1.4 96/02/13 09:13:09 09:13:09 mjames (Mike James) |
||
163 | * Updated to be version 2.0 with net joining |
||
164 | * |
||
165 | * Revision 1.3 96/02/08 15:28:07 15:28:07 mjames (Mike James) |
||
166 | * First release |
||
167 | * |
||
168 | * Revision 1.2 96/02/07 16:01:21 16:01:21 mjames (Mike James) |
||
169 | * Added correct RCS header |
||
170 | * |
||
171 | * Revision 1.1 96/02/07 15:49:19 15:49:19 mjames (Mike James) |
||
172 | * Initial revision |
||
173 | * |
||
174 | *********************************************************************************************************/ |
||
175 | |||
176 | #include "cmdexec.h" |
||
177 | #include "cmdlog.h" |
||
178 | #include "cmdparse.h" |
||
179 | #include "cmdutil.h" |
||
180 | #include "expression.h" |
||
181 | #include "generic.h" |
||
182 | |||
183 | #include <ctype.h> |
||
184 | #include <stdio.h> |
||
185 | #include <stdlib.h> |
||
186 | #include <string.h> |
||
187 | /* used for dynamic string allocation/deallocation code |
||
188 | * used here for command keywords May 2 2000 */ |
||
189 | #include "lx_support.h" |
||
190 | |||
191 | /*********************************************************************************************************/ |
||
192 | static char IDstr[] = "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/cmdparse_nonTCL.c,v 1.1.1.1 " |
||
193 | "2003/11/04 23:34:56 mjames Exp $"; |
||
194 | |||
195 | /******************************************* Execute a command |
||
196 | * ******************************************/ |
||
197 | |||
198 | /* modification to use a datastructure used elsewhere */ |
||
199 | static struct str *cmd_first, *cmd_last; |
||
200 | |||
201 | #define WORDWIDTH 100 /* max command word everexpected */ |
||
202 | #define CMDWIDTH 20 /*Field width for printing CMD word */ |
||
203 | int execute (struct CommandStruct *CmdPtr, struct command Dispatch[], int NumCmds) |
||
204 | { |
||
205 | int i, j, FinalResult = UNKNOWNCMD; |
||
206 | if (CmdPtr->CurrentCommand == CmdPtr->NumberCommands) |
||
207 | return (NARGS); |
||
208 | if (CmdPtr->Words[CmdPtr->CurrentCommand][0] == '?') |
||
209 | { |
||
210 | printf ("Commands available;\nHelp on:"); |
||
211 | for (i = 0; i < CmdPtr->CurrentCommand; i++) |
||
212 | printf ("%s ", CmdPtr->Words[i]); |
||
213 | putchar ('\n'); |
||
214 | for (i = 0; i < NumCmds; i++) |
||
215 | { |
||
216 | int p; |
||
217 | for (j = 0; j < Dispatch[i].NumChar; |
||
218 | j++) /* upper case significant chars */ |
||
219 | putchar (toupper (Dispatch[i].name[j])); |
||
220 | for (; Dispatch[i].name[j]; |
||
221 | j++) /* and all of the rest, we just print */ |
||
222 | putchar (Dispatch[i].name[j]); |
||
223 | putchar (' '); |
||
224 | j++; |
||
225 | if (Dispatch[i].extras) |
||
226 | { |
||
227 | p = j; |
||
228 | for (; Dispatch[i].extras[j - p]; |
||
229 | j++) /* and all of the extras field we just print */ |
||
230 | putchar (Dispatch[i].extras[j - p]); |
||
231 | }; |
||
232 | for (; j < CMDWIDTH; j++) /* create spacing , relies on auto - wrap */ |
||
233 | putchar (j & 1 ? '.' : ' '); |
||
234 | putchar (' '); |
||
235 | puts (Dispatch[i].helpstr); |
||
236 | } |
||
237 | putchar ('\n'); |
||
238 | FinalResult = OKCMD; /* ? is a valid command at this level */ |
||
239 | } |
||
240 | else |
||
241 | { |
||
242 | for (i = 0; i < NumCmds; i++) |
||
243 | if (strncmp ( |
||
244 | CmdPtr->Words[CmdPtr->CurrentCommand], |
||
245 | Dispatch[i].name, |
||
246 | Dispatch[i].NumChar) == 0) |
||
247 | { |
||
248 | CmdPtr->CurrentCommand++; /* Dispatch the next level command */ |
||
249 | FinalResult = (*Dispatch[i].function) (CmdPtr); |
||
250 | break; |
||
251 | } |
||
252 | } |
||
253 | return (FinalResult); |
||
254 | } |
||
255 | |||
256 | /******************************************** Strip off words |
||
257 | * ********************************************/ |
||
258 | /* this needs repairing . This code is unsafe. |
||
259 | * Needs to keep a record of how many chars copied !! |
||
260 | * and stop when in danger of a buffer overflow. |
||
261 | * |
||
262 | * Did not work properly if expanded strings are longer than the |
||
263 | * original strings. This now fixed. |
||
264 | * |
||
265 | * Code modified to use some string allocation functions in lx_support.c |
||
266 | */ |
||
267 | char wordbuff[1024]; |
||
268 | |||
269 | int FindWords (char *linebuff, struct CommandStruct *Cmd, int nArgs, char *Args[]) |
||
270 | { |
||
271 | char *WordPtr, *Optr; |
||
272 | char *BasePtr; |
||
273 | int i, Len, term = ' ', escape; |
||
274 | |||
275 | /* deallocate any previous structures */ |
||
276 | free_strings (&cmd_first, &cmd_last); |
||
277 | |||
278 | if (Cmd->Text) |
||
279 | { |
||
280 | strcpy (linebuff, Cmd->Text); /* make a safe copy */ |
||
281 | Len = strlen (linebuff); |
||
282 | } |
||
283 | else |
||
284 | Len = 0; |
||
285 | |||
286 | Cmd->NumberCommands = 0; |
||
287 | if (Len > 0) |
||
288 | { |
||
289 | linebuff[Len - 1] = 0; /* kill <CR> */ |
||
290 | /* for (i=0; i<Len; i++) */ |
||
291 | /* Cmd->Text[i] = tolower(Cmd->Text[i]); */ /* convert text |
||
292 | to lower case |
||
293 | */ |
||
294 | WordPtr = linebuff; /* set LineStart to beginning of string */ |
||
295 | escape = 0; |
||
296 | /* Now split off the words */ |
||
297 | BasePtr = NULL; |
||
298 | while (*WordPtr && Cmd->NumberCommands < WORDSINLINE) |
||
299 | { |
||
300 | while (*WordPtr && *WordPtr == ' ') /* skip leading spaces */ |
||
301 | WordPtr++; |
||
302 | if (!*WordPtr) |
||
303 | break; |
||
304 | |||
305 | if (*WordPtr == '"' || *WordPtr == '\'') |
||
306 | { /* sigle or double quotes ? */ |
||
307 | term = *WordPtr++; |
||
308 | } |
||
309 | else |
||
310 | term = ' '; |
||
311 | |||
312 | BasePtr = WordPtr; |
||
313 | escape = 0; |
||
314 | |||
315 | while (*WordPtr && (escape || *WordPtr != term)) |
||
316 | { /* scan for terminator ' ' or '"' */ |
||
317 | escape = |
||
318 | (*WordPtr == '\\' && |
||
319 | *(WordPtr + 1) == term); /* only escape terminators */ |
||
320 | |||
321 | WordPtr++; |
||
322 | } |
||
323 | if (!*WordPtr) /* if end of line */ |
||
324 | break; |
||
325 | |||
326 | *WordPtr++ = '\0'; |
||
327 | /* make_string now performs an expand_string call */ |
||
328 | Cmd->Words[Cmd->NumberCommands++] = |
||
329 | make_string (BasePtr, &cmd_first, &cmd_last); |
||
330 | BasePtr = NULL; |
||
331 | } |
||
332 | if (BasePtr) |
||
333 | { |
||
334 | Cmd->Words[Cmd->NumberCommands++] = |
||
335 | make_string (BasePtr, &cmd_first, &cmd_last); |
||
336 | } |
||
337 | } |
||
338 | |||
339 | /* |
||
340 | printf("Seen %d words on line\n",Cmd->NumberCommands); |
||
341 | for(i=0;i<Cmd->NumberCommands;i++) |
||
342 | printf("word[%d]='%s'\n",i,Cmd->Words[i]); |
||
343 | */ |
||
344 | return (OKCMD); |
||
345 | } |
||
346 | |||
347 | /********************************* executes the command from stdin or a do file |
||
348 | * **************************/ |
||
349 | |||
350 | int ExecuteCommand (FILE *CmdFile, struct CommandStruct Cmd, int nArgs, char *Args[]) |
||
351 | { |
||
352 | char Buff[PATHLENGTH]; |
||
353 | char linebuff[LINELEN]; |
||
354 | int i, Status; |
||
355 | char *p; |
||
356 | if (feof (CmdFile)) |
||
357 | return (QUITCMD); |
||
358 | |||
359 | p = fgets (Buff, PATHLENGTH - 1, CmdFile); /* read the command from the input stream */ |
||
360 | Cmd.Text = Buff; /* place the command in the command structure */ |
||
361 | Cmd.NumberCommands = 0; |
||
362 | Cmd.CurrentCommand = 0; |
||
363 | if (p == NULL || *Buff == '\0') |
||
364 | return (OKCMD); |
||
365 | |||
366 | /* convert control codes to spaces */ |
||
367 | i = 0; |
||
368 | while (Buff[i]) |
||
369 | { |
||
370 | if (Buff[i] < ' ') |
||
371 | Buff[i] = ' '; |
||
372 | i++; |
||
373 | } |
||
374 | |||
375 | FindWords (linebuff, &Cmd, nArgs, Args); /* split off the words and save in structure |
||
376 | */ |
||
377 | if (CmdFile != stdin) |
||
378 | { |
||
379 | for (i = 0; i < Cmd.NumberCommands; i++) |
||
380 | printf ("%s ", Cmd.Words[i]); /* log the command word by word if its |
||
381 | not given interactively */ |
||
382 | printf ("\n"); /* */ |
||
383 | } |
||
384 | |||
385 | if (Cmd.NumberCommands == 0 || Cmd.Words[0][0] == '-' || Cmd.Words[0][0] == '#') |
||
386 | return (OKCMD); /* comment or a null string */ |
||
387 | |||
388 | Status = TopMenu (&Cmd); /* pass the command through the top-level menu */ |
||
389 | switch (Status) |
||
390 | { |
||
391 | case UNKNOWNCMD: |
||
392 | Log (LOG_ERROR, "# Unknown command:"); |
||
393 | break; |
||
394 | case NARGS: |
||
395 | Log (LOG_ERROR, "# Too few parameters:"); |
||
396 | break; |
||
397 | case FAILED: |
||
398 | Log (LOG_ERROR, "# Could not execute command:"); |
||
399 | break; |
||
400 | }; |
||
401 | if (Status != OKCMD) |
||
402 | { |
||
403 | for (i = 0; i < Cmd.NumberCommands; i++) /* display offending command */ |
||
404 | Log (LOG_ERROR, " %s", Cmd.Words[i]); |
||
405 | Log (LOG_ERROR, "\n"); |
||
406 | }; |
||
407 | return (Status); |
||
408 | } |
||
409 | |||
410 | /********************************* Execute a command string |
||
411 | * ******************************************/ |
||
412 | int ExecuteString (char *commandstring, int nArgs, char *Args[]) |
||
413 | { |
||
414 | struct CommandStruct Cmd; |
||
415 | char linebuff[LINELEN]; |
||
416 | |||
417 | int Status = 0; |
||
418 | Cmd.Text = commandstring; /* place the command in the command structure */ |
||
419 | Cmd.NumberCommands = 0; |
||
420 | Cmd.CurrentCommand = 0; |
||
421 | FindWords (linebuff, &Cmd, nArgs, Args); /* split off the words and save in structure |
||
422 | */ |
||
423 | Status = TopMenu (&Cmd); /* pass the command through the top-level menu */ |
||
424 | return (Status); |
||
425 | } |
||
426 | |||
427 | /********************************* A parser for the '*.do files |
||
428 | * ******************************************/ |
||
429 | static int Depth = 0; |
||
430 | #define MAXDEPTH 10 /* maximum depth of 'do' files */ |
||
431 | #define MAXARGV 10 |
||
432 | int ParseFile (FILE *CmdFile, int nArgs, char *Args[]) |
||
433 | { |
||
434 | struct CommandStruct Cmd; |
||
435 | int Status = 0; |
||
436 | char *argp[MAXARGV]; |
||
437 | char **argp_prev; |
||
438 | int nArgs_prev; |
||
439 | int i; |
||
440 | /* diagnosis */ |
||
441 | if (nArgs > MAXARGV) |
||
442 | nArgs = MAXARGV; |
||
443 | if (nArgs < 0) |
||
444 | nArgs = 0; |
||
445 | |||
446 | for (i = 0; i < MAXARGV; i++) |
||
447 | { |
||
448 | if (i < nArgs) |
||
449 | argp[i] = strdup (Args[i]); |
||
450 | else |
||
451 | argp[i] = NULL; |
||
452 | |||
453 | /* printf("Arg [%2d]='%s'\n",i,argp[i]); */ |
||
454 | } |
||
455 | nArgs_prev = yy_nArgs; |
||
456 | argp_prev = yy_Args; |
||
457 | yy_nArgs = nArgs; |
||
458 | yy_Args = argp; |
||
459 | |||
460 | Depth++; /* keep a count of recursion depth */ |
||
461 | printf ("Command file nesting level = %d\n", Depth); |
||
462 | if (Depth > MAXDEPTH) |
||
463 | { |
||
464 | Log (LOG_ERROR, "Recursive call of files is greater than %d\n", MAXDEPTH); |
||
465 | Depth--; |
||
466 | return (FAILED); |
||
467 | } |
||
468 | while (Status != QUITCMD) /* execute the command from do file input stream */ |
||
469 | Status = ExecuteCommand (CmdFile, Cmd, nArgs, argp); |
||
470 | Depth--; |
||
471 | yy_nArgs = nArgs_prev; |
||
472 | yy_Args = argp_prev; |
||
473 | for (i = 0; i < MAXARGV; i++) |
||
474 | if (argp[i]) |
||
475 | { |
||
476 | free (argp[i]); |
||
477 | argp[i] = NULL; |
||
478 | } |
||
479 | return (Status); |
||
480 | } |
||
481 | |||
482 | /*********************************************************************************************************/ |