Yet Another Shell (part 6 of 11)

Dave Clemans dclemans.falcon at mntgfx.mentor.com
Thu Mar 16 08:24:23 AEST 1989


With all the talk about shells that has been going on recently...

Here's an early pre-release of a "Korn"-like shell for anyone
who might want to experiment.  It is definitely NOT complete,
but it starting to be usable.  It does use some GNU code (for
expression evaluation), so it presumably comes under their
"copyleft".

It basically runs on BSD/USG Unix systems, and on the Atari ST.
I'm currently working on a port to the Amiga.

dgc

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 11)."
# Contents:  cmd3.c
# Wrapped by dclemans at dclemans on Wed Mar 15 14:03:57 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'cmd3.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cmd3.c'\"
else
echo shar: Extracting \"'cmd3.c'\" \(24304 characters\)
sed "s/^X//" >'cmd3.c' <<'END_OF_FILE'
X/*
X * Command Input Shell
X * Dave Clemans
X * 12/88-1/89
X *
X * "spiritually" based on Bourne, Korn shells
X *
X * Built-in Commands (part 3)
X *
X * $Id: cmd3.c,v 1.8 89/02/25 17:40:00 dclemans Exp $
X *
X * $Log:	cmd3.c,v $
X * Revision 1.8  89/02/25  17:40:00  dclemans
X * miscellaneous bug fixes/speedups
X * 
X * Revision 1.7  89/02/22  16:27:08  dclemans
X * Implement [[, ]] brackets
X * 
X * Revision 1.6  89/02/22  08:16:43  dclemans
X * implement left-justified, right-justified, etc. parameter attributes
X * 
X * Revision 1.5  89/02/20  20:14:22  dclemans
X * Add RCS identifiers
X * 
X */
X#include <stdio.h>
X#include "shell.h"
X
X#ifdef  GEMDOS
X#include <types.h>
X#include <stat.h>
X#ifdef  MWC
X#include <basepage.h>
X#endif  /* MWC */
X#else
X#include <sys/types.h>
X#include <sys/stat.h>
X#endif  /* GEMDOS */
X
Xstatic int test_parse(tp)
Xstruct token *tp;
X{
X    register char *s1,*s2,*arg;
X    int n1,n2;
X    int rc;
X    struct stat statb;
X    long date1;
X
X    if (tp == (struct token *)NULL)
X        return 0;
X    if (strcmp(tp->name,"]") == 0)
X        return 0;
X    if (strcmp(tp->name,"]]") == 0)
X        return 0;
X    if (strcmp(tp->name,"!") == 0)
X        return test_parse(tp->next);
X    if (strcmp(tp->name,"(") == 0)
X        return !test_parse(tp->next);
X    if (strcmp(tp->name,")") == 0)
X        tp = tp->next;
X    rc = 0;
X
X    arg = tp->name;
X    s1 = (char *)NULL;
X    tp = tp->next;
X    if (tp != (struct token *)NULL)
X    {   /* get file */
X        s1 = tp->name;
X        tp = tp->next;
X    }
X    if (arg != (char *)NULL)
X        stripquotes(arg);
X    if (s1 != (char *)NULL)
X        stripquotes(s1);
X    if (strcmp(arg,"-b") == 0)
X    {   /* a block file? */
X#ifdef  GEMDOS
X        if (s1 == (char *)NULL)
X            rc = 1;
X        else
X        {   /* is it a drive name? */
X            if (islower(*s1))
X                *s1 = _toupper(*s1);
X            if (strcmp(&s1[1],":") == 0 && *s1 >= 'A' && *s1 <= 'P')
X                rc = 0;
X            else    rc = 1;
X        }
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if ((statb.st_mode & S_IFMT) == S_IFBLK)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-c") == 0)
X    {   /* a character file? */
X#ifdef  GEMDOS
X        if (s1 == (char *)NULL)
X            rc = 1;
X        else
X        {   /* check for char device names */
X            for (s2 = s1; *s2; s2++)
X                if (islower(*s2))
X                    *s2 = _toupper(*s2);
X            if (strcmp(s1,"CON:") == 0 ||
X                strcmp(s1,"TTY:") == 0 ||
X                strcmp(s1,"AUX:") == 0 ||
X                strcmp(s1,"PRN:") == 0 ||
X                strcmp(s1,"PRT:") == 0)
X                rc = 0;
X            else    rc = 1;
X        }
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if ((statb.st_mode & S_IFMT) == S_IFCHR)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-d") == 0)
X    {   /* is a directory? */
X        if (s1 == (char *)NULL || stat(s1,&statb) < 0)
X            rc = 1;
X        else
X        {   /* check the modes */
X#ifdef  GEMDOS
X            if (statb.st_mode & S_IJDIR)
X                rc = 0;
X            else    rc = 1;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if ((statb.st_mode & S_IFMT) == S_IFDIR)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X        }
X    }
X    else if (strcmp(arg,"-f") == 0)
X    {   /* is a regular file? */
X        if (s1 == (char *)NULL || stat(s1,&statb) < 0)
X            rc = 1;
X        else
X        {   /* check the modes */
X#ifdef  GEMDOS
X            if (statb.st_mode & S_IJVOL)
X                rc = 1;
X            else    rc = 0;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if ((statb.st_mode & S_IFMT) == S_IFREG)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X        }
X    }
X    else if (strcmp(arg,"-g") == 0)
X    {   /* setgid set? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if (statb.st_mode & S_ISGID)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-k") == 0)
X    {   /* sticky set? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if (statb.st_mode & S_ISVTX)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-l") == 0)
X    {   /* is a link? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X#ifndef USG
X            if ((statb.st_mode & S_IFMT) == S_IFLNK)
X                rc = 0;
X            else rc = 1;
X#else
X            rc = -1;
X#endif  /* USG */
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-n") == 0)
X    {   /* is string length zero? */
X        if (s1 == (char *)NULL || strlen(s1) == 0)
X            rc = 0;
X        else    rc = 1;
X    }
X    else if (strcmp(arg,"-p") == 0)
X    {   /* is a pipe? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = -1;
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-r") == 0)
X    {   /* is readable? */
X        if (s1 == (char *)NULL)
X            rc = 1;
X        else rc = !isread(s1);
X    }
X    else if (strcmp(arg,"-t") == 0)
X    {   /* is a terminal? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = !isatty(base_env.io->input);
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-u") == 0)
X    {   /* setuid set? */
X#ifdef  GEMDOS
X        rc = -1;
X#else
X        rc = stat(s1,&statb);
X        if (rc >= 0)
X        {   /* if something to look at */
X            if (statb.st_mode & S_ISUID)
X                rc = 0;
X            else rc = 1;
X        }
X#endif  /* GEMDOS */
X    }
X    else if (strcmp(arg,"-w") == 0)
X    {   /* is writable? */
X        if (s1 == (char *)NULL || stat(s1,&statb) < 0)
X            rc = 1;
X        else
X        {   /* check the modes */
X#ifdef  GEMDOS
X            if (statb.st_mode & S_IJRON)
X                rc = 1;
X            else    rc = 0;
X#else
X            rc = -1;
X#endif  /* GEMDOS */
X        }
X    }
X    else if (strcmp(arg,"-x") == 0)
X    {   /* is executable? */
X        if (s1 == (char *)NULL)
X            rc = 1;
X        else rc = !isexec(s1);
X    }
X
X    s2 = s1;
X    s1 = arg;
X    arg = s2;
X    if (tp != (struct token *)NULL)
X        s2 = tp->name;
X    else    s2 = (char *)NULL;
X    if (s2 != (char *)NULL)
X        stripquotes(s2);
X    if (s1 != (char *)NULL)
X        n1 = atoi(s1);
X    else    n1 = -1;
X    if (s2 != (char *)NULL)
X        n2 = atoi(s2);
X    else    n2 = -1;
X    if (tp != (struct token *)NULL)
X    {   /* if possible dyadic? */
X        if (strcmp(arg,"=") == 0)
X        {   /* equivalent strings? */
X            rc = strcmp(s1,s2);             
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"!=") == 0)
X        {   /* not equivalent strings */
X            rc = !strcmp(s1,s2);
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-eq") == 0)
X        {   /* equal numbers? */
X            if (n1 == n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-gt") == 0)
X        {   /* greater than? */
X            if (n1 > n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-ge") == 0)
X        {   /* greater than or equal to? */
X            if (n1 >= n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-lt") == 0)
X        {   /* less than? */
X            if (n1 < n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-le") == 0)
X        {   /* less than or equal to? */
X            if (n1 <= n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-ne") == 0)
X        {   /* not equal to? */
X            if (n1 != n2)
X                rc = 0;
X            else    rc = 1;
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-nt") == 0)
X        {   /* file newer? */
X            if (stat(s1,&statb) < 0)
X                date1 = -1;
X            else    date1 = statb.st_mtime;
X            if (stat(s2,&statb) < 0)
X                rc = 1;
X            else
X            {   /* check dates */
X                if (date1 > statb.st_mtime)
X                    rc = 0;
X                else    rc = 1;
X            }
X            tp = tp->next;
X        }
X        else if (strcmp(arg,"-ot") == 0)
X        {   /* file older? */
X            if (stat(s1,&statb) < 0)
X                date1 = -1;
X            else    date1 = statb.st_mtime;
X            if (stat(s2,&statb) < 0)
X                rc = 1;
X            else
X            {   /* check dates */
X                if (date1 < statb.st_mtime)
X                    rc = 0;
X                else    rc = 1;
X            }
X            tp = tp->next;
X        }
X    }
X
X    if (s1 != (char *)NULL && arg == (char *)NULL && s2 == (char *)NULL)
X    {   /* just a single string? */
X        if (strlen(s1) != 0)
X            rc = 0;
X        else    rc = 1;
X    }
X
X    if (tp != (struct token *)NULL)
X    {   /* check for continued expressions? */
X        if (strcmp(tp->name,"-a") == 0)
X        {   /* anded exprs? */
X            if (rc != 0)
X                return rc;
X            return test_parse(tp->next);
X        }
X        else if (strcmp(tp->name,"-o") == 0)
X        {   /* ored exprs? */
X            if (rc == 0)
X                return rc;
X            return test_parse(tp->next);
X        }
X        else if (strcmp(tp->name,"]") == 0)
X            return rc;
X        else if (strcmp(tp->name,"]]") == 0)
X            return rc;
X    }
X
X    if (tp != (struct token *)NULL)
X        errmsg(0,LOC("test_parse"),"expression syntax error at token %s",tp->name);
X    return rc;
X}   /* end of test_parse */
X
Xint cmd_test(pp)
Xstruct phrase *pp;
X{
X    return test_parse(pp->body->next);
X}   /* end of cmd_test */
X
Xint cmd_version()
X{
X    char buffer[BUFSIZ];
X#ifdef  GEMDOS
X    unsigned version;
X    long oldssp;
X    int *sysbase;
X    int romvers;
X#endif  /* GEMDOS */
X
X    strcpy(buffer,shell_version);
X    strcat(buffer,"\n");
X    io_writestring(0,buffer);
X#ifdef  LINED
X    sprintf(buffer,"    emacs & vi line editing code installed.\n");
X    io_writestring(0,buffer);
X#endif  /* LINED */
X#ifdef  GEMDOS
X    sprintf(buffer,"    compiled for Atari ST systems.\n");
X    io_writestring(0,buffer);
X#endif  /* GEMDOS */
X#ifdef  unix
X#ifndef USG
X    sprintf(buffer,"    compiled for BSD systems.\n");
X#else
X    sprintf(buffer,"    compiled for SYSV systems.\n");
X#endif  /* USG */
X    io_writestring(0,buffer);
X#endif  /* unix */
X
X#ifdef  GEMDOS
X    oldssp = Super(0L);
X    sysbase = *(int **)0x4f2;
X    romvers = *(sysbase+1);
X    Super(oldssp);
X    version = Sversion();
X    sprintf(buffer,"    running on Atari ST; TOS %d.%d; GEM %d.%d\n",(romvers >> 8) & 0xFF,romvers & 0xFF,version & 0xFF,(version >> 8) & 0xFF);
X    io_writestring(0,buffer);
X    sprintf(buffer,"\nAuthor:\n");
X    io_writestring(0,buffer);
X    sprintf(buffer,"    Dave Clemans\n");
X    io_writestring(0,buffer);
X    sprintf(buffer,"    c/o ST Enthusiasts Of Portland\n");
X    io_writestring(0,buffer);
X    sprintf(buffer,"    4470 SW Hall Blvd., Suite 325\n");
X    io_writestring(0,buffer);
X    sprintf(buffer,"    Beaverton, OR 97005\n");
X    io_writestring(0,buffer);
X#endif  /* GEMDOS */
X
X    return 0;
X}   /* end of cmd_version */
X
Xstatic char *kbytes(value)
Xlong value;
X{
X    static char buf[16];
X    register long first;
X    register int last;
X
X    first = value / 1024L;
X    last = ((int)((value % 1024L) * 10)) / 1024;
X    sprintf(buf,"%ld.%dK",first,last);
X    return buf;
X}   /* end of kbytes */
X
X#ifdef  MYMALLOC
Xint cmd_memory()
X{
X    char buffer[BUFSIZ];
X    register char *p;
X    extern long poolSize,mallocTotal,mallocHighWater;
X    long memblock;
X
X#ifdef  GEMDOS
X#ifdef  MWC
X    long totalMemory;
X    extern long _stksize;
X    int percent;
X
X    sprintf(buffer,"%s: text base,length=0x%lx,%s bytes\n",var_arg0,
X        BP->p_tbase,kbytes(BP->p_tlen));
X    totalMemory = BP->p_tlen;
X    io_writestring(0,buffer);
X    sprintf(buffer,"    data base,length=0x%lx,%s bytes\n",
X        BP->p_dbase,kbytes(BP->p_dlen));
X    totalMemory += BP->p_dlen;
X    io_writestring(0,buffer);
X    sprintf(buffer,"    bss base,length=0x%lx,%s bytes\n",
X        BP->p_bbase,kbytes(BP->p_blen));
X    totalMemory += BP->p_blen;
X    io_writestring(0,buffer);
X    p = (char *)_stksize;
X    for (p = p+1; *p == '\0' && p < (char *)(_stksize+DEFSTACK); p++)
X        /* do nothing */;
X    percent = (int)(((DEFSTACK-(long)((long)p-_stksize))*100L)/DEFSTACK);
X    sprintf(buffer,"  Stack: %s bytes; estimated max usage=%d%%\n",kbytes(DEFSTACK),percent);
X    io_writestring(0,buffer);
X    percent = (int)(((DEFSTACK-(long)((long)buffer-_stksize))*100L)/DEFSTACK);
X    sprintf(buffer,"         estimated current usage=%d%%\n",percent);
X    totalMemory += DEFSTACK;
X    io_writestring(0,buffer);
X#else
X    sprintf(buffer,"%s:\n",var_arg0);
X    io_writestring(0,buffer);
X#endif  /* MWC */
X#else
X    sprintf(buffer,"%s:\n",var_arg0);
X    io_writestring(0,buffer);
X#endif  /* GEMDOS */
X
X    sprintf(buffer,"  Dynamic memory: pool=%s bytes, allocated=%ld bytes\n",
X        kbytes(poolSize),mallocTotal);
X    io_writestring(0,buffer);
X    sprintf(buffer,"                  max allocated=%ld bytes\n",mallocHighWater);
X    io_writestring(0,buffer);
X#ifdef  GEMDOS
X#ifdef  MWC
X    totalMemory += poolSize;
X    sprintf(buffer,"  Total memory used: %s bytes\n",kbytes(totalMemory));
X    io_writestring(0,buffer);
X#endif  /* MWC */
X    memblock = Malloc(-1L);
X    sprintf(buffer,"\n  Largest free memory block in system: %s\n",kbytes(memblock));
X    io_writestring(0,buffer);
X#endif  /* GEMDOS */
X
X    return 0;
X}   /* end of cmd_memory */
X#endif  /* MYMALLOC */
X
Xvoid func_dump(fp,flag)
Xregister struct function *fp;
Xregister int flag;
X{
X    if (fp == (struct function *)NULL)
X        return;
X    if (fp->left != (struct function *)NULL)
X        func_dump(fp->left,flag);
X    phrase_dump(fp->code,flag,0);
X    if (fp->right != (struct function *)NULL)
X        func_dump(fp->right,flag);
X}   /* end of func_dump */
X
Xint cmd_typeset(pp)
Xstruct phrase *pp;
X{
X    register char *p;
X    char *cp;
X    int type,mask,misc,functions;
X    register struct token *tp;
X    char buffer[BUFSIZ];
X
X    functions = type = 0;
X    mask = ~0;
X    misc = 0;
X    tp = pp->body->next;
X    if (tp != (struct token *)NULL)
X        stripquotes(tp->name);
X    if (tp != (struct token *)NULL && (tp->name[0] == '-' || tp->name[0] == '+'))
X    {   /* pick up options */
X        for (p = &tp->name[1]; *p; p++)
X        {   /* what options? */
X            switch (*p)
X            {   /* select which one */
X                case 'f':
X                    if (tp->name[0] == '-')
X                        functions = 1;
X                    else functions = 2;
X                    break;
X                case 'r':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_READONLY;
X                    else mask &= ~TYPE_READONLY;
X                    break;
X                case 'x':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_EXPORTED;
X                    else mask &= ~TYPE_EXPORTED;
X                    break;
X                case 'i':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_INTEGER;
X                    else mask &= ~TYPE_INTEGER;
X                    break;
X                case 'u':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_UPPERCASE;
X                    else mask &= ~TYPE_UPPERCASE;
X                    break;
X                case 'l':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_LOWERCASE;
X                    else mask &= ~TYPE_LOWERCASE;
X                    break;
X                case 't':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_TAGGED;
X                    else mask &= ~TYPE_TAGGED;
X                    break;
X                case 'R':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_RIGHTJUST;
X                    else mask &= ~TYPE_RIGHTJUST;
X                    if (p[1] == 'Z')
X                    {   /* add in zero stuff? */
X                        cp = &p[2];
X                        if (tp->name[0] == '-')
X                            type |= TYPE_ZEROS;
X                        else mask &= ~TYPE_ZEROS;
X                    }
X                    else cp = &p[1];
X                    misc = atoi(cp);
X                    p = (char *)NULL;
X                    mask &= ~TYPE_LEFTJUST;
X                    break;
X                case 'L':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_LEFTJUST;
X                    else mask &= ~TYPE_LEFTJUST;
X                    if (p[1] == 'Z')
X                    {   /* add in zero stuff? */
X                        cp = &p[2];
X                        if (tp->name[0] == '-')
X                            type |= TYPE_ZEROS;
X                        else mask &= ~TYPE_ZEROS;
X                    }
X                    else cp = &p[1];
X                    misc = atoi(cp);
X                    p = (char *)NULL;
X                    mask &= ~TYPE_RIGHTJUST;
X                    break;
X                case 'Z':
X                    if (tp->name[0] == '-')
X                        type |= (TYPE_RIGHTJUST|TYPE_ZEROS);
X                    else mask &= ~(TYPE_RIGHTJUST|TYPE_ZEROS);
X                    misc = atoi(&p[1]);
X                    p = (char *)NULL;
X                    mask &= ~TYPE_LEFTJUST;
X                    break;
X                case 'H':
X                    if (tp->name[0] == '-')
X                        type |= TYPE_HOSTMAP;
X                    else mask &= ~TYPE_HOSTMAP;
X                    break;
X                default:
X                    errmsg(0,LOC("cmd_typeset"),"unknown typeset option in: %s",tp->name);
X                    return 1;
X            }
X            if (p == (char *)NULL)
X                break;
X        }
X        tp = tp->next;		/* skip past options */
X    }
X    if (tp == (struct token *)NULL)
X    {   /* just dump out definitions */
X        if (functions)
X            func_dump(base_env.func_table,functions == 1);
X        else
X        {   /* dump all or part of variable table */
X            if (mask == ~0)
X                var_dump(type,1);
X            else var_dump(~mask,0);
X        }
X        return 0;
X    }
X    for (; tp != (struct token *)NULL; tp = tp->next)
X    {   /* for the rest of the args */
X        stripquotes(tp->name);
X        p = strchr(tp->name,'=');
X        if (p != (char *)NULL)
X        {   /* set type and value? */
X            strncpy(buffer,tp->name,(int)(p-tp->name));
X            buffer[(int)(p-tp->name)] = '\0';
X        }
X        else strcpy(buffer,tp->name);
X        if (p != (char *)NULL)
X            var_define0(buffer,&p[1],1);
X        var_setmisc(buffer,misc);
X        var_settype(buffer,type,mask);
X    }
X    return 0;
X}   /* end of cmd_typeset */
X
Xint cmd_let(pp)
Xstruct phrase *pp;
X{
X    int result;
X    register struct token *tp;
X
X    result = 0;
X    for (tp = pp->body->next; tp != (struct token *)NULL; tp = tp->next)
X    {   /* eval each argument */
X        stripquotes(tp->name);
X        result = parse_c_expression(tp->name,1);
X    }
X    if (result != 0)
X        return 0;
X    else return 1;
X}   /* end of cmd_let */
X
Xint cmd_dparen(pp)
Xstruct phrase *pp;
X{
X    register struct token *tp;
X    int length,result;
X    char *expression;
X
X    length = 0;
X    for (tp = pp->body->next; tp != (struct token *)NULL; tp = tp->next)
X    {   /* get length of args */
X        stripquotes(tp->name);
X        length += strlen(tp->name);
X        if (tp->next != (struct token *)NULL)
X            length++;
X    }
X    expression = new_string(length+1);
X    if (expression == (char *)NULL)
X    {   /* enough memory? */
X        errmsg(SHERR_NOMEM,LOC("cmd_dparen"));
X        return 1;
X    }
X    expression[0] = '\0';
X    for (tp = pp->body->next; tp != (struct token *)NULL; tp = tp->next)
X    {   /* get length of args */
X        if (tp->type == SYM_DRPAREN)
X            continue;
X        strcat(expression,tp->name);
X    }
X    result = parse_c_expression(expression,1);
X    free(expression);
X    if (result != 0)
X        return 0;
X    return 1;
X}   /* end of cmd_dparen */
X
Xint cmd_whence(pp)
Xstruct phrase *pp;
X{
X    register struct token *tp,*ftp;
X    int verbose;
X    struct aliases *ap;
X    char *ptr;
X    char buffer[BUFSIZ];
X
X    verbose = 0;
X    tp = pp->body->next;
X    if (tp != (struct token *)NULL && strcmp(tp->name,"-v") == 0)
X    {   /* verbose flag set? */
X        verbose = 1;
X        tp = tp->next;
X    }
X    for (; tp != (struct token *)NULL; tp = tp->next)
X    {   /* for each arg */
X        stripquotes(tp->name);
X        if (verbose)
X        {   /* check reserved words, etc. */
X            buffer[0] = '\0';
X            if (reserved_word(tp->name))
X            {   /* is it this? */
X                sprintf(buffer,"%s is a reserved word",tp->name);
X            }
X            else if ((ap = alias_get(tp->name)) != (struct aliases *)NULL)
X            {   /* is it this? */
X                if (ap->type & TYPE_TRACKED)
X                    sprintf(buffer,"%s is a tracked alias for ",tp->name);
X                else sprintf(buffer,"%s is an alias for ",tp->name);
X                for (ftp = ap->tp; ftp != (struct token *)NULL; ftp = ftp->next)
X                {   /* dump each token */
X                    strcat(buffer,ftp->name);
X                    if (ftp->next != (struct token *)NULL)
X                        strcat(buffer," ");
X                }
X            }
X            else if (func_get(tp->name) != (struct function *)NULL)
X            {   /* is it this? */
X                sprintf(buffer,"%s is a shell function",tp->name);
X            }
X            else if (builtin_word(tp->name))
X            {   /* is it this? */
X                sprintf(buffer,"%s is a shell built-in",tp->name);
X            }
X            if (buffer[0] != '\0')
X            {   /* generated a message? */
X                io_writestring(0,buffer);
X                io_writestring(0,"\n");
X                continue;
X            }
X        }
X        if ((ap = alias_get(tp->name)) != (struct aliases *)NULL)
X        {   /* if alias or tracked alias */
X            if (ap->type & TYPE_TRACKED)
X            {   /* give full name of tracked alias */
X                buffer[0] = '\0';
X                for (ftp = ap->tp; ftp != (struct token *)NULL; ftp = ftp->next)
X                {   /* dump each token */
X                    strcat(buffer,ftp->name);
X                    if (ftp->next != (struct token *)NULL)
X                        strcat(buffer," ");
X                }
X                io_writestring(0,buffer);
X            }
X            else io_writestring(0,tp->name);
X        }
X        else if (reserved_word(tp->name) ||
X            func_get(tp->name) != (struct function *)NULL ||
X            builtin_word(tp->name))
X        {   /* is it this? */
X            io_writestring(0,tp->name);
X        }
X        else
X        {   /* normal path search for program */
X            ptr = exec_pathsearch(tp->name);
X            if (ptr == (char *)NULL)
X            {   /* not there */
X                if (!verbose)
X                    sprintf(buffer,"%s",tp->name);
X                else sprintf(buffer,"%s not found",tp->name);
X            }
X            else
X            {   /* actually found the program */
X                if (!verbose)
X                    sprintf(buffer,"%s",ptr);
X		else sprintf(buffer,"%s is %s",tp->name,ptr);
X                free(ptr);
X            }
X            io_writestring(0,buffer);
X        }
X        io_writestring(0,"\n");
X    }
X
X    return 0;
X}   /* end of cmd_whence */
END_OF_FILE
if test 24304 -ne `wc -c <'cmd3.c'`; then
    echo shar: \"'cmd3.c'\" unpacked with wrong size!
fi
# end of 'cmd3.c'
fi
echo shar: End of archive 6 \(of 11\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Alt.sources mailing list