home *** CD-ROM | disk | FTP | other *** search
- /* MS-DOS SHELL - Function Processing
- *
- * MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited
- *
- * This code is subject to the following copyright restrictions:
- *
- * 1. Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice is duplicated in the
- * source form and the copyright notice in file sh6.c is displayed
- * on entry to the program.
- *
- * 2. The sources (or parts thereof) or objects generated from the sources
- * (or parts of sources) cannot be sold under any circumstances.
- *
- * $Header: C:/SRC/SHELL/RCS/sh10.c 1.5 90/09/11 19:40:46 Ian_Stewartson Exp $
- *
- * $Log: sh10.c $
- * Revision 1.5 90/09/11 19:40:46 Ian_Stewartson
- * Fix bug in case printing/deletion in functions
- *
- * Revision 1.4 90/08/14 23:33:32 MS_user
- * Fix memory bugs - Add Copy function code to code a function tree
- * before it is executed.
- *
- * Revision 1.3 90/05/31 09:51:06 MS_user
- * Add some signal lockouts to prevent corruption
- *
- * Revision 1.2 90/04/25 22:34:04 MS_user
- * Fix case in TELIF where then and else parts are not defined
- *
- * Revision 1.1 90/01/25 13:40:54 MS_user
- * Initial revision
- *
- */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <process.h>
- #include <dos.h>
- #include <signal.h>
- #include <errno.h>
- #include <setjmp.h>
- #include <ctype.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <dirent.h>
- #include "sh.h"
-
-
- /* Function declarations */
-
- static void Print_Command (C_Op *);
- static void Print_IO (IO_Actions *);
- static void Print_Case (C_Op *);
- static void Print_IString (char *, int);
- static void Set_Free_ExTree (C_Op *, void (*)(char *));
- static void Set_Free_Command (C_Op *, void (*)(char *));
- static void Set_Free_Case (C_Op *, void (*)(char *));
- static C_Op *Copy_ExTree (C_Op *);
- static void Copy_Command (C_Op *, C_Op *);
- static C_Op *Copy_Case (C_Op *);
- static void Set_ExTree (char *);
- static void Free_ExTree (char *);
- static void *field_dup (void *, size_t);
-
- static int Print_indent; /* Current indent level */
-
- /*
- * print the execute tree - used for displaying functions
- */
-
- void Print_ExTree (t)
- register C_Op *t;
- {
- char **wp;
-
- if (t == (C_Op *)NULL)
- return;
-
- /* Check for start of print */
-
- if (t->type == TFUNC)
- {
- Print_indent = 0;
- v1_puts (*t->words);
- v1a_puts (" ()");
- Print_ExTree (t->left);
- return;
- }
-
- /* Otherwise, process the tree and print it */
-
- switch (t->type)
- {
- case TPAREN: /* () */
- case TCOM: /* A command process */
- Print_Command (t);
- return;
-
- case TPIPE: /* Pipe processing */
- Print_ExTree (t->left);
- Print_IString ("|\n", 0);
- Print_ExTree (t->right);
- return;
-
- case TLIST: /* Entries in a for statement */
- Print_ExTree (t->left);
- Print_ExTree (t->right);
- return;
-
- case TOR: /* || and && */
- case TAND:
- Print_ExTree (t->left);
-
- if (t->right != (C_Op *)NULL)
- {
- Print_IString ((t->type == TAND) ? "&&\n" : "||\n", 0);
- Print_ExTree (t->right);
- }
-
- return;
-
- case TFOR: /* First part of a for statement*/
- Print_IString ("for ", 0);
- v1_puts (t->str);
-
- if ((wp = t->words) != (char **)NULL)
- {
- v1_puts (" in");
-
- while (*wp != (char *)NULL)
- {
- v1_putc (SP);
- v1_puts (*wp++);
- }
- }
-
- v1_putc (NL);
- Print_IString ("do\n", 1);
- Print_ExTree (t->left);
- Print_IString ("done\n", -1);
- return;
-
- case TWHILE: /* WHILE and UNTIL functions */
- case TUNTIL:
- Print_IString ((t->type == TWHILE) ? "while " : "until ", 1);
- Print_ExTree (t->left);
- Print_IString ("do\n", 0);
- Print_ExTree (t->right);
- Print_IString ("done\n", -1);
- return;
-
- case TIF: /* IF and ELSE IF functions */
- case TELIF:
- if (t->type == TIF)
- Print_IString ("if\n", 1);
-
- else
- Print_IString ("elif\n", 1);
-
- Print_ExTree (t->left);
-
- if (t->right != (C_Op *)NULL)
- {
- Print_indent -= 1;
- Print_IString ("then\n", 1);
- Print_ExTree (t->right->left);
-
- if (t->right->right != (C_Op *)NULL)
- {
- Print_indent -= 1;
-
- if (t->right->right->type != TELIF)
- Print_IString ("else\n", 1);
-
- Print_ExTree (t->right->right);
- }
- }
-
- if (t->type == TIF)
- Print_IString ("fi\n", -1);
-
- return;
-
- case TCASE: /* CASE function */
- Print_IString ("case ", 1);
- v1_puts (t->str);
- v1a_puts (" in");
- Print_Case (t->left);
- Print_IString (" esac\n", -1);
- return;
-
- case TBRACE: /* {} statement */
- Print_IString ("{\n", 1);
- if (t->left != (C_Op *)NULL)
- Print_ExTree (t->left);
-
- Print_IString ("}\n", -1);
- return;
- }
- }
-
- /*
- * Print a command line
- */
-
- static void Print_Command (t)
- register C_Op *t;
- {
- char *cp;
- IO_Actions **iopp;
- char **wp = t->words;
- char **owp = wp;
-
- if (t->type == TCOM)
- {
- while ((cp = *wp++) != (char *)NULL)
- ;
-
- cp = *wp;
-
- /* strip all initial assignments not correct wrt PATH=yyy command etc */
-
- if ((cp == (char *)NULL) && (t->ioact == (IO_Actions **)NULL))
- {
- Print_IString (null, 0);
-
- while (*owp != (char *)NULL)
- v1a_puts (*(owp++));
-
- return;
- }
- }
-
- /* Parenthesis ? */
-
- if (t->type == TPAREN)
- {
- Print_IString ("(\n", 1);
- Print_ExTree (t->left);
- Print_IString (")", -1);
- }
-
- else
- {
- Print_IString (null, 0);
-
- while (*owp != (char *)NULL)
- {
- v1_puts (*owp++);
-
- if (*owp != (char *)NULL)
- v1_putc (SP);
- }
- }
-
- /* Set up anyother IO required */
-
- if ((iopp = t->ioact) != (IO_Actions **)NULL)
- {
- while (*iopp != (IO_Actions *)NULL)
- Print_IO (*iopp++);
- }
-
- v1_putc (NL);
- }
-
- /*
- * Print the IO re-direction
- */
-
- static void Print_IO (iop)
- register IO_Actions *iop;
- {
- int unit = iop->io_unit;
- static char *cunit = " x";
-
- if (unit == IODEFAULT) /* take default */
- unit = (iop->io_flag & (IOREAD | IOHERE)) ? STDIN_FILENO
- : STDOUT_FILENO;
-
- /* Output unit number */
-
- cunit[1] = (char)(unit + '0');
- v1_puts (cunit);
-
- switch (iop->io_flag)
- {
- case IOHERE:
- case IOHERE | IOXHERE:
- v1_putc ('<');
-
- case IOREAD:
- v1_putc ('<');
- break;
-
- case IOWRITE | IOCAT:
- v1_putc ('>');
-
- case IOWRITE:
- v1_putc ('>');
- break;
-
- case IODUP:
- v1_puts (">&");
- v1_putc (*iop->io_name);
- return;
- }
-
- v1_puts (iop->io_name);
- }
-
- /*
- * Print out the contents of a case statement
- */
-
- static void Print_Case (t)
- C_Op *t;
- {
- register C_Op *t1;
- register char **wp;
-
- if (t == (C_Op *)NULL)
- return;
-
- /* type - TLIST - go down the left tree first and then processes this level */
-
- if (t->type == TLIST)
- {
- Print_Case (t->left);
- t1 = t->right;
- }
-
- else
- t1 = t;
-
- /* Output the conditions */
-
- Print_IString (null, 0);
-
- for (wp = t1->words; *wp != (char *)NULL;)
- {
- v1_puts (*(wp++));
-
- if (*wp != (char *)NULL)
- v1_puts (" | ");
- }
-
- v1a_puts (" )");
- Print_indent += 1;
-
- /* Output the commands */
-
- Print_ExTree (t1->left);
- Print_IString (";;\n", -1);
- }
-
- /*
- * Print an indented string
- */
-
- static void Print_IString (cp, indent)
- char *cp;
- int indent;
- {
- int i;
-
- if (indent < 0)
- Print_indent += indent;
-
- for (i = 0; i < (Print_indent / 2); i++)
- v1_putc ('\t');
-
- if (Print_indent % 2)
- v1_puts (" ");
-
- v1_puts (cp);
-
- if (indent > 0)
- Print_indent += indent;
- }
-
- /*
- * Look up a function in the save tree
- */
-
- Fun_Ops *Fun_Search (name)
- char *name;
- {
- Fun_Ops *fp;
-
- for (fp = fun_list; fp != (Fun_Ops *)NULL; fp = fp->next)
- {
- if (strcmp (*(fp->tree->words), name) == 0)
- return fp;
- }
-
- return (Fun_Ops *)NULL;
- }
-
- /*
- * Save or delete a function tree
- */
-
- void Save_Function (t, delete_only)
- C_Op *t;
- bool delete_only; /* True - delete */
- {
- char *name = *t->words;
- register Fun_Ops *fp = Fun_Search (name);
- Fun_Ops *p_fp = (Fun_Ops *)NULL;
- void (*save_signal)(int);
-
- /* Find the entry */
-
- for (fp = fun_list; (fp != (Fun_Ops *)NULL) &&
- (strcmp (*(fp->tree->words), name) != 0);
- p_fp = fp, fp = fp->next);
-
- /* Disable signals */
-
- save_signal = signal (SIGINT, SIG_IGN);
-
- /* If it already exists, free the tree and delete the entry */
-
- if (fp != (Fun_Ops *)NULL)
- {
- Set_Free_ExTree (fp->tree, Free_ExTree);
-
- if (p_fp == (Fun_Ops *)NULL)
- fun_list = fp->next;
-
- else
- p_fp->next = fp->next;
-
- DELETE (fp);
- }
-
- /* Restore signals */
-
- signal (SIGINT, save_signal);
-
- /* If delete only - exit */
-
- if (delete_only)
- return;
-
- /* Create new entry */
-
- if ((fp = (Fun_Ops *)space (sizeof (Fun_Ops))) == (Fun_Ops *)NULL)
- return;
-
- /* Disable signals */
-
- save_signal = signal (SIGINT, SIG_IGN);
-
- /* Set up the tree */
-
- setarea ((char *)fp, 0);
- Set_Free_ExTree (t, Set_ExTree);
-
- fp->tree = t;
- fp->next = fun_list;
- fun_list = fp;
-
- /* Restore signals */
-
- signal (SIGINT, save_signal);
- }
-
- /*
- * Set ExTree areas to zero function
- */
-
- static void Set_ExTree (s)
- char *s;
- {
- setarea (s, 0);
- }
-
- /*
- * Free the ExTree function
- */
-
- static void Free_ExTree (s)
- char *s;
- {
- DELETE (s);
- }
-
- /*
- * Set/Free function tree area by recursively processing of tree
- */
-
- static void Set_Free_ExTree (t, func)
- C_Op *t;
- void (*func)(char *);
- {
- char **wp;
-
- if (t == (C_Op *)NULL)
- return;
-
- /* Check for start of print */
-
- if (t->type == TFUNC)
- {
- (*func)(*t->words);
- (*func)((char *)t->words);
- Set_Free_ExTree (t->left, func);
- }
-
- /* Otherwise, process the tree and print it */
-
- switch (t->type)
- {
- case TPAREN: /* () */
- case TCOM: /* A command process */
- Set_Free_Command (t, func);
- break;
-
- case TPIPE: /* Pipe processing */
- case TLIST: /* Entries in a for statement */
- case TOR: /* || and && */
- case TAND:
- case TWHILE: /* WHILE and UNTIL functions */
- case TUNTIL:
- Set_Free_ExTree (t->left, func);
- Set_Free_ExTree (t->right, func);
- break;
-
- case TFOR: /* First part of a for statement*/
- (*func)(t->str);
-
- if ((wp = t->words) != (char **)NULL)
- {
- while (*wp != (char *)NULL)
- (*func) (*wp++);
-
- (*func)((char *)t->words);
- }
-
- Set_Free_ExTree (t->left, func);
- break;
-
- case TIF: /* IF and ELSE IF functions */
- case TELIF:
- if (t->right != (C_Op *)NULL)
- {
- Set_Free_ExTree (t->right->left, func);
- Set_Free_ExTree (t->right->right, func);
- (*func)((char *)t->right);
- }
-
- case TBRACE: /* {} statement */
- Set_Free_ExTree (t->left, func);
- break;
-
- case TCASE: /* CASE function */
- (*func)(t->str);
- Set_Free_Case (t->left, func);
- break;
- }
-
- (*func)((char *)t);
- }
-
- /*
- * Set/Free a command line
- */
-
- static void Set_Free_Command (t, func)
- C_Op *t;
- void (*func)(char *);
- {
- IO_Actions **iopp;
- char **wp = t->words;
-
- /* Parenthesis ? */
-
- if (t->type == TPAREN)
- Set_Free_ExTree (t->left, func);
-
- else
- {
- while (*wp != (char *)NULL)
- (*func)(*wp++);
-
- (*func) ((char *)t->words);
- }
-
- /* Process up any IO required */
-
- if ((iopp = t->ioact) != (IO_Actions **)NULL)
- {
- while (*iopp != (IO_Actions *)NULL)
- {
- (*func)((char *)(*iopp)->io_name);
- (*func)((char *)*iopp);
- iopp++;
- }
-
- (*func)((char *)t->ioact);
- }
- }
-
- /*
- * Set/Free the contents of a case statement
- */
-
- static void Set_Free_Case (t, func)
- C_Op *t;
- void (*func)(char *);
- {
- register C_Op *t1;
- register char **wp;
-
- if (t == (C_Op *)NULL)
- return;
-
- /* type - TLIST - go down the left tree first and then processes this level */
-
- if (t->type == TLIST)
- {
- Set_Free_Case (t->left, func);
- (*func)((char *)t->left);
- t1 = t->right;
- }
-
- else
- t1 = t;
-
- /* Set/Free the conditions */
-
- for (wp = t1->words; *wp != (char *)NULL;)
- (*func)(*(wp++));
-
- (*func)((char *)t1->words);
-
- Set_Free_ExTree (t1->left, func);
-
- if (t1 == t->right)
- (*func)((char *)t->right);
- }
-
- /*
- * Copy function tree area by recursively processing of tree
- */
-
- static C_Op *Copy_ExTree (Old_t)
- C_Op *Old_t;
- {
- char **wp;
- C_Op *New_t;
- Word_B *wb = (Word_B *)NULL;
-
- if (Old_t == (C_Op *)NULL)
- return (C_Op *)NULL;
-
- New_t = (C_Op *) field_dup (Old_t, sizeof (C_Op));
-
- /* Check for start of print */
-
- if (Old_t->type == TFUNC)
- {
- New_t->words = (char **)getcell (sizeof (char *) * 2);
- *New_t->words = strsave (*Old_t->words, areanum);
- New_t->left = Copy_ExTree (Old_t->left);
- }
-
- /* Otherwise, process the tree and print it */
-
- switch (Old_t->type)
- {
- case TPAREN: /* () */
- case TCOM: /* A command process */
- Copy_Command (Old_t, New_t);
- break;
-
- case TPIPE: /* Pipe processing */
- case TLIST: /* Entries in a for statement */
- case TOR: /* || and && */
- case TAND:
- case TWHILE: /* WHILE and UNTIL functions */
- case TUNTIL:
- New_t->left = Copy_ExTree (Old_t->left);
- New_t->right = Copy_ExTree (Old_t->right);
- break;
-
- case TFOR: /* First part of a for statement*/
- New_t->str = strsave (Old_t->str, areanum);
-
- if ((wp = Old_t->words) != (char **)NULL)
- {
- while (*wp != (char *)NULL)
- wb = addword (strsave (*(wp++), areanum), wb);
-
- New_t->words = getwords (addword ((char *)NULL, wb));
- }
-
- New_t->left = Copy_ExTree (Old_t->left);
- break;
-
- case TIF: /* IF and ELSE IF functions */
- case TELIF:
- if (Old_t->right != (C_Op *)NULL)
- {
- New_t->right = (C_Op *)field_dup (Old_t->right, sizeof (C_Op));
- New_t->right->left = Copy_ExTree (Old_t->right->left);
- New_t->right->right = Copy_ExTree (Old_t->right->right);
- }
-
- case TBRACE: /* {} statement */
- New_t->left = Copy_ExTree (Old_t->left);
- break;
-
- case TCASE: /* CASE function */
- New_t->str = strsave (Old_t->str, areanum);
- New_t->left = Copy_Case (Old_t->left);
- break;
- }
-
- return New_t;
- }
-
- /*
- * Copy a command line
- */
-
- static void Copy_Command (Old_t, New_t)
- C_Op *Old_t, *New_t;
- {
- IO_Actions **iopp;
- char **wp = Old_t->words;
- Word_B *wb = (Word_B *)NULL;
- IO_Actions *iop;
-
- /* Parenthesis ? */
-
- if (Old_t->type == TPAREN)
- New_t->left = Copy_ExTree (Old_t->left);
-
- else
- {
- while (*wp != (char *)NULL)
- wb = addword (strsave (*(wp++), areanum), wb);
-
- New_t->words = getwords (addword ((char *)NULL, wb));
- }
-
- /* Process up any IO required */
-
- if ((iopp = Old_t->ioact) != (IO_Actions **)NULL)
- {
- wb = (Word_B *)NULL;
-
- while (*iopp != (IO_Actions *)NULL)
- {
- iop = (IO_Actions *)field_dup (*iopp, sizeof (IO_Actions));
- iop->io_name = strsave ((*iopp)->io_name, areanum);
- wb = addword ((char *)iop, wb);
- ++iopp;
- }
-
- New_t->ioact = (IO_Actions **)getwords (addword ((char *)NULL, wb));
- }
- }
-
- /*
- * Copy the contents of a case statement
- */
-
- static C_Op *Copy_Case (Old_t)
- C_Op *Old_t;
- {
- register C_Op *Old_t1, *New_t, *New_t1;
- register char **wp;
- Word_B *wb = (Word_B *)NULL;
-
- if (Old_t == (C_Op *)NULL)
- return (C_Op *)NULL;
-
- /* type - TLIST - go down the left tree first and then processes this level */
-
- New_t = (C_Op *)field_dup (Old_t, sizeof (C_Op));
-
- if (Old_t->type == TLIST)
- {
- New_t->left = Copy_Case (Old_t->left);
- New_t->right = (C_Op *)field_dup (Old_t->right, sizeof (C_Op));
- Old_t1 = Old_t->right;
- New_t1 = New_t->right;
- }
-
- else
- {
- New_t1 = New_t;
- Old_t1 = Old_t;
- }
-
- /* Duplicate the word block */
-
- wp = Old_t1->words;
-
- while (*wp != (char *)NULL)
- wb = addword (strsave (*(wp++), areanum), wb);
-
- New_t1->words = getwords (addword ((char *)NULL, wb));
- New_t1->left = Copy_ExTree (Old_t1->left);
- return New_t;
- }
-
-
- /*
- * Duplicate a field
- */
-
- static void *field_dup (source, size)
- void *source;
- size_t size;
- {
- return memcpy (space (size), source, size);
- }
-
- /* Duplicate the tree */
-
- C_Op *Copy_Function (Old_t)
- C_Op *Old_t;
- {
- int *save_errpt;
- jmp_buf new_errpt;
- C_Op *New_t = (C_Op *)NULL;
-
- /* Set up for error handling - like out of space */
-
- save_errpt = e.errpt;
-
- if (setjmp (new_errpt) == 0)
- New_t = Copy_ExTree (Old_t);
-
- e.errpt = save_errpt;
- return New_t;
- }
-