Subversion Repositories Vertical

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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