From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 14:25:34.58
To:	galaxy::gleeve
CC:	
Subj:	FGREP.06_OF_06

-+-+-+-+-+-+-+-+ START OF PART 6 -+-+-+-+-+-+-+-+
X      ** that it's not to be considered as such.
X      */
X      if (*++place_p == '-')
X      `7B
X        new_argv`5Bi_new++`5D = arg_p;
X        if ((arg_p = (*argv_p)`5B++i_old`5D) == NULL)
X            goto BREAKOUT;
X        else`09`09`09`09`09/* V1.2-005 */
X            new_argv`5Bi_new++`5D = arg_p;`09`09/* V1.2-005 */
X      `7D
X      else
X      `7B
X        /* The string after the option is an input filespec, so we glob it.
X        ** But we glob it to return only the first match (if it's a wildcard
V),
X        ** not all possible matches.
X        */
X        if (*(arg_p + 2) == '\0')
X        `7B
X          new_argv = xrealloc(new_argv,(++new_argv_count * sizeof (char *)))
V;
X          new_argv`5Bi_new++`5D = arg_p;
X          if ((arg_p = (*argv_p)`5B++i_old`5D) == NULL)
X           goto BREAKOUT;
X
X          filespec_v = shell_glob(arg_p,NULL);
X          new_argv`5Bi_new++`5D = *filespec_v;
X          free(filespec_v);
X        `7D
X        else
X        `7B
X          filespec_v = shell_glob((arg_p + 2),NULL);
X          new_argv`5Bi_new`5D = xmalloc(2 + strlen(*filespec_v) + 1);
X          memcpy(new_argv`5Bi_new`5D,arg_p,2);
X          strcpy((new_argv`5Bi_new++`5D + 2),*filespec_v);
X          free(*filespec_v);
X          free(filespec_v);
X        `7D
X      `7D
X    `7D
X    break;
X
X    /* If we get here, the argument is a parameter.  If we're not concerned
X    ** about parameters (that is, if `60parameter_number' is zero or less),
V or
X    ** if the parameter count is less than `60parameter_number', we simply c
Vopy
X    ** the parameter into the new argument vector.  Otherwise, the parameter
X    ** and those following it are expected to be filespecs, and an attempt i
Vs
X    ** made to parse them as such and put all resulting filespecs into the
X    ** argument vector.
X    */
X    default:
X    if ((parameter_number <= 0) `7C`7C (++parameter_count < parameter_number
V))
X     new_argv`5Bi_new++`5D = arg_p;
X    else
X    `7B
X      filespec_v = shell_glob(arg_p,&filespec_count);
X      if (filespec_count == 1)
X       new_argv`5Bi_new++`5D = *filespec_v;
X      else
X      `7B
X        new_argv_count += filespec_count - 1;
X        new_argv = xrealloc(new_argv,(new_argv_count * sizeof (char *)));
X        memcpy(&new_argv`5Bi_new`5D,filespec_v,(filespec_count * sizeof (cha
Vr *)));
X        i_new += filespec_count;
X      `7D
X      free(filespec_v);
X    `7D
X    break;
X
X  `7D /* for/switch */
X
XBREAKOUT:
X
X  new_argv`5Bi_new`5D = NULL;
X
X  /* --- UPDATE ARGUMENT COUNT AND ARGUMENT VECTOR --- */
X
X  *argc_p = i_new;
X  *argv_p = new_argv;
X
X  return i_new - i_old;
X
X`7D /* shell_mung() */
X
X/* -=- STATIC FUNCTION -=- */
X
X/* truncate_argv_0
X**--------------------------------------------------------------------------
V---
X** Functional Description
X** `7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E
X**  Programs written in VAX C, when run under VMS DCL, will have their entir
Ve
X** filespec (i.e., the filespec of the running image) in the main() function
V's
X** `60argv`5B0`5D' variable.  While this makes sense from a VMS standpoint,
V it does
X** not look very good in programs ported from GNU, which often use `60argv`5
VB0`5D' as
X** an error message prefix.
X**  This function, which is called from shell_mung(), truncates the filespec
V in
X** `60argv`5B0`5D' to just the filename or, if the filetype is not ".EXE", t
Vo the
X** filename and filetype.
X**--------------------------------------------------------------------------
V---
X** Calling Sequence
X** `7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E
X** new_argv`5B0`5D = truncate_argv_0(given_filespec);
X**--------------------------------------------------------------------------
V---
X** Formal Argument      Description
X** `7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E      `7E`7E`7E`7E`7E`7E`7E`
V7E`7E`7E`7E
X** given_filespec       The filespec to be truncated.  Assumed to be `60argv
V`5B0`5D'
X**                      or a pointer to the same thing `60argv`5B0`5D' point
Vs to.
X**--------------------------------------------------------------------------
V---
X** Implicit Inputs:     None
X**--------------------------------------------------------------------------
V---
X** Implicit Outputs:    None
X**--------------------------------------------------------------------------
V---
X** Return Value
X** `7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E
X**  Returns the truncated filespec, which is in newly-allocated memory.
X**--------------------------------------------------------------------------
V---
X** Side Effects
X** `7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E`7E
X**  Memory is allocated for the truncated filespec.
X**--------------------------------------------------------------------------
V---
X*/
Xstatic char *
Xtruncate_argv_0(given_filespec)
X char *  given_filespec;
X`7B
X  /* --- LOCAL VARIABLES --- */
X
X  register char *  character_p;         /* General-purpose character pointer
V,
X                                        ** used to lowercase filespec.
X                                        */
X  char  * expanded_filespec;`09`09/* v1.2-004 */
X                                        /* Buffer to hold the expanded files
Vpec
X                                        ** from a call to sys$parse().
X                                        */
X  register char *  filespec_p;          /* Pointer to truncated filespec to
V be
X                                        ** returned.
X                                        */
X  struct FAB  fab = cc$rms_fab;         /* RMS file access block for file.
X                                        */
X  struct NAM  nam = cc$rms_nam;         /* RMS name block for file.
X                                        */
X
X  /* --- INITIALIZE FABS AND NAMS --- */
X
X  expanded_filespec = xmalloc(NAM$C_MAXRSS + 1);`09/* v1.2-004 */
X  fab.fab$l_fna = given_filespec;
X  fab.fab$b_fns = strlen(given_filespec);
X  fab.fab$l_nam = &nam;
X  nam.nam$l_esa = expanded_filespec;`09`09`09/* v1.2-004 */
X  nam.nam$b_ess = NAM$C_MAXRSS;
X  nam.nam$b_nop = NAM$M_SYNCHK;
X
X  /* --- PARSE OUT THE GIVEN FILESPEC --- */
X
X  sys$parse(&fab);
X
X  /* --- NUL-TERMINATE AND LOWERCASE FILESPEC --- */
X
X  *nam.nam$l_ver = '\0';
X
X  for (character_p = nam.nam$l_esa; *character_p; ++character_p)
X   *character_p = _tolower(*character_p);`09/* v1.2-004 */
X
X  /* --- RETURN TRUNCATED FILESPEC --- */
X
X  if (strcmp(nam.nam$l_type,".exe"))
X   filespec_p = xmalloc(nam.nam$b_name + nam.nam$b_type + 1);
X  else
X  `7B
X    *nam.nam$l_type = '\0';
X    filespec_p = xmalloc(nam.nam$b_name + 1);
X  `7D
X
X  strcpy(filespec_p,nam.nam$l_name);
X  return filespec_p;
X
X`7D /* truncate_argv_0() */
$ CALL UNPACK [.FGREP011]SHELL_MUNG.C;1 593217989
$ create 'f'
X/* std.c - compensate for a few missing library functions.
X   In the Public Domain; written by Mike Haertel. */
X
X#include "std.h"
X#include "unix.h"
X
X#ifdef X_memmove
XPTR
XDEFUN(memmove, (d, s, n), PTR d AND PTRCONST s AND size_t n)
X`7B
X  char *dd;
X  const char *ss;
X
X  dd = d;
X  ss = s;
X  if (dd > ss && dd < ss + n)
X    `7B
X      dd += n;
X      ss += n;
X      while (n--)
X`09*--dd = *--ss;
X    `7D
X  else
X    while (n--)
X      *dd++ = *ss++;
X  return d;
X`7D
X#endif /* X_memmove */
X
X#ifdef X_remove
X#if defined(unix) `7C`7C defined(__unix__)
Xint
XDEFUN(remove, (filename), const char *filename)
X`7B
X  extern int EXFUN(unlink, (const char *));
X
X  return unlink(filename);
X`7D
X#endif /* unix */
X#endif /* X_strerror */
X
X#ifdef X_strerror
X#if defined(unix) `7C`7C defined(__unix__)
Xchar *
XDEFUN(strerror, (errnum), int errnum)
X`7B
X  extern int sys_nerr;
X  extern char *sys_errlist`5B`5D;
X
X  if (errnum > 0 && errnum < sys_nerr)
X    return sys_errlist`5Berrnum`5D;
X  return "";
X`7D
X#endif /* unix */
X#endif /* X_strerror */
$ CALL UNPACK [.FGREP011]STD.C;1 527923263
$ create 'f'
X/* std.h - automagically adapt to old and new compilers.
X   In the Public Domain; written by Mike Haertel. */
X
X#if defined(__STDC__) `7C`7C defined(VAXC)
X
X#include <stddef.h>
X#include <limits.h>
X
Xtypedef void *PTR;
Xtypedef const void *PTRCONST;
X
X#define AND ,
X#define DEFUN(F, L, P) F(P)
X#define EXFUN(F, P) F P
X
X#else
X
X#define const
X#define volatile
X
X/* The following approximations of <stddef.h> and <limits.h> are appropriate
X   for most machines. */
Xtypedef int ptrdiff_t;
Xtypedef unsigned int size_t;
X#ifndef NULL
X#define NULL 0
X#endif
X#define offsetof(T, M) ((size_t)&((T *) 0)->(M))
X
X#define CHAR_BIT 8
X#define SCHAR_MIN -128
X#define SCHAR_MAX 127
X#define UCHAR_MAX 255
X#define CHAR_MIN ((char) UCHAR_MAX < 0 ? SCHAR_MIN : 0)
X#define CHAR_MAX ((char) UCHAR_MAX < 0 ? SCHAR_MAX : UCHAR_MAX)
X#define SHRT_MIN -32768
X#define SHRT_MAX 32767
X#define USHRT_MAX 65535
X#define INT_MIN (sizeof (int) == 2 ? -32768 : -2147483648)
X#define INT_MAX (sizeof (int) == 2 ? 32767 : 2147483647)
X#define UINT_MAX (sizeof (int) == 2 ? 65535 : 4294967295)
X#define LONG_MIN -2147483648L
X#define LONG_MAX 2147483647L
X#define ULONG_MAX 4294967295
X
Xtypedef char *PTR;
Xtypedef const char *PTRCONST;
X
X#define AND ;
X#define DEFUN(F, L, P) F L P ;
X#define EXFUN(F, P) F()
X
X#endif
X
X/* Deal with <ctype.h> lossage. */
X#include <ctype.h>
X
X#ifndef isascii
X
X#define ISALNUM(C) isalnum(C)
X#define ISALPHA(C) isalpha(C)
X#define ISCNTRL(C) iscntrl(C)
X#define ISDIGIT(C) isdigit(C)
X#define ISGRAPH(C) isgraph(C)
X#define ISLOWER(C) islower(C)
X#define ISPRINT(C) isprint(C)
X#define ISPUNCT(C) ispunct(C)
X#define ISSPACE(C) isspace(C)
X#define ISUPPER(C) isupper(C)
X#define ISXDIGIT(C) isxdigit(C)
X#define TOLOWER(C) tolower(C)
X#define TOUPPER(C) toupper(C)
X
X#else
X
X#define ISALNUM(C) (isascii(C) && isalnum(C))
X#define ISALPHA(C) (isascii(C) && isalpha(C))
X#define ISCNTRL(C) (isascii(C) && iscntrl(C))
X#define ISDIGIT(C) (isascii(C) && isdigit(C))
X#define ISGRAPH(C) (isascii(C) && isgraph(C))
X#define ISLOWER(C) (isascii(C) && islower(C))
X#define ISPRINT(C) (isascii(C) && isprint(C))
X#define ISPUNCT(C) (isascii(C) && ispunct(C))
X#define ISSPACE(C) (isascii(C) && isspace(C))
X#define ISUPPER(C) (isascii(C) && isupper(C))
X#define ISXDIGIT(C) (isascii(C) && isxdigit(C))
X#define TOLOWER(C) (ISUPPER(C) ? tolower(C) : (C))
X#define TOUPPER(C) (ISLOWER(C) ? toupper(C) : (C))
X
X#endif
X
X/* Declaring this here should be safe.  Some losing <errno.h>'s don't. */
X#ifndef VAXC
Xextern int errno;
X#endif
X
X/* Adapt variable arguments to new implementations (with <stdarg.h>)
X   or old (which are assumed to have <varargs.h>). */
X
X#if __STDC__
X
X#include <stdarg.h>
X
X#define VA_ALIST ...
X#define VA_DCL ...
X#define VA_LIST va_list
X#define VA_START(AP, LASTARG) va_start(AP, LASTARG)
X#define VA_ARG(AP, TYPE) va_arg(AP, TYPE)
X#define VA_END(AP) va_end(AP)
X
X#define VA_DEFUN(F, L, P) F(P)
X
X#else
X
X#include <varargs.h>
X
X#define VA_ALIST va_alist
X#define VA_DCL va_dcl
X#define VA_LIST va_list
X#define VA_START(AP, LASTARG) va_start(AP)
X#define VA_ARG(AP, TYPE) va_arg(AP, TYPE)
X#define VA_END(AP) va_end(AP)
X
X#define VA_DEFUN(F, L, P) F L P
X
X#endif
X
X/* Declarations of traditional library routines. */
Xextern double EXFUN(atof, (const char *));
Xextern int EXFUN(atoi, (const char *));
Xextern long int EXFUN(atol, (const char *));
Xextern int EXFUN(rand, (void));
Xextern void EXFUN(srand, (int));
Xextern PTR EXFUN(calloc, (size_t, size_t));
Xextern void EXFUN(free, (PTR));
Xextern PTR EXFUN(malloc, (size_t));
Xextern PTR EXFUN(realloc, (PTR, size_t));
Xextern void EXFUN(abort, (void));
Xextern void EXFUN(exit, (int));
Xextern char *EXFUN(getenv, (const char *));
Xextern int EXFUN(system, (const char *));
Xextern void EXFUN(qsort, (PTR, size_t, size_t,
X`09`09`09  int EXFUN((*), (PTRCONST, PTRCONST))));
Xextern int EXFUN(abs, (int));
Xextern long int EXFUN(labs, (long int));
X
X#ifdef X_strerror
Xextern char *EXFUN(strerror, (int));
X#endif
$ CALL UNPACK [.FGREP011]STD.H;1 791435419
$ create 'f'
X/* unix.h - prototype UNIX system calls and a few library routines.
X   In the Public Domain; written by Mike Haertel. */
X
X#ifdef VAXC
X#include <types.h>
X#include <stat.h>
X#else
X#define size_t unix_size_t
X#include <sys/types.h>
X#undef size_t
X#include <sys/stat.h>
X#endif
X#ifndef VMS
X#include <sys/dir.h>
X#endif
X
X/* Optionally get the directory routines.  The Makefile needs to
X   define which version. */
X#ifdef DIRENT
X#include <dirent.h>
X#else
X#ifdef SYSDIR
X#include <sys/dir.h>
X#else
X#ifdef NDIR
X#include <ndir.h>
X#endif /* NDIR */
X#endif /* SYSDIR */
X#endif /* DIRENT */
X
X/* Prototype certain UNIX system calls. */
Xextern int EXFUN(access, (const char *, int));
Xextern unsigned int EXFUN(alarm, (unsigned int));
Xextern PTR EXFUN(sbrk, (size_t));
Xextern int EXFUN(chdir, (const char *));
Xextern int EXFUN(chmod, (const char *, int));
Xextern int EXFUN(chown, (const char *, int, int));
Xextern int EXFUN(close, (int));
Xextern int EXFUN(creat, (const char *, int));
Xextern int EXFUN(dup, (int));
Xextern int EXFUN(execl, (const char *, ...));
Xextern int EXFUN(execv, (const char *, char **));
Xextern int EXFUN(execle, (const char *, ...));
Xextern int EXFUN(execve, (const char *, char **, char **));
Xextern int EXFUN(execlp, (const char *, ...));
Xextern int EXFUN(execvp, (const char *, char **));
Xextern void EXFUN(_exit, (int));
Xextern int EXFUN(fcntl, (int, int, int));
Xextern int EXFUN(fork, (void));
Xextern int EXFUN(getpid, (void));
Xextern int EXFUN(getppid, (void));
Xextern int EXFUN(ioctl, (int, int, PTR));
Xextern int EXFUN(kill, (int, int));
Xextern int EXFUN(link, (const char *, const char *));
Xextern long int EXFUN(lseek, (int, long int, int));
Xextern int EXFUN(open, (const char *, int, ...));
Xextern void EXFUN(pause, (void));
Xextern int EXFUN(pipe, (int *));
Xextern int EXFUN(read, (int, char *, size_t));
Xextern int EXFUN(stat, (const char *, struct stat *));
Xextern int EXFUN(fstat, (int, struct stat *));
Xextern int EXFUN(umask, (int));
Xextern int EXFUN(unlink, (const char *));
Xextern int EXFUN(wait, (int *));
Xextern int EXFUN(write, (int, const char *, size_t));
X
X/* Prototype certain UNIX library routines. */
Xextern char *EXFUN(crypt, (const char *, const char *));
Xextern int EXFUN(getopt, (int, char **, const char *));
Xextern char EXFUN(getpass, (const char *));
Xextern unsigned int EXFUN(sleep, (unsigned int));
Xextern int EXFUN(isatty, (int));
Xextern const char *EXFUN(ttyname, (int));
Xextern int EXFUN(tgetent, (char *, const char *));
Xextern int EXFUN(tgetnum, (const char *));
Xextern int EXFUN(tgetflag, (const char *));
Xextern char *EXFUN(tgetstr, (const char *, char **));
Xextern char *EXFUN(tgoto, (const char *, int, int));
Xextern int EXFUN(tputs, (const char *, int, int EXFUN((*), (int))));
Xextern char *EXFUN(tparam, (const char *, char *, size_t, ...));
X
X/* Declare a few UNIX-specific external objects. */
Xextern char PC, *BC, *UP;
Xextern short int ospeed;
Xextern char *optarg;
Xextern int optind;
$ CALL UNPACK [.FGREP011]UNIX.H;1 138697552
$ create 'f'
X$!
X$!  DCL Command procedure to build GNU fgrep
X$!
X$!  To compile with VAX C, define CC = "CC"
X$!  To compile with GNU C, define CC = "GCC"
X$!
X$ CC = "CC"
X$! CC = "GCC"
X$ say := write sys$output
X$ say "Compiling fgrep...."
X$ 'CC' FGREP
X$ say "Compiling GETOPT...."
X$ 'CC' GETOPT
X$ say "Compiling KWSET...."
X$ 'CC' KWSET
X$ say "Compiling OBSTACK...."
X$ 'CC' OBSTACK
X$ say "Compiling ALLOCA...."
X$ 'CC' ALLOCA
X$ say "Compiling XALLOC...."
X$ 'CC' XALLOC
X$ say "Compiling SHELL_MUNG...."
X$ 'CC' SHELL_MUNG
X$ say "Compiling STD...."
X$ 'CC' STD
X$ say "Linking fgrep...."
X$ if cc.eqs."CC"
X$ then`09LINK/NOTRACE FGREP,GETOPT,SHELL_MUNG,OBSTACK,STD,KWSET,XALLOC,ALLOC
VA,-
X`09sys$input/options
X`09sys$share:vaxcrtl.exe/share
X$ else`09LINK/NOTRACE FGREP,GETOPT,SHELL_MUNG,OBSTACK,STD,KWSET,ALLOCA,XALLO
VC,-
X`09GNU_CC:`5B000000`5DOPTIONS/OPT
X$ endif
X$ say "Generating GREP on-line help file...."
X$ runoff grep.rnh
X$ say "Build of fgrep completed"
X$ exit
$ CALL UNPACK [.FGREP011]VMSMAKE.COM;1 1780444820
$ create 'f'
X/* xalloc and xrealloc (malloc and realloc that exit on error)
X   Copyright 1985 Free Software Foundation
X
X   This program is free software; you can redistribute it and/or modify
X   it under the terms of the GNU General Public License as published by
X   the Free Software Foundation; either version 1, or (at your option)
X   any later version.
X
X   This program is distributed in the hope that it will be useful,
X   but WITHOUT ANY WARRANTY; without even the implied warranty of
X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X   GNU General Public License for more details.
X
X   You should have received a copy of the GNU General Public License
X   along with this program; if not, write to the Free Software
X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
X
X/* Borrowed from GNU Emacs by Hunter Goatley, goathunter@WKUVX1.BITNET */
X
X/* Called if malloc returns zero */
Xmemory_full ()
X`7B
X  perror ("Memory exhausted");
X`7D
X
X/* like malloc and realloc but check for no memory left */
X
Xlong *
Xxmalloc (size)
X     int size;
X`7B
X  register long *val = (long *) malloc (size);
X  if (!val) memory_full ();
X  return val;
X`7D
X
Xlong *
Xxrealloc (block, size)
X     long *block;
X     int size;
X`7B
X  register long *val = (long *) realloc (block, size);
X  if (!val) memory_full ();
X  return val;
X`7D
$ CALL UNPACK [.FGREP011]XALLOC.C;1 238963600
$ v=f$verify(v)
$ EXIT
