Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**********
2
 * $Id: cmdparse.c,v 1.1.1.1 2003/11/04 23:34:56 mjames Exp $ **********
3
 
4
             One time Author: Kevin Ross (x6143)
5
                      Philips Semiconductors Limited.
6
                      Millbrook Industrial Estate, Southampton, SO9 7BH. England.
7
 
8
                Date: 13th May 1993
9
 
10
             Mostly by Mike James these days
11
 
12
             Comment: This program parses the input commands for the SFC3 evaluation software
13
$Log: cmdparse.c,v $
14
Revision 1.1.1.1  2003/11/04 23:34:56  mjames
15
Imported into local repositrory
16
 
17
Revision 1.18  2002/09/09 10:26:56  mjames
18
Removed set generic range and replaced it with a set generic value command
19
that takes both integers and ranges.
20
 
21
Revision 1.17  2002/01/16 11:22:41  mjames
22
database.h header file is read in first as it undefined DLL stuff irrelevant
23
to HPUX
24
 
25
Revision 1.16  2001/12/20 13:49:48  mjames
26
force ?
27
 
28
Revision 1.15  2001/12/13 22:14:26  mjames
29
Corrected nested command handlers to allow variable passing without corruption.
30
 
31
Revision 1.14  2001/10/31 22:20:00  mjames
32
Tidying up problematical comments caused by CVS
33
'intelligent' comment guessing
34
 
35
Revision 1.13  2001/10/10 20:19:56  mjames
36
Adjustment of handling of escapes and comments
37
 
38
Revision 1.12  2001/10/10 10:02:59  mjames
39
Final tweaks to work with end-of line at end-of-file
40
 
41
Revision 1.11  2001/10/10 09:54:30  mjames
42
Modified command line handler to correctly recognise
43
comment leaders anywhere on line, not just as first character.
44
 
45
Revision 1.10  2001/07/09 15:08:44  mjames
46
Check the last character of a line of text to see if it is actually a control code
47
before deleting it
48
 
49
Revision 1.9  2001/06/19 05:24:57  mjames
50
Created a trap_fopen to overcome trying to write to read only files.
51
If this attempted in NT the file can be opened but not written to.
52
 
53
Revision 1.8  2001/06/06 12:10:24  mjames
54
Move from HPUX
55
 
56
Revision 1.7  2001/05/01 15:21:18  mjames
57
Added comment leaders on printout of commands executed
58
 
59
Revision 1.6  2001/04/06 22:47:01  mjames
60
Added doc2, the creator of documentation to Vertical scripts uses PERL
61
 
62
 
63
Also correcting generic behaviour and the printing of Verilog.
64
 
65
Revision 1.5  2001/02/06 22:41:14  mjames
66
Added correct argument passing for 'read file comp_suffix arg0 arg1 arg2 ...
67
 
68
Revision 1.4  2001/01/26 21:50:10  mjames
69
Managed to get vertical non TCL to compile again
70
 
71
Conversion to argv, argc[] mode of operation continues
72
 
73
Revision 1.3  2001/01/04 21:26:54  mjames
74
Modifications to add in the TCL style
75
argument list to all of the functions
76
.
77
 
78
Revision 1.2  2001/01/02 07:53:52  mjames
79
Made changes to allow for interface with TCL/Tk
80
 
81
Revision 1.1.1.1  2000/10/19 21:58:35  mjames
82
Mike put it here
83
 
84
There has been a lot more development, but the comments have been
85
removed in order to cut down the junk
86
 
87
*********************************************************************************************************/
88
 
89
#include "cmdparse.h"
90
 
91
#include "cmdexec.h"
92
#include "cmdlog.h"
93
#include "cmdutil.h"
94
#include "database.h"
95
#include "expression.h"
96
#include "generic.h"
97
#include "vertcl_main.h"
98
 
99
#include <ctype.h>
100
#include <stdio.h>
101
#include <stdlib.h>
102
#include <string.h>
103
/* used for dynamic string allocation/deallocation code
104
 * used here for command keywords May 2 2000 */
105
#include "lx_support.h"
106
 
107
/*********************************************************************************************************/
108
#ident                                                                                        \
109
    "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/cmdlib/cmdparse.c,v 1.1.1.1 2003/11/04 23:34:56 mjames Exp $"
110
 
111
/******************************************* Execute a command
112
 * ******************************************/
113
/* define flag for global control of execution mode
114
 * can be Tcl_Cmd or  Tcl_GUI : default to be Tcl_Cmd for
115
 * backwards compatibility */
116
 
117
tcl_mode_t tcl_mode = Tcl_Cmd;
118
 
119
#define WORDWIDTH 100 /* max command word  ever expected */
120
#define CMDWIDTH 20   /*Field width for printing CMD word */
121
int Execute (int argc, char *argv[], struct command Dispatch[])
122
{
123
        int i, j, FinalResult = UNKNOWNCMD;
124
 
125
        if (!argc)
126
                return (NARGS);
127
        if (argv[0][0] == '?')
128
        {
129
                printf ("Commands available;\nHelp on:");
130
                for (i = 0; i < argc; i++)
131
                        printf ("%s ", argv[i]);
132
                putchar ('\n');
133
                for (i = 0; Dispatch[i].name; i++)
134
                {
135
                        int p;
136
                        for (j = 0; j < Dispatch[i].NumChar;
137
                             j++) /* upper case significant chars */
138
                                putchar (toupper (Dispatch[i].name[j]));
139
                        for (; Dispatch[i].name[j];
140
                             j++) /* and all of the rest, we just print */
141
                                putchar (Dispatch[i].name[j]);
142
                        putchar (' ');
143
                        j++;
144
                        if (Dispatch[i].extras)
145
                        {
146
                                p = j;
147
                                for (; Dispatch[i].extras[j - p];
148
                                     j++) /* and all of the extras field we just print */
149
                                        putchar (Dispatch[i].extras[j - p]);
150
                        };
151
                        for (; j < CMDWIDTH; j++) /* create spacing , relies on auto - wrap */
152
                                putchar (j & 1 ? '.' : ' ');
153
                        putchar (' ');
154
                        puts (Dispatch[i].helpstr);
155
                }
156
                putchar ('\n');
157
                FinalResult = OKCMD; /* ? is a valid command at this level */
158
        }
159
        else
160
        {
161
                for (i = 0; Dispatch[i].name; i++)
162
                        if (strncmp (argv[0], Dispatch[i].name, Dispatch[i].NumChar) == 0)
163
                        {
164
                                /* Dispatch the next level command */
165
                                if (Dispatch[i].function)
166
                                { /* call function if there */
167
                                        FinalResult = (*Dispatch[i].function) (
168
                                            Tcl_interp, NULL, argc - 1, argv + 1);
169
                                }
170
                                else /* call down the menu */
171
                                        FinalResult =
172
                                            Execute (argc - 1, argv + 1, Dispatch[i].Menu);
173
                                break;
174
                        }
175
        }
176
        return (FinalResult);
177
}
178
 
179
/******************************************** Strip off words
180
 * ********************************************/
181
/* this needs repairing . This code is unsafe.
182
 * Needs to keep a record of how many chars copied !!
183
 * and stop when in danger of a buffer overflow.
184
 *
185
 * Did not work properly if expanded strings are longer than the
186
 * original strings. This now fixed.
187
 *
188
 * Code modified to use some string allocation functions in lx_support.c
189
 */
190
/*char wordbuff[1024];
191
 */
192
typedef enum
193
{
194
        SPACES,
195
        CHARS
196
} Phase_t;
197
 
198
int FindWords (
199
    char *linebuff,
200
    int *pargc,
201
    char *argv[],
202
    int nArgs,
203
    char *Args[],
204
    struct str **cmd_first,
205
    struct str **cmd_last)
206
{
207
        char *WordPtr;
208
        char *BasePtr;
209
        int argc = 0;
210
        int term = ' ', escape, comment, done_word, chars_seen;
211
        char *copy_buff;
212
        Phase_t Phase;
213
 
214
        copy_buff = malloc (strlen (linebuff) + 1); /* make a safe copy */
215
 
216
        /*      for (i=0; i<Len; i++)                               */
217
        /*         Cmd->Text[i] = tolower(Cmd->Text[i]);            */ /* convert text to lower
218
                                                                          case */
219
        WordPtr = linebuff; /* set LineStart to beginning of string */
220
        escape = 0;
221
        comment = 0;
222
        /* Now split off the words */
223
        BasePtr = NULL;
224
        while (*WordPtr && argc < WORDSINLINE && comment < 2)
225
        {
226
                BasePtr = copy_buff;
227
                Phase = SPACES;
228
                term = ' ';
229
                done_word = 0;
230
                chars_seen = 0;
231
                while (*WordPtr && !done_word && comment < 2)
232
                {
233
                        switch (Phase)
234
                        {
235
                        case SPACES:
236
                                if (isspace (*WordPtr)) /* skip leading spaces */
237
                                        WordPtr++;
238
                                else
239
                                        Phase = CHARS;
240
                                break;
241
                        case CHARS:
242
                                if (!escape && *WordPtr == '\\')
243
                                {
244
                                        escape = 1;
245
                                        WordPtr++;
246
                                }
247
                                else
248
                                {
249
                                        if (term == ' ' && !escape &&
250
                                            (*WordPtr == '"' || *WordPtr == '\''))
251
                                        { /* sigle or double quotes ? */
252
                                                term = *WordPtr++;
253
                                                chars_seen = 1;
254
                                        }
255
                                        else
256
                                        {
257
                                                /* handle ordinary chars */
258
                                                if (!escape && term == ' ' &&
259
                                                    WordPtr[0] == '#')
260
                                                {
261
                                                        comment = 2;
262
                                                        done_word =
263
                                                            chars_seen; /* comment is appended
264
                                                                           to valid chars */
265
                                                        WordPtr++;
266
                                                }
267
                                                else if (
268
                                                    !escape && term == ' ' &&
269
                                                    WordPtr[0] == '-')
270
                                                {
271
                                                        comment++;
272
                                                        WordPtr++;
273
                                                        if (comment == 2)
274
                                                                done_word =
275
                                                                    chars_seen; /* comment is
276
                                                                                   appended to
277
                                                                                   valid chars
278
                                                                                 */
279
                                                }
280
                                                else if (
281
                                                    (*WordPtr == '\r') || (*WordPtr == '\n') ||
282
                                                    (!escape && (*WordPtr == term)))
283
                                                {
284
                                                        if (comment == 1)
285
                                                                *BasePtr++ = '-';
286
                                                        comment = 0;
287
                                                        Phase = SPACES;
288
                                                        *BasePtr = '\0';
289
                                                        done_word = 1;
290
                                                        WordPtr++;
291
                                                }
292
                                                else
293
                                                {
294
                                                        if (escape)
295
                                                                *BasePtr++ = '\\';
296
                                                        if (comment == 1)
297
                                                                *BasePtr++ = '-';
298
                                                        chars_seen = 1;
299
                                                        comment = 0;
300
                                                        escape = 0;
301
                                                        *BasePtr++ = *WordPtr++;
302
                                                }
303
                                        }
304
                                }
305
                                break;
306
                        } /* switch */
307
                }         /* while */
308
                *BasePtr = '\0';
309
                /* make_string now performs an expand_string call */
310
                if (chars_seen)
311
                {
312
                        argv[argc++] = make_string (copy_buff, cmd_first, cmd_last);
313
                }
314
        }
315
        *pargc = argc;
316
        free (copy_buff);
317
 
318
        return (OKCMD);
319
}
320
 
321
/********************************* executes the command from stdin or a do file
322
 * **************************/
323
 
324
int ExecuteCommand (FILE *CmdFile, int nArgs, char *Args[])
325
{
326
        char Buff[PATHLENGTH];
327
        int i, Status;
328
        char *p;
329
        int argc;
330
        char *argv[WORDSINLINE];
331
        struct str *cmd_first, *cmd_last;
332
        cmd_first = NULL;
333
        cmd_last = NULL;
334
 
335
        if (!CmdFile || feof (CmdFile))
336
                return (QUITCMD);
337
 
338
        p = fgets (Buff, PATHLENGTH - 1, CmdFile); /* read the command from the input stream */
339
        argc = 0; /* place the command in the command structure */
340
        if (p == NULL || *Buff == '\0')
341
                return (OKCMD);
342
 
343
        /* convert control codes to spaces */
344
        i = 0;
345
        while (Buff[i])
346
        {
347
                if (Buff[i] < ' ')
348
                        Buff[i] = ' ';
349
                i++;
350
        }
351
 
352
        FindWords (Buff, &argc, argv, nArgs, Args, &cmd_first, &cmd_last); /* split off the
353
                                                                              words and save in
354
                                                                              structure */
355
        if (1 || CmdFile != stdin)
356
        {
357
                printf ("-- ");
358
                for (i = 0; i < argc; i++)
359
                        printf (
360
                            "%s ",
361
                            ISNULLSTR (argv[i]) ? "\"\""
362
                                                : argv[i]); /* log the command word by word if
363
                                                               its not given interactively */
364
                printf ("\n");                              /*  */
365
        }
366
        /* the code below is not as helpful as it seems . Moved recognizer for comments into
367
           Execute as the comments can appear at any point on the command line */
368
        /*   if (argc ==0 ||
369
               argv[0][0] == '-' ||
370
               argv[0][0] == '#') */
371
        if (argc == 0)
372
        {
373
                /* deallocate any previous structures */
374
                free_strings (&cmd_first, &cmd_last);
375
                return (OKCMD); /* comment or a null string */
376
        }
377
 
378
        Status =
379
            Execute (argc, argv, TopMenu); /* pass the command through the top-level menu */
380
        switch (Status)
381
        {
382
        case UNKNOWNCMD:
383
                Log (LOG_ERROR, "# Unknown command\n");
384
                break;
385
        case NARGS:
386
                Log (LOG_ERROR, "# Too few parameters\n");
387
                break;
388
        case FAILED:
389
                Log (LOG_ERROR, "# Problem with command\n");
390
                break;
391
        };
392
 
393
        if (Status != OKCMD)
394
        {
395
                Log (LOG_ERROR, "-- ? ");
396
                for (i = 0; i < argc; i++) /*    display offending command */
397
                        Log (LOG_ERROR, " %s", ISNULLSTR (argv[i]) ? "\"\"" : argv[i]);
398
 
399
                Log (LOG_ERROR, "\n");
400
        };
401
 
402
        /* deallocate any previous structures */
403
        free_strings (&cmd_first, &cmd_last);
404
 
405
        return (Status);
406
}
407
 
408
/********************************* Execute a command string
409
 * ******************************************/
410
int ExecuteString (char *commandstring, int nArgs, char *Args[])
411
{
412
        int argc = 0;
413
        char *argv[WORDSINLINE];
414
        int Status = 0;
415
 
416
        struct str *cmd_first, *cmd_last;
417
        cmd_first = NULL;
418
        cmd_last = NULL;
419
        FindWords (
420
            commandstring, &argc, argv, nArgs, Args, &cmd_first, &cmd_last); /* split off the
421
                                                                                words and save
422
                                                                                in structure */
423
        Status =
424
            Execute (argc, argv, TopMenu); /* pass the command through the top-level menu */
425
                                           /* deallocate any previous structures */
426
        free_strings (&cmd_first, &cmd_last);
427
        return (Status);
428
}
429
 
430
/********************************* A parser for the '*.do files
431
 * ******************************************/
432
static int Depth = 0;
433
#define MAXDEPTH 10 /* maximum depth of 'do' files */
434
#define MAXARGV 10
435
int ParseFile (FILE *CmdFile, int nArgs, char *Args[])
436
{
437
        int Status = 0;
438
        char *argp[MAXARGV];
439
        char **argp_prev;
440
        int nArgs_prev;
441
        int i;
442
        /* diagnosis */
443
        if (nArgs > MAXARGV)
444
                nArgs = MAXARGV;
445
        if (nArgs < 0)
446
                nArgs = 0;
447
        /* belt and braces null check */
448
        if (!CmdFile)
449
                return (FAILED);
450
 
451
        for (i = 0; i < MAXARGV; i++)
452
        {
453
                if (i < nArgs)
454
                        argp[i] = strdup (Args[i]);
455
                else
456
                        argp[i] = NULL;
457
 
458
                /* printf("Arg [%2d]='%s'\n",i,argp[i]);  */
459
        }
460
        nArgs_prev = yy_nArgs;
461
        argp_prev = yy_Args;
462
        yy_nArgs = nArgs;
463
        yy_Args = argp;
464
 
465
        Depth++; /* keep a count of recursion depth */
466
        printf ("-- Command file nesting level = %d\n", Depth);
467
        if (Depth > MAXDEPTH)
468
        {
469
                Log (LOG_ERROR, "Recursive call of files is greater than %d\n", MAXDEPTH);
470
                Depth--;
471
                return (FAILED);
472
        }
473
        while (Status == OKCMD) /* execute the command from do file input stream */
474
                Status = ExecuteCommand (CmdFile, nArgs, argp);
475
        Depth--;
476
        yy_nArgs = nArgs_prev;
477
        yy_Args = argp_prev;
478
        for (i = 0; i < MAXARGV; i++)
479
                if (argp[i])
480
                {
481
                        free (argp[i]);
482
                        argp[i] = NULL;
483
                }
484
        return (Status);
485
}
486
 
487
/*********************************************************************************************************/