w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

sh2.c
Go to the documentation of this file.
1 /*
2  * MS-DOS SHELL - Symantic Parser
3  *
4  * MS-DOS SHELL - Copyright (c) 1990,4 Data Logic Limited and Charles Forsyth
5  *
6  * This code is based on (in part) the shell program written by Charles
7  * Forsyth and the subsequence modifications made by Simon J. Gerraty (for
8  * his Public Domain Korn Shell) and is subject to the following copyright
9  * restrictions:
10  *
11  * 1. Redistribution and use in source and binary forms are permitted
12  * provided that the above copyright notice is duplicated in the
13  * source form and the copyright notice in file sh6.c is displayed
14  * on entry to the program.
15  *
16  * 2. The sources (or parts thereof) or objects generated from the sources
17  * (or parts of sources) cannot be sold under any circumstances.
18  *
19  *
20  * $Header: /usr/users/istewart/shell/sh2.3/Release/RCS/sh2.c,v 2.12 1994/08/25 20:49:11 istewart Exp $
21  *
22  * $Log: sh2.c,v $
23  * Revision 2.12 1994/08/25 20:49:11 istewart
24  * MS Shell 2.3 Release
25  *
26  * Revision 2.11 1994/02/01 10:25:20 istewart
27  * Release 2.3 Beta 2, including first NT port
28  *
29  * Revision 2.10 1994/01/11 17:55:25 istewart
30  * Release 2.3 Beta 0 patches
31  *
32  * Revision 2.9 1993/08/25 16:03:57 istewart
33  * Beta 225 - see Notes file
34  *
35  * Revision 2.8 1993/07/02 10:21:35 istewart
36  * 224 Beta fixes
37  *
38  * Revision 2.7 1993/06/14 11:00:12 istewart
39  * More changes for 223 beta
40  *
41  * Revision 2.6 1993/06/02 09:52:35 istewart
42  * Beta 223 Updates - see Notes file
43  *
44  * Revision 2.5 1993/02/16 16:03:15 istewart
45  * Beta 2.22 Release
46  *
47  * Revision 2.4 1993/01/26 18:35:09 istewart
48  * Release 2.2 beta 0
49  *
50  * Revision 2.3 1992/11/06 10:03:44 istewart
51  * 214 Beta test updates
52  *
53  * Revision 2.2 1992/09/03 18:54:45 istewart
54  * Beta 213 Updates
55  *
56  * Revision 2.1 1992/07/10 10:52:48 istewart
57  * 211 Beta updates
58  *
59  * Revision 2.0 1992/04/13 17:39:09 Ian_Stewartson
60  * MS-Shell 2.0 Baseline release
61  *
62  */
63 
64 #include <sys/types.h>
65 #include <sys/stat.h>
66 #include <stdio.h>
67 #include <stddef.h>
68 #include <signal.h>
69 #include <errno.h>
70 #include <setjmp.h>
71 #include <string.h>
72 #include <ctype.h>
73 #include <unistd.h>
74 #include <limits.h>
75 #include <dirent.h>
76 #include "sh.h"
77 
78 static C_Op * F_LOCAL ScanPipeSyntax (int);
79 static C_Op * F_LOCAL ScanAndOrSyntax (void);
80 static C_Op * F_LOCAL CommandList (void);
81 static IO_Actions * F_LOCAL SynchroniseIOList (int);
82 static void F_LOCAL CheckNextTokenIS (int, int);
83 static void F_LOCAL SyntaxError (char *);
84 static C_Op * F_LOCAL ScanNestedSyntax (int, int);
85 static C_Op * F_LOCAL ScanSimpleCommand (int);
86 static C_Op * F_LOCAL GetDoDoneCommandList (void);
87 static C_Op * F_LOCAL ThenPartList (void);
88 static C_Op * F_LOCAL ElsePartList (void);
89 static C_Op * F_LOCAL CaseList (void);
90 static C_Op * F_LOCAL CaseListEntries (void);
91 static char ** F_LOCAL GetINWordList (void);
92 static C_Op * F_LOCAL SetupTreeNode (int, C_Op *, C_Op *, char **);
93 static C_Op * F_LOCAL CreateTreeNode (void);
94 static C_Op * F_LOCAL yyparse (void);
95 static char * F_LOCAL LookUpToken (int);
96 static int F_LOCAL GetNextToken (int);
97 static int F_LOCAL LookAtNextToken (int);
98 static char * F_LOCAL MemoryDup (char *, size_t);
99 
100 static char *LIT_2ManyRedir = "Too many redirections";
101 static char *LIT_Expecting = "%s - Expecting '%s', found '%s'";
102 
103 /*
104  * Special strings for (( and ))
105  */
106 
107 static char LIT_ODP [] = {
108  WORD_CHAR,
110  WORD_CHAR,
112  0
113 };
114 
115 static char LIT_CDP [] = {
116  WORD_CHAR,
118  WORD_CHAR,
120  0
121 };
122 
123 /* Special [[ */
124 
125 static char LIT_ODB [] = {
126  WORD_CHAR,
128  WORD_CHAR,
130  0
131 };
132 
133 /*
134  * Other statics
135  */
136 
137 static bool reject; /* GetNextToken(cf) gets symbol */
138  /* again */
139 static int symbol; /* yylex value */
140 
141 #define NEWNODE ((C_Op *)CreateTreeNode ())
142 #define REJECT (reject = TRUE)
143 #define ACCEPT (reject = FALSE)
144 
145 /*
146  * Get the next token from input
147  */
148 
149 static int F_LOCAL GetNextToken (int cf)
150 {
151  if (reject)
152  ACCEPT;
153 
154  else
155  {
156  symbol = ScanNextToken (cf);
157  ACCEPT;
158  }
159 
160  return symbol;
161 }
162 
163 /*
164  * Look at the next token from input
165  */
166 
167 static int F_LOCAL LookAtNextToken (int cf)
168 {
169  if (!reject)
170  {
171  symbol = ScanNextToken (cf);
172  REJECT;
173  }
174 
175  return symbol;
176 }
177 
178 /*
179  * Parse the current input stack
180  */
181 
182 static C_Op * F_LOCAL yyparse (void)
183 {
184  C_Op *t; /* yyparse output */
185 
186  ACCEPT;
187  yynerrs = 0;
188 
189 /* Check for EOF */
190 
192  {
193  (t = NEWNODE)->type = TEOF;
194  DPRINT (1, ("yyparse: Create TEOF"));
195  }
196 
197  else
198  {
199  t = CommandList ();
201  }
202 
203  return t;
204 }
205 
206 /*
207  * Check a pipeline
208  */
209 
210 static C_Op * F_LOCAL ScanPipeSyntax (int LexicalControlFlags)
211 {
212  C_Op *t, *p, *tl = NULL;
213 
214  if ((t = ScanSimpleCommand (LexicalControlFlags)) != (C_Op *)NULL)
215  {
216  while (GetNextToken (0) == CHAR_PIPE)
217  {
219  SyntaxError ("no commands found following pipe");
220 
221  if (tl == NULL)
222  {
223  tl = SetupTreeNode (TPIPE, t, p, NOWORDS);
224  t = tl;
225  }
226 
227  else
228  {
229  tl->right = SetupTreeNode (TPIPE, tl->right, p, NOWORDS);
230  tl = tl->right;
231  }
232  }
233 
234  REJECT;
235  }
236 
237  return t;
238 }
239 
240 static C_Op * F_LOCAL ScanAndOrSyntax (void)
241 {
242  C_Op *t, *p;
243  int c;
244 
245  t = ScanPipeSyntax (0);
246 
247  if (t != NULL)
248  {
249  while (((c = GetNextToken (0)) == PARSE_LOGICAL_AND) ||
250  (c == PARSE_LOGICAL_OR))
251  {
253  SyntaxError ("no commands found following || or &&");
254 
255  t = SetupTreeNode ((c == PARSE_LOGICAL_AND) ? TAND : TOR, t, p,
256  NOWORDS);
257  }
258 
259  REJECT;
260  }
261 
262  return t;
263 }
264 
265 static C_Op *F_LOCAL CommandList (void)
266 {
267  C_Op *t, *p, *tl = NULL;
268  int c;
269 
270  if ((t = ScanAndOrSyntax ()) != NULL)
271  {
272  while (((c = GetNextToken (0)) == CHAR_SEPARATOR) ||
273  (c == CHAR_ASYNC) || (c == PARSE_COPROCESS) ||
274  ((AllowMultipleLines ||
275  (source->type == SSTRING) ||
276  (source->type == SALIAS)) && (c == CHAR_NEW_LINE)))
277  {
278  if ((c == CHAR_ASYNC) || (c == PARSE_COPROCESS))
279  {
280  c = (c == CHAR_ASYNC) ? TASYNC : TCOPROCESS;
281 
282  if (tl)
283  tl->right = SetupTreeNode (c, tl->right, NOBLOCK, NOWORDS);
284 
285  else
286  t = SetupTreeNode (c, t, NOBLOCK, NOWORDS);
287  }
288 
289  if ((p = ScanAndOrSyntax ()) == NULL)
290  return t;
291 
292  if (tl == NULL)
293  {
294  tl = SetupTreeNode (TLIST, t, p, NOWORDS);
295  t = tl;
296  }
297 
298  else
299  {
300  tl->right = SetupTreeNode (TLIST, tl->right, p, NOWORDS);
301  tl = tl->right;
302  }
303  }
304 
305  REJECT;
306  }
307 
308  return t;
309 }
310 
311 /*
312  * Handle IO re-direction
313  */
314 
315 static IO_Actions * F_LOCAL SynchroniseIOList (int LexicalControlFlags)
316 {
317  IO_Actions *iop;
318 
319  if (LookAtNextToken (LexicalControlFlags) != PARSE_REDIR)
320  return (IO_Actions *)NULL;
321 
322  ACCEPT;
323  iop = yylval.iop;
325  iop->io_name = yylval.cp;
326 
327  if ((iop->io_flag & IOTYPE) == IOHERE)
328  {
329  if (*CurrentLexIdentifier != 0) /* unquoted */
330  iop->io_flag |= IOEVAL;
331 
332  SaveHereDocumentInfo (iop);
333  }
334 
335  return iop;
336 }
337 
338 static void F_LOCAL CheckNextTokenIS (int c, int LexicalControlFlags)
339 {
340  int got;
341 
342  if ((got = GetNextToken (LexicalControlFlags)) != c)
343  {
344  CompilingError ();
346  LookUpToken (got));
347  }
348 }
349 
350 /*
351  * Handle Nested thingys - ( and {
352  */
353 
354 static C_Op * F_LOCAL ScanNestedSyntax (int type, int mark)
355 {
356  C_Op *t;
357 
359  t = CommandList ();
362  return SetupTreeNode (type, t, NOBLOCK, NOWORDS);
363 }
364 
365 /*
366  * Handle a single command and its bits and pieces - IO redirection,
367  * arguments and variable assignments
368  */
369 
370 static C_Op * F_LOCAL ScanSimpleCommand (int LexicalControlFlags)
371 {
372  C_Op *t;
373  int c;
374  IO_Actions *iop;
375  Word_B *Arguments = (Word_B *)NULL;
376  Word_B *Variables = (Word_B *)NULL;
377  Word_B *IOactions = (Word_B *)NULL;
378 
379 /* Allocate space for IO actions structures */
380 
381  if (AllowMultipleLines)
382  LexicalControlFlags = ALLOW_CONTINUATION;
383 
384  LexicalControlFlags |= ALLOW_KEYWORD | ALLOW_ALIAS;
385 
386  while ((iop = SynchroniseIOList (LexicalControlFlags)) != NULL)
387  {
388  if (WordBlockSize (IOactions) >= NUFILE)
389  {
390  CompilingError ();
392  }
393 
394  IOactions = AddWordToBlock ((char *)iop, IOactions);
395  LexicalControlFlags &=~~ ALLOW_CONTINUATION;
396  }
397 
398  switch (c = GetNextToken (LexicalControlFlags))
399  {
400  case 0:
401  CompilingError ();
402  ShellErrorMessage ("unexpected EOF");
403  return NULL;
404 
405  case CHAR_SEPARATOR:
406  REJECT;
407  (t = NEWNODE)->type = TCOM;
408  DPRINT (1, ("ScanSimpleCommand: Create TCOM"));
409  break;
410 
411  default:
412  REJECT;
413 
414  if (WordBlockSize (IOactions) == 0)
415  return (C_Op *)NULL; /* empty line */
416 
417  (t = NEWNODE)->type = TCOM;
418  DPRINT (1, ("ScanSimpleCommand: Create TCOM"));
419  break;
420 
421  case PARSE_WORD:
422  case PARSE_MDPAREN:
423  REJECT;
424  (t = NEWNODE)->type = TCOM;
425  DPRINT (1, ("ScanSimpleCommand: Create TCOM"));
426 
427  if (c == PARSE_MDPAREN)
428  {
429  ACCEPT;
430  Arguments = AddWordToBlock (MemoryDup (LIT_ODP, 5), Arguments);
432  Arguments = AddWordToBlock (yylval.cp, Arguments);
433  Arguments = AddWordToBlock (MemoryDup (LIT_CDP, 5), Arguments);
434  }
435 
436  while (1)
437  {
438  switch (LookAtNextToken (0))
439  {
440  case PARSE_REDIR:
441  if (WordBlockSize (IOactions) >= NUFILE)
442  {
443  CompilingError ();
445  }
446 
447  IOactions = AddWordToBlock (
448  (char *)SynchroniseIOList (0),
449  IOactions);
450  break;
451 
452 /*
453  * Word - check to see if this should be an argument or a variable,
454  * depending on what we've seen, the state of the k flag and an
455  * assignment in the word
456  */
457 
458  case PARSE_WORD:
459  ACCEPT;
460  if (((WordBlockSize (Arguments) == 0) ||
463  (char *)NULL))
464  Variables = AddWordToBlock (yylval.cp, Variables);
465 
466  else
467  Arguments = AddWordToBlock (yylval.cp, Arguments);
468 
469  break;
470 
471  case PARSE_MPAREN:
472  ACCEPT;
473 
474  if (WordBlockSize (Arguments) != 1)
475  SyntaxError ("Too many function names");
476 
477  if (*CurrentLexIdentifier == 0)
478  SyntaxError ("Bad function name");
479 
480  (t = NEWNODE)->type = TFUNC;
481  DPRINT (1, ("ScanSimpleCommand: Create TFUNC"));
486  return t;
487 
488  default:
489  goto Leave;
490  }
491  }
492 Leave:
493  break;
494 
497  break;
498 
499  case CHAR_OPEN_BRACES:
501  break;
502 
503 /*
504  * Format for: [[ ..... ]]
505  */
506 
507  case PARSE_TEST:
508  (t = NEWNODE)->type = TCOM;
509  DPRINT (1, ("ScanSimpleCommand: Create TCOM"));
510  Arguments = AddWordToBlock (MemoryDup (LIT_ODB, 5), Arguments);
511 
513  {
514  Arguments = AddWordToBlock (yylval.cp, Arguments);
515 
516  if (strcmp (CurrentLexIdentifier , "]]") == 0)
517  break;
518  }
519 
520  break;
521 
522 /*
523  * Format for: select word in list do .... done
524  * select word do .... done
525  * for word in list do .... done
526  * for word do .... done
527  */
528 
529  case PARSE_FOR:
530  case PARSE_SELECT:
531  (t = NEWNODE)->type = (c == PARSE_FOR) ? TFOR : TSELECT;
532  DPRINT (1, ("ScanSimpleCommand: Create TFOR/TSELECT"));
536  t->vars = GetINWordList ();
537  t->left = GetDoDoneCommandList ();
539  break;
540 
541 
542 /*
543  * Format for: while command do ... done
544  * until command do ... done
545  */
546 
547  case PARSE_WHILE:
548  case PARSE_UNTIL:
550  (t = NEWNODE)->type = (c == PARSE_WHILE) ? TWHILE : TUNTIL;
551  DPRINT (1, ("ScanSimpleCommand: Create TWHILE/TUNTIL"));
552  t->left = CommandList ();
553  t->right = GetDoDoneCommandList ();
555  break;
556 
557 /*
558  * Format for: case name in .... esac
559  */
560 
561  case PARSE_CASE:
562  (t = NEWNODE)->type = TCASE;
563  DPRINT (1, ("ScanSimpleCommand: Create TCASE"));
565  t->str = yylval.cp;
568  t->left = CaseList ();
571  break;
572 
573 /*
574  * Format for: if command then command fi
575  * if command then command else command fi
576  * if command then command elif command then ... else ... fi
577  */
578 
579  case PARSE_IF:
581  (t = NEWNODE)->type = TIF;
582  DPRINT (1, ("ScanSimpleCommand: Create TIF"));
583  t->left = CommandList ();
584  t->right = ThenPartList ();
587  break;
588 
589 /*
590  * Format for: time command
591  */
592 
593  case PARSE_TIME:
596  break;
597 
598 /*
599  * Format for: function name { .... }
600  */
601 
602  case PARSE_FUNCTION:
603  (t = NEWNODE)->type = TFUNC;
604  DPRINT (1, ("ScanSimpleCommand: Create TFUNC"));
610  break;
611  }
612 
613 /* Get any remaining IOactions */
614 
615  while ((iop = SynchroniseIOList (ALLOW_KEYWORD)) != NULL)
616  {
617  if (WordBlockSize (IOactions) >= NUFILE)
618  {
619  CompilingError ();
621  }
622 
623  IOactions = AddWordToBlock ((char *)iop, IOactions);
624  }
625 
626 /* Save the IOactions */
627 
628  if (WordBlockSize (IOactions) == 0)
629  t->ioact = (IO_Actions **)NULL;
630 
631  else
632  t->ioact = (IO_Actions **) GetWordList (AddWordToBlock (NOWORD,
633  IOactions));
634 
635 /* If TCOM, save the arguments and variable assignments */
636 
637  if (t->type == TCOM)
638  {
639  t->args = GetWordList (AddWordToBlock (NOWORD, Arguments));
640  t->vars = GetWordList (AddWordToBlock (NOWORD, Variables));
641  }
642 
643 /* Handle re-direction on other pipelines */
644 
645  else if ((t->type != TPAREN) && (t->ioact != (IO_Actions **)NULL))
646  {
647  C_Op *t1 = t;
648 
649  (t = NEWNODE)->type = TPAREN;
650  DPRINT (1, ("ScanSimpleCommand: Create TPAREN"));
651  t->left = t1;
652  t->right = NOBLOCK;
653  t->args = NOWORDS;
654  t->vars = NOWORDS;
655  t->ioact = t1->ioact;
656  t1->ioact = (IO_Actions **)NULL;
657  }
658 
659 /*
660  * We should probably release IOactions, Arguments and Variables if they
661  * are not used. However, I don't think its necessary. The release memory
662  * level should do it.
663  */
664 
665  return t;
666 }
667 
668 
669 /*
670  * Processing for the do grouping - do ... done
671  */
672 
674 {
675  int c;
676  C_Op *list;
677 
679  {
680  CompilingError ();
682  LookUpToken (c));
683  }
684 
685  list = CommandList ();
687  return list;
688 }
689 
690 
691 /*
692  * Handle the then part of an if statement
693  */
694 
695 static C_Op * F_LOCAL ThenPartList (void)
696 {
697  C_Op *t;
698 
699  if (GetNextToken (0) != PARSE_THEN)
700  {
701  REJECT;
702  return (C_Op *)NULL;
703  }
704 
705  (t = NEWNODE)->type = 0;
706  DPRINT (1, ("ThenPartList: Create dummy"));
707 
708  if ((t->left = CommandList ()) == (C_Op *)NULL)
709  SyntaxError ("no command found after then");
710 
711  t->right = ElsePartList ();
712  return t;
713 }
714 
715 
716 /*
717  * Handle the else part of an if statement
718  */
719 
720 static C_Op * F_LOCAL ElsePartList (void)
721 {
722  C_Op *t;
723 
724  switch (GetNextToken (0))
725  {
726  case PARSE_ELSE:
727  if ((t = CommandList ()) == (C_Op *)NULL)
728  SyntaxError ("no commands associated with else");
729 
730  return t;
731 
732  case PARSE_ELIF:
733  (t = NEWNODE)->type = TELIF;
734  DPRINT (1, ("ElsePartList: Create TELIF"));
735  t->left = CommandList ();
736  t->right = ThenPartList ();
737  return t;
738 
739  default:
740  REJECT;
741  return (C_Op *)NULL;
742  }
743 }
744 
745 
746 /*
747  * Process the CASE statment
748  */
749 
750 static C_Op * F_LOCAL CaseList (void)
751 {
752  C_Op *t = (C_Op *)NULL;
753  C_Op *tl = (C_Op *)NULL;
754 
756  {
757  C_Op *tc = CaseListEntries ();
758 
759  if (tl == (C_Op *)NULL)
760  {
761  t = tc;
762  (tl = tc)->right = (C_Op *)NULL;
763  }
764 
765  else
766  {
767  tl->right = tc;
768  tl = tc;
769  }
770  }
771 
772  return t;
773 }
774 
775 
776 /*
777  * Process an individual case entry: pattern) commands;;
778  */
779 
780 static C_Op * F_LOCAL CaseListEntries (void)
781 {
782  C_Op *t;
783  int LexicalControlFlags = ALLOW_CONTINUATION | ALLOW_KEYWORD;
784  Word_B *Patterns = (Word_B *)NULL;
785 
786  (t = NEWNODE)->type = TPAT;
787  DPRINT (1, ("CaseListEntries: Create TPAT"));
788 
789  if (GetNextToken (LexicalControlFlags) != CHAR_OPEN_PARATHENSIS)
790  REJECT;
791 
792  else
793  LexicalControlFlags = 0;
794 
795  do
796  {
797  CheckNextTokenIS (PARSE_WORD, LexicalControlFlags);
798  Patterns = AddWordToBlock (yylval.cp, Patterns);
799  LexicalControlFlags = 0;
800  } while (GetNextToken (0) == CHAR_PIPE);
801 
802  REJECT;
803 
804 /*
805  * Terminate the list of patterns
806  */
807 
808  t->vars = GetWordList (AddWordToBlock (NOWORD, Patterns));
809 
810 /*
811  * Check for the terminating ), and get the command list
812  */
813 
815 
816  t->left = CommandList ();
817 
820 
821  return (t);
822 }
823 
824 
825 /*
826  * Handle the in words.... part of a for or select statement. Get the
827  * words and build a list.
828  */
829 
830 static char ** F_LOCAL GetINWordList (void)
831 {
832  int c;
833  Word_B *Parameters = (Word_B *)NULL;
834 
835 /*
836  * Check to see if the next symbol is "in". If not there are no words
837  * following
838  */
839 
841  {
842  REJECT;
843  return NOWORDS;
844  }
845 
846 /* Get the list */
847 
848  while ((c = GetNextToken (0)) == PARSE_WORD)
849  Parameters = AddWordToBlock (yylval.cp, Parameters);
850 
851  if ((c != CHAR_NEW_LINE) && (c != CHAR_SEPARATOR))
852  {
853  CompilingError ();
854  ShellErrorMessage (LIT_Expecting, LIT_SyntaxError, "newline' or ';",
855  LookUpToken (c));
856  }
857 
858 /* Are there any words found? */
859 
860  if (Parameters == (Word_B *)NULL)
861  return NOWORDS;
862 
863  return GetWordList (AddWordToBlock (NOWORD, Parameters));
864 }
865 
866 /*
867  * supporting functions
868  */
869 
870 static C_Op * F_LOCAL SetupTreeNode (int type, C_Op *t1, C_Op *t2, char **wp)
871 {
872  C_Op *t;
873 
874  (t = NEWNODE)->type = type;
875  DPRINT (1, ("SetupTreeNode: Create %d", type));
876  t->left = t1;
877  t->right = t2;
878  t->vars = wp;
879  return t;
880 }
881 
882 /*
883  * Get and compile the next command from the user/file etc
884  */
885 
887 {
888  C_Op *t; /* yyparse output */
889 
890  yynerrs = 0;
891  AllowMultipleLines = 0;
892  source = s;
893 
894  t = yyparse ();
895 
896  if (s->type == STTY || s->type == SFILE)
897  s->str = null; /* line is not preserved */
898 
899  return yynerrs ? (C_Op *)NULL : t;
900 }
901 
902 /*
903  * Get a new tree leaf structure
904  */
905 
906 static C_Op * F_LOCAL CreateTreeNode (void)
907 {
908  C_Op *t;
909 
910  if ((t = (C_Op *)AllocateMemoryCell (sizeof (C_Op))) == (C_Op *)NULL)
911  ShellErrorMessage ("command line too complicated");
912 
913  return t;
914 }
915 
916 /*
917  * List of keywords
918  */
919 
920 static struct res {
921  char *r_name;
922  int r_val;
923 } restab[] = {
924  { "for", PARSE_FOR}, { "case", PARSE_CASE},
925  { "esac", PARSE_ESAC}, { "while", PARSE_WHILE},
926  { "do", PARSE_DO}, { LIT_done, PARSE_DONE},
927  { "if", PARSE_IF}, { "in", PARSE_IN},
928  { "then", PARSE_THEN}, { "else", PARSE_ELSE},
929  { "elif", PARSE_ELIF}, { "until", PARSE_UNTIL},
930  { "fi", PARSE_FI}, { "select", PARSE_SELECT},
931  { "time", PARSE_TIME}, { "function", PARSE_FUNCTION},
932  { LIT_Test, PARSE_TEST},
933  { "{", CHAR_OPEN_BRACES}, { "}", CHAR_CLOSE_BRACES},
934 
935  { (char *)NULL, 0},
936 
937 /* Additional definitions */
938 
939  { "word", PARSE_WORD}, { "&&", PARSE_LOGICAL_AND},
940  { "||", PARSE_LOGICAL_OR}, { "redirection",PARSE_REDIR },
941  { "(..)", PARSE_MPAREN}, { "((...))", PARSE_MDPAREN},
942  { "|&", PARSE_COPROCESS}, { "newline",'\n'},
943 
944  { (char *)NULL, 0}
945 };
946 
947 int LookUpSymbol (char *n)
948 {
949  struct res *rp = restab;
950 
951  while ((rp->r_name != (char *)NULL) && strcmp (rp->r_name, n))
952  rp++;
953 
954  return rp->r_val;
955 }
956 
957 static char * F_LOCAL LookUpToken (int n)
958 {
959  struct res *rp = restab;
960  int first = TRUE;
961 
962  while (TRUE)
963  {
964  if ((rp->r_name == (char *)NULL) && !first)
965  {
966  char *cp = GetAllocatedSpace (4);
967 
968  if (cp == (char *)NULL)
969  return (char *)NULL;
970 
971  sprintf (cp, "%c", n);
972  return cp;
973  }
974 
975  else if (rp->r_name == (char *)NULL)
976  first = FALSE;
977 
978  else if (rp->r_val == n)
979  return rp->r_name;
980 
981  rp++;
982  }
983 }
984 
985 /*
986  * Syntax error
987  */
988 
989 static void F_LOCAL SyntaxError (char *emsg)
990 {
991  CompilingError ();
992  ShellErrorMessage ("%s - %s", LIT_SyntaxError, emsg);
993 }
994 
995 /*
996  * Duplicate a memory string
997  */
998 
999 static char * F_LOCAL MemoryDup (char *string, size_t length)
1000 {
1001  char *t;
1002 
1003  if ((t = AllocateMemoryCell (length)) == (char *)NULL)
1004  ShellErrorMessage ("Out of memory");
1005 
1006  return memcpy (t, string, length);
1007 }
rp
Definition: action.c:992
cp
Definition: action.c:1035
#define mark
Definition: aptex-macros.h:374
#define type(a)
Definition: aptex-macros.h:171
@ SSTRING
Definition: cmscgats.c:55
#define n
Definition: t4ht.c:1290
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int strcmp()
Definition: coll.cpp:143
#define yylval
#define yynerrs
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define strchr
Definition: gsftopk.c:59
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
@ right
Definition: annotate.c:15
#define length(c)
Definition: ctangleboot.c:65
#define sprintf
Definition: snprintf.c:44
cell * list
Definition: list_routines.h:30
#define t1
#define t2
static int32_t first
Definition: ppagelist.c:29
static char * LIT_Expecting
Definition: sh2.c:101
C_Op * BuildParseTree(Source *s)
Definition: sh2.c:886
static char *near LookUpToken(int)
Definition: sh2.c:957
#define NEWNODE
Definition: sh2.c:141
static C_Op *near yyparse(void)
Definition: sh2.c:182
static struct res restab[]
static char * LIT_2ManyRedir
Definition: sh2.c:100
static int symbol
Definition: sh2.c:139
static C_Op *near GetDoDoneCommandList(void)
Definition: sh2.c:673
#define ACCEPT
Definition: sh2.c:143
static char LIT_CDP[]
Definition: sh2.c:115
static C_Op *near ScanAndOrSyntax(void)
Definition: sh2.c:240
static C_Op *near SetupTreeNode(int, C_Op *, C_Op *, char **)
Definition: sh2.c:870
static void near CheckNextTokenIS(int, int)
Definition: sh2.c:338
static int near LookAtNextToken(int)
Definition: sh2.c:167
static C_Op *near ScanPipeSyntax(int)
Definition: sh2.c:210
static C_Op *near ThenPartList(void)
Definition: sh2.c:695
static bool reject
Definition: sh2.c:137
static IO_Actions *near SynchroniseIOList(int)
Definition: sh2.c:315
static C_Op *near CaseList(void)
Definition: sh2.c:750
#define REJECT
Definition: sh2.c:142
int LookUpSymbol(char *n)
Definition: sh2.c:947
static char *near MemoryDup(char *, size_t)
Definition: sh2.c:999
static C_Op *near ElsePartList(void)
Definition: sh2.c:720
static C_Op *near ScanSimpleCommand(int)
Definition: sh2.c:370
static void near SyntaxError(char *)
Definition: sh2.c:989
static int near GetNextToken(int)
Definition: sh2.c:149
static C_Op *near CommandList(void)
Definition: sh2.c:265
static char LIT_ODP[]
Definition: sh2.c:107
static char LIT_ODB[]
Definition: sh2.c:125
static C_Op *near ScanNestedSyntax(int, int)
Definition: sh2.c:354
static C_Op *near CaseListEntries(void)
Definition: sh2.c:780
static char **near GetINWordList(void)
Definition: sh2.c:830
static C_Op *near CreateTreeNode(void)
Definition: sh2.c:906
#define PARSE_TIME
Definition: sh.h:1305
#define F_LOCAL
Definition: sh.h:121
#define PARSE_SELECT
Definition: sh.h:1303
#define PARSE_FUNCTION
Definition: sh.h:1304
#define CHAR_NEW_LINE
Definition: sh.h:1007
#define PARSE_MDPAREN
Definition: sh.h:1308
#define PARSE_WORD
Definition: sh.h:1286
#define PARSE_ELIF
Definition: sh.h:1293
#define TFUNC
Definition: sh.h:1257
#define FL_TEST(x)
Definition: sh.h:1705
#define TPAT
Definition: sh.h:1254
#define PARSE_DONE
Definition: sh.h:1301
char LIT_Test[]
Definition: sh6.c:276
#define TSELECT
Definition: sh.h:1258
#define PARSE_THEN
Definition: sh.h:1291
#define TCOM
Definition: sh.h:1241
#define STTY
Definition: sh.h:1363
void * GetAllocatedSpace(size_t)
Definition: sh1.c:1241
#define PARSE_FOR
Definition: sh.h:1297
#define PARSE_IN
Definition: sh.h:1302
int ScanNextToken(int)
Definition: sh5.c:153
#define PARSE_WHILE
Definition: sh.h:1298
char CurrentLexIdentifier[64+1]
Definition: sh6.c:346
#define TCOPROCESS
Definition: sh.h:1248
#define PARSE_REDIR
Definition: sh.h:1306
#define PARSE_CASE
Definition: sh.h:1295
#define PARSE_FI
Definition: sh.h:1294
char * LIT_SyntaxError
Definition: sh6.c:269
#define CHAR_ASSIGN
Definition: sh.h:1054
#define PARSE_MPAREN
Definition: sh.h:1307
#define PARSE_BREAK
Definition: sh.h:1289
#define PARSE_TEST
Definition: sh.h:1309
#define TTIME
Definition: sh.h:1259
#define PARSE_ESAC
Definition: sh.h:1296
#define CHAR_ASYNC
Definition: sh.h:1035
#define TFOR
Definition: sh.h:1247
#define PARSE_COPROCESS
Definition: sh.h:1310
#define PARSE_DO
Definition: sh.h:1300
#define WORD_CHAR
Definition: sh.h:1266
#define IOEVAL
Definition: sh.h:1659
#define MATHS_EXPRESSION
Definition: sh.h:1334
#define TPIPE
Definition: sh.h:1243
#define TCASE
Definition: sh.h:1249
#define TELIF
Definition: sh.h:1253
#define PARSE_LOGICAL_OR
Definition: sh.h:1288
#define CHAR_OPEN_PARATHENSIS
Definition: sh.h:1019
char LIT_done[]
Definition: sh6.c:259
#define NOWORD
Definition: sh.h:1149
void SaveHereDocumentInfo(IO_Actions *)
Definition: sh5.c:1365
#define TBRACE
Definition: sh.h:1255
#define CHAR_OPEN_BRACES
Definition: sh.h:1021
#define CHAR_OPEN_BRACKETS
Definition: sh.h:1023
#define IOHERE
Definition: sh.h:1655
int WordBlockSize(Word_B *)
Definition: system.c:1779
#define TLIST
Definition: sh.h:1244
#define IOTYPE
Definition: sh.h:1651
int AllowMultipleLines
Definition: sh6.c:126
char * StringCopy(char *)
Definition: sh1.c:1325
Word_B * AddWordToBlock(char *, Word_B *)
Definition: system.c:1748
#define SALIAS
Definition: sh.h:1368
#define NOWORDS
Definition: sh.h:1150
#define PARSE_UNTIL
Definition: sh.h:1299
#define ALLOW_CONTINUATION
Definition: sh.h:1329
#define TOR
Definition: sh.h:1245
#define ALLOW_ALIAS
Definition: sh.h:1332
char ** GetWordList(Word_B *)
Definition: sh8.c:1483
#define TWHILE
Definition: sh.h:1251
#define CHAR_SEPARATOR
Definition: sh.h:1045
void ShellErrorMessage(char *,...)
Definition: sh1.c:1032
#define DPRINT(a, b)
Definition: sh.h:2458
#define TIF
Definition: sh.h:1250
#define SFILE
Definition: sh.h:1364
#define TPAREN
Definition: sh.h:1242
void CompilingError(void)
Definition: sh5.c:1004
#define CHAR_PIPE
Definition: sh.h:1026
#define PARSE_LOGICAL_AND
Definition: sh.h:1287
#define CHAR_CLOSE_BRACES
Definition: sh.h:1022
#define ALLOW_KEYWORD
Definition: sh.h:1333
char * AllocateMemoryCell(size_t)
Definition: sh1.c:2071
#define NOBLOCK
Definition: sh.h:1148
#define FLAG_ALL_KEYWORDS
Definition: sh.h:1721
#define NUFILE
Definition: sh.h:999
#define TAND
Definition: sh.h:1246
#define PARSE_ELSE
Definition: sh.h:1292
#define PARSE_IF
Definition: sh.h:1290
#define TEST_EXPRESSION
Definition: sh.h:1335
#define CHAR_CLOSE_PARATHENSIS
Definition: sh.h:1020
#define TUNTIL
Definition: sh.h:1252
#define TEOF
Definition: sh.h:1240
#define TASYNC
Definition: sh.h:1256
Definition: sh.h:1645
short io_flag
Definition: sh.h:1647
char * io_name
Definition: sh.h:1648
Definition: sh.h:1226
struct op * right
Definition: sh.h:1232
Definition: sh2.c:920
char * r_name
Definition: sh2.c:921
int r_val
Definition: sh2.c:922
Definition: sh.h:1345
int type
Definition: sh.h:1347
Definition: dvips.h:235
Definition: sh.h:1559