[comp.sys.ibm.pc] GNU e?grep patches for MSDOS

chasm@killer.DALLAS.TX.US (Charles Marslett) (02/19/89)

#	The following two files are: one to patch the GNU e?grep utility
#	source files so as to compile with Microsoft C (and probably
#	Turbo C) for use under MSDOS.  The routine "wild.c" distributed
#	by Microsoft is also used to expand wild card file name references
#	in the command line.  A bug fix for that routine is also included
#	int this diff file to use it in the compact memory model, and a
#	second bug (handling quoted arguments) is also corrected.  (Even
#	Microsoft isn't perfect. ;^)
#
#	The second file is a modified Makefile to generate e?grep in the
#	compact memory model.  Two changes in the syntax of the command
#	line have been made as concessions to MSDOS (no real pipes and
#	no file linking).  One is the new flag -E (to effect egrep syntax)
#	and the other is controlled with the new flag -u (by default, the
#	printed lines, etc., are written following a header line with the
#	file name, rather than concatenated with the file name in normal
#	e?grep fashion -- "-u" restores the normal mode).  The blocked
#	report can be disabled by undefining -DBLOCKS if desired.  Undefining
#	-DMSC_WILD will eliminate the need for the Microsoft C compiler
#	routine "wild.c" (and an alternative file name expansion technique
#	should be substituted).
#
#	I am also submitting the executable result of these patches to
#	comp.binaries.ibm.pc.
#
#					Thank you,
#					Charles Marslett
#
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:   Shell Archiver
#	Run the following text with /bin/sh to create:
#	diffs
#	makefile.msc
# This archive created: Sat Feb 18 12:23:54 1989
sed 's/^X//' << \SHAR_EOF > diffs
X*** README
X--- NEW/README
X***************
X*** 77,82 ****
X  	-w		print only lines where the match is a complete word
X  	-x		print only lines where the match is a whole line
X  
X  The options understood by GNU e?grep are meant to be (nearly) compatible
X  with both the BSD and System V versions of grep and egrep.
X  
X--- 77,85 ----
X  	-w		print only lines where the match is a complete word
X  	-x		print only lines where the match is a whole line
X  
X+ 	-E		behave as if the command were "egrep"
X+ 	-u		unblock the output (if blocked output is enabled)
X+ 
X  The options understood by GNU e?grep are meant to be (nearly) compatible
X  with both the BSD and System V versions of grep and egrep.
X  
X***************
X*** 85,90 ****
X  	-b prints a byte offset instead of a block offset
X  	the \{m,n\} construct of System V grep is not implemented
X  
X  GNU e?grep has been thoroughly debugged and tested by several people
X  over a period of several months; we think it's a reliable beast or we
X  wouldn't distribute it.  If by some fluke of the universe you discover
X--- 88,99 ----
X  	-b prints a byte offset instead of a block offset
X  	the \{m,n\} construct of System V grep is not implemented
X  
X+ In addition, if GNU e?grep is compiled with -DBLOCKS, any filenames
X+ printed are printed on a seperate lines, double spaced from the previous
X+ matched lines.  This can be overridden by the -u command line option.
X+ Also, if compiled with -DMSDOS, the command name is ignored and "egrep"
X+ is specified by means of the command line option -E.
X+ 
X  GNU e?grep has been thoroughly debugged and tested by several people
X  over a period of several months; we think it's a reliable beast or we
X  wouldn't distribute it.  If by some fluke of the universe you discover
X***************
X*** 119,124 ****
X  
X  	Paul Placeway wrote the manual page, based on this README.
X  
X  If you are interested in improving this program, you may wish to try
X  any of the following:
X  
X--- 128,136 ----
X  
X  	Paul Placeway wrote the manual page, based on this README.
X  
X+ 	Charles Marslett made the very minor changes to permit use of
X+ 	this program in an MSDOS environment.
X+ 
X  If you are interested in improving this program, you may wish to try
X  any of the following:
X  
X*** GETOPT.C
X--- NEW/GETOPT.C
X**************
X*** 110,115
X  
X  #include <stdio.h>
X  
X  #ifdef sparc
X  #include <alloca.h>
X  #endif
X--- 110,123 -----
X  
X  #include <stdio.h>
X  
X+ #ifndef __GNUC__
X+ #include <stdlib.h>
X+ #endif
X+ 
X+ #ifdef MSDOS
X+ char *alloca(int);
X+ #endif
X+ 
X  #ifdef sparc
X  #include <alloca.h>
X  #endif
X**************
X*** 114,119
X  #include <alloca.h>
X  #endif
X  #ifdef USG
X  #define bcopy(s, d, l) memcpy((d), (s), (l))
X  #endif
X  
X--- 122,129 -----
X  #include <alloca.h>
X  #endif
X  #ifdef USG
X+ #include <string.h>
X+ #define index strchr
X  #define bcopy(s, d, l) memcpy((d), (s), (l))
X  #endif
X  
X*** DFA.H
X--- NEW/DFA.H
X**************
X*** 105,112
X  
X  #ifdef __STDC__
X  
X! /* Missing include files for GNU C. */
X! /* #include <stdlib.h> */
X  typedef int size_t;
X  extern void *calloc(int, size_t);
X  extern void *malloc(size_t);
X--- 105,112 -----
X  
X  #ifdef __STDC__
X  
X! #ifdef __GNUC__
X! /* Missing include files for GNU C. Missing define for NULL*/
X  typedef int size_t;
X  extern void *calloc(int, size_t);
X  extern void *malloc(size_t);
X**************
X*** 113,118
X  extern void *realloc(void *, size_t);
X  extern void free(void *);
X  
X  #ifndef USG
X  extern char *strchr(), *strrchr(), *memcpy();
X  #else
X--- 113,127 -----
X  extern void *realloc(void *, size_t);
X  extern void free(void *);
X  
X+ #define NULL 0
X+ 
X+ #else
X+ #include <stdlib.h>
X+ #ifndef NULL
X+ #define NULL 0
X+ #endif
X+ #endif
X+ 
X  #ifndef USG
X  extern char *strchr(), *strrchr(), *memcpy();
X  #else
X**************
X*** 186,194
X  #define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
X  #define RE_SYNTAX_EMACS 0
X  
X- /* The NULL pointer. */
X- #define NULL 0
X- 
X  /* Number of bits in an unsigned char. */
X  #define CHARBITS 8
X  
X--- 195,200 -----
X  #define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
X  #define RE_SYNTAX_EMACS 0
X  
X  /* Number of bits in an unsigned char. */
X  #define CHARBITS 8
X  
X**************
X*** 380,386
X     a constraint. */
X  typedef struct
X  {
X!   unsigned index:24,		/* Index into the parse array. */
X  	   constraint:8;	/* Constraint for matching this position. */
X  } _position;
X  
X--- 386,392 -----
X     a constraint. */
X  typedef struct
X  {
X!   unsigned long index:24,	/* Index into the parse array. */
X  	   constraint:8;	/* Constraint for matching this position. */
X  } _position;
X  
X*** GREP.C
X--- NEW/GREP.C
X**************
X*** 125,132
X  extern char *strrchr();
X  #endif
X  
X! extern char *optarg;
X! extern optind, opterr;
X  extern errno;
X  extern char *sys_errlist[];
X  
X--- 125,131 -----
X  extern char *strrchr();
X  #endif
X  
X! #ifdef __GNUC__
X  extern errno;
X  extern char *sys_errlist[];
X  #endif
X**************
X*** 129,134
X  extern optind, opterr;
X  extern errno;
X  extern char *sys_errlist[];
X  
X  #define MAX(a, b) ((a) > (b) ? (a) : (b))
X  
X--- 128,134 -----
X  #ifdef __GNUC__
X  extern errno;
X  extern char *sys_errlist[];
X+ #endif
X  
X  extern char *optarg;
X  extern optind, opterr;
X**************
X*** 130,136
X  extern errno;
X  extern char *sys_errlist[];
X  
X! #define MAX(a, b) ((a) > (b) ? (a) : (b))
X  
X  /* Exit status codes. */
X  #define MATCHES_FOUND 0		/* Exit 0 if no errors and matches found. */
X--- 130,137 -----
X  extern char *sys_errlist[];
X  #endif
X  
X! extern char *optarg;
X! extern optind, opterr;
X  
X  #define MAX(a, b) ((a) > (b) ? (a) : (b))
X  
X**************
X*** 132,137
X  
X  #define MAX(a, b) ((a) > (b) ? (a) : (b))
X  
X  /* Exit status codes. */
X  #define MATCHES_FOUND 0		/* Exit 0 if no errors and matches found. */
X  #define NO_MATCHES_FOUND 1	/* Exit 1 if no matches were found. */
X--- 133,140 -----
X  extern char *optarg;
X  extern optind, opterr;
X  
X+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
X+ 
X  /* Exit status codes. */
X  #define MATCHES_FOUND 0		/* Exit 0 if no errors and matches found. */
X  #define NO_MATCHES_FOUND 1	/* Exit 1 if no matches were found. */
X**************
X*** 537,542
X  usage_and_die()
X  {
X    fprintf(stderr,
X  "usage: %s [-CVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X            prog);
X    exit(ERROR);
X--- 540,548 -----
X  usage_and_die()
X  {
X    fprintf(stderr,
X+ #ifdef MSDOS
X+ "usage: %s [-ECVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X+ #else
X  "usage: %s [-CVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X  #endif
X            prog);
X**************
X*** 538,543
X  {
X    fprintf(stderr,
X  "usage: %s [-CVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X            prog);
X    exit(ERROR);
X  }
X--- 544,550 -----
X  "usage: %s [-ECVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X  #else
X  "usage: %s [-CVbchilnsvwx] [-<num>] [-AB <num>] [-f file] [-e] expr [files]\n",
X+ #endif
X            prog);
X    exit(ERROR);
X  }
X**************
X*** 562,567
X    char *regex_errmesg;		/* Error message from regex routines. */
X    char translate[_NOTCHAR];	/* Translate table for case conversion
X  				   (needed by the backtracking matcher). */
X  
X    if (prog = strrchr(argv[0], '/'))
X      ++prog;
X--- 569,577 -----
X    char *regex_errmesg;		/* Error message from regex routines. */
X    char translate[_NOTCHAR];	/* Translate table for case conversion
X  				   (needed by the backtracking matcher). */
X+ #ifdef MSDOS
X+   char *cp;
X+   char egrep_flag;
X  
X  #ifdef MSC_WILD
X    extern int __argc;
X**************
X*** 563,568
X    char translate[_NOTCHAR];	/* Translate table for case conversion
X  				   (needed by the backtracking matcher). */
X  
X    if (prog = strrchr(argv[0], '/'))
X      ++prog;
X    else
X--- 573,589 -----
X    char *cp;
X    char egrep_flag;
X  
X+ #ifdef MSC_WILD
X+   extern int __argc;
X+   extern char **__argv;
X+ 
X+   if (_cwild()) {
X+     printf("Unable to expand file names: check command line!\n");
X+     exit (1);
X+     }
X+   argv = __argv;
X+   argc = __argc;
X+ #endif
X    if (prog = strrchr(argv[0], '/'))
X      ++prog;
X    else
X**************
X*** 567,572
X      ++prog;
X    else
X      prog = argv[0];
X  
X    opterr = 0;
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X--- 588,605 -----
X      ++prog;
X    else
X      prog = argv[0];
X+   if (cp = strrchr(prog, '\\')) {
X+     prog = cp;
X+     ++prog;
X+     }
X+   if (cp = strrchr(prog, '.'))
X+     *cp = 0;
X+ #else
X+   if (prog = strrchr(argv[0], '/'))
X+     ++prog;
X+   else
X+     prog = argv[0];
X+ #endif
X  
X    opterr = 0;
X  #ifdef MSDOS
X**************
X*** 569,574
X      prog = argv[0];
X  
X    opterr = 0;
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X      switch (c)
X        {
X--- 602,611 -----
X  #endif
X  
X    opterr = 0;
X+ #ifdef MSDOS
X+   egrep_flag = 0;
X+   while ((c = getopt(argc, argv, "0123456789A:B:CEVbce:f:hilnsvwx")) != EOF)
X+ #else
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X  #endif
X      switch (c)
X**************
X*** 570,575
X  
X    opterr = 0;
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X      switch (c)
X        {
X        case '?':
X--- 607,613 -----
X    while ((c = getopt(argc, argv, "0123456789A:B:CEVbce:f:hilnsvwx")) != EOF)
X  #else
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X+ #endif
X      switch (c)
X        {
X  #ifdef MSDOS
X**************
X*** 572,577
X    while ((c = getopt(argc, argv, "0123456789A:B:CVbce:f:hilnsvwx")) != EOF)
X      switch (c)
X        {
X        case '?':
X  	usage_and_die();
X  	break;
X--- 610,621 -----
X  #endif
X      switch (c)
X        {
X+ #ifdef MSDOS
X+       case 'E':
X+         egrep_flag = 1;
X+         break;
X+ #endif
X+ 
X        case '?':
X  	usage_and_die();
X  	break;
X**************
X*** 679,684
X  	break;
X        }
X  
X    /* Set the syntax depending on arg 0 and whether to ignore case. */
X    if (*prog == 'e')
X      {
X--- 723,732 -----
X  	break;
X        }
X  
X+ #ifdef MSDOS
X+   /* Set the syntax and whether to ignore case based on -E. */
X+   if (egrep_flag)
X+ #else
X    /* Set the syntax depending on arg 0 and whether to ignore case. */
X    if (*prog == 'e')
X  #endif
X**************
X*** 681,686
X  
X    /* Set the syntax depending on arg 0 and whether to ignore case. */
X    if (*prog == 'e')
X      {
X        regsyntax(RE_SYNTAX_EGREP, ignore_case);
X        re_set_syntax(RE_SYNTAX_EGREP);
X--- 729,735 -----
X  #else
X    /* Set the syntax depending on arg 0 and whether to ignore case. */
X    if (*prog == 'e')
X+ #endif
X      {
X        regsyntax(RE_SYNTAX_EGREP, ignore_case);
X        re_set_syntax(RE_SYNTAX_EGREP);
X*** REGEX.C
X--- NEW/REGEX.C
X**************
X*** 120,125
X  
X  #else  /* not emacs */
X  
X  #ifdef USG
X  #define bcopy(s,d,n)	memcpy((d),(s),(n))
X  #define bcmp(s1,s2,n)	memcmp((s1),(s2),(n))
X--- 120,132 -----
X  
X  #else  /* not emacs */
X  
X+ #ifdef __STDC__
X+ #include <stdlib.h>
X+ #endif
X+ #ifdef MSDOS
X+ char *alloca(int);
X+ #endif
X+ 
X  #ifdef USG
X  #define bcopy(s,d,n)	memcpy((d),(s),(n))
X  #define bcmp(s1,s2,n)	memcmp((s1),(s2),(n))
X**************
X*** 247,253
X  
X  #define EXTEND_BUFFER \
X    { char *old_buffer = bufp->buffer; \
X!     if (bufp->allocated == (1<<16)) goto too_big; \
X      bufp->allocated *= 2; \
X      if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
X      if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
X--- 254,260 -----
X  
X  #define EXTEND_BUFFER \
X    { char *old_buffer = bufp->buffer; \
X!     if (bufp->allocated == (1<<14)) goto too_big; \
X      bufp->allocated *= 2; \
X      if (bufp->allocated > (1<<14)) bufp->allocated = (1<<14); \
X      if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
X**************
X*** 249,255
X    { char *old_buffer = bufp->buffer; \
X      if (bufp->allocated == (1<<16)) goto too_big; \
X      bufp->allocated *= 2; \
X!     if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
X      if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
X        goto memory_exhausted; \
X      c = bufp->buffer - old_buffer; \
X--- 256,262 -----
X    { char *old_buffer = bufp->buffer; \
X      if (bufp->allocated == (1<<14)) goto too_big; \
X      bufp->allocated *= 2; \
X!     if (bufp->allocated > (1<<14)) bufp->allocated = (1<<14); \
X      if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
X        goto memory_exhausted; \
X      c = bufp->buffer - old_buffer; \
X*** DFA.C
X--- NEW/DFA.C
X**************
X*** 148,154
X  {
X    ptr_t r = realloc(p, n);
X  
X!   if (r)
X      return r;
X    else
X      regerror("Memory exhausted");
X--- 148,154 -----
X  {
X    ptr_t r = realloc(p, n);
X  
X!   if (r || (n == 0))
X      return r;
X    else
X      regerror("Memory exhausted");
X**************
X*** 1190,1197
X       struct regexp *r;
X       int trans[];
X  {
X-   _position_set grps[_NOTCHAR];	/* As many as will ever be needed. */
X-   _charset labels[_NOTCHAR];	/* Labels corresponding to the groups. */
X    int ngrps = 0;		/* Number of groups actually used. */
X    _position pos;		/* Current position being considered. */
X    _charset matches;		/* Set of matching characters. */
X--- 1190,1195 -----
X       struct regexp *r;
X       int trans[];
X  {
X    int ngrps = 0;		/* Number of groups actually used. */
X    _position pos;		/* Current position being considered. */
X    _charset matches;		/* Set of matching characters. */
X**************
X*** 1211,1216
X    int state_letter;		/* New state on a letter transition. */
X    static initialized;		/* Flag for static initialization. */
X    int i, j, k;
X  
X    /* Initialize the set of letters, if necessary. */
X    if (! initialized)
X--- 1209,1217 -----
X    int state_letter;		/* New state on a letter transition. */
X    static initialized;		/* Flag for static initialization. */
X    int i, j, k;
X+   _position_set grps[_NOTCHAR];	/* As many as will ever be needed. */
X+   _charset labels[_NOTCHAR];	/* Labels corresponding to the groups. */
X+ 
X  
X    /* Initialize the set of letters, if necessary. */
X    if (! initialized)
X*** WILD.C
X--- NEW/WILD.C
X***************
X*** 16,21 ****
X  #include <register.h>
X  #include <ctype.h>
X  #include <msdos.h>
X  
X  
X  /*
X--- 16,25 ----
X  #include <register.h>
X  #include <ctype.h>
X  #include <msdos.h>
X+ char *strlwr(char *arg);
X+ static int match (char *arg, char *ptr);
X+ static int add (char *arg);
X+ static void sort (struct argnode *first);
X  
X  
X  /*
X***************
X*** 64,73 ****
X  char *malloc();
X  char *_find();
X  
X- static int match ();
X- static int add ();
X- static sort ();
X- 
X  extern int __argc;
X  extern char **__argv;
X  
X--- 68,73 ----
X  char *malloc();
X  char *_find();
X  
X  extern int __argc;
X  extern char **__argv;
X  
X***************
X*** 112,121 ****
X      arghead = argend = NULL;
X  
X      for (argv = __argv; *argv; argv++)  /* for each arg... */
X!         if ( *(*argv)++ == '"' )
X!             /* strip leading quote from quoted arg */
X!         {
X!             if (add(*argv))
X                  return(-1);
X          }
X          else if (wchar = strpbrk( *argv, WILDSTRING )) {
X--- 112,119 ----
X      arghead = argend = NULL;
X  
X      for (argv = __argv; *argv; argv++)  /* for each arg... */
X!         if ( **argv == '"' ) { /* strip leading quote from quoted arg */
X!             if (add(*argv + 1))
X                  return(-1);
X          }
X          else if (wchar = strpbrk( *argv, WILDSTRING )) {
X***************
X*** 204,210 ****
X                  if (*ptr != SLASHCHAR && *ptr != ':'
X                      && *ptr != FWDSLASHCHAR ) {
X                      /* current directory; don't need path */
X!                     if (!(arg = strdup(new)) || add(arg))
X                          return(-1);
X                  }
X                  else    /* add full pathname */
X--- 202,208 ----
X                  if (*ptr != SLASHCHAR && *ptr != ':'
X                      && *ptr != FWDSLASHCHAR ) {
X                      /* current directory; don't need path */
X!                     if (!(arg = strdup(new)) || add(strlwr(arg)))
X                          return(-1);
X                  }
X                  else    /* add full pathname */
X***************
X*** 209,216 ****
X                  }
X                  else    /* add full pathname */
X                      if (!(all=malloc(length+strlen(new)+1))
X!                         || add(strcpy(strncpy(all,arg,length)+length,new)
X!                         - length))
X                          return(-1);
X  
X                  gotone++;
X--- 207,214 ----
X                  }
X                  else    /* add full pathname */
X                      if (!(all=malloc(length+strlen(new)+1))
X!                         || add(strlwr(strcpy(strncpy(all,arg,length)+length,new)
X!                         - length)))
X                          return(-1);
X  
X                  gotone++;
X***************
X*** 276,282 ****
X  *
X  *******************************************************************************/
X  
X! static
X  sort (first)
X  REG2 struct argnode *first;
X  {
X--- 274,280 ----
X  *
X  *******************************************************************************/
X  
X! static void
X  sort (first)
X  REG2 struct argnode *first;
X  {
SHAR_EOF
sed 's/^X//' << \SHAR_EOF > makefile.msc
X#
X# Makefile for GNU e?grep (using a PD MSDOS development environment)
X#
X
X# -DUSG for System V, -DMSDOS for IBM/PCs (if the compiler doesn't).
X# -DMSC_WILD to use the Microsoft C compiler's wild card function _cwild().
X# -DBLOCKS to print file names seperate from matched lines.
X#CFLAGS = -Oalt -DUSG -AC -Zi
XCFLAGS = -Oailt -Gs -DUSG -DMSC_WILD -DBLOCKS -AC
X
X# You may add getopt.obj if your C library lacks getopt(); note that
X# 4.3BSD getopt() is said to be somewhat broken.
X# Add alloca.obj if your machine does not support alloca().
X# Add wild.obj if you are using the Microsoft C compiler.
XOBJS = grep.obj dfa.obj regex.obj getopt.obj wild.obj
X
Xall: regress
X
Xregress: grep.exe
X	cd tests; sh regress.sh
X
Xgrep.exe: $(OBJS)
X	$(CC) $(CFLAGS) -F 4000  -o grep $(OBJS) -link /noe
X
Xclean:
X	del grep.exe *.obj tests/tmp.scr
X
Xdfa.obj grep.obj: dfa.h
Xgrep.obj regex.obj: regex.h
SHAR_EOF
#	End of shell archive
exit 0
===========================================================================
Charles Marslett
STB Systems, Inc.  <== Apply all standard disclaimers
Wordmark Systems   <== No disclaimers required -- that's just me
chasm@killer.dallas.tx.us