home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
COMPILER
/
GREP
/
GREP.C
< prev
next >
Wrap
Text File
|
1993-02-28
|
23KB
|
657 lines
/*+--------------------------------------------------------------------------+*/
/*| |*/
/*| PROGRAM NAME: GREP |*/
/*| ------------- |*/
/*| A Simple OS/2 GREP program |*/
/*| |*/
/*| COPYRIGHT: |*/
/*| ---------- |*/
/*| Copyright (C) International Business Machines Corp., 1991,1992,1993. |*/
/*| |*/
/*| DISCLAIMER OF WARRANTIES: |*/
/*| ------------------------- |*/
/*| The following [enclosed] code is sample code created by IBM |*/
/*| Corporation. This sample code is not part of any standard IBM product |*/
/*| and is provided to you solely for the purpose of assisting you in the |*/
/*| development of your applications. The code is provided "AS IS", |*/
/*| without warranty of any kind. IBM shall not be liable for any damages |*/
/*| arising out of your use of the sample code, even if they have been |*/
/*| advised of the possibility of such damages. |*/
/*| |*/
/*| REVISION LEVEL: 1.0 |*/
/*| --------------- |*/
/*| |*/
/*| WHAT THIS PROGRAM DOES: |*/
/*| ----------------------- |*/
/*| This program is a simple grep with limited regular expression |*/
/*| support. Type Grep by itself for more help. |*/
/*| |*/
/*| WHAT THIS PROGRAM DEMONSTRATES: |*/
/*| ------------------------------- |*/
/*| This program demonstrates how various C constructs are used; |*/
/*| it demonstrates how to do subdirectory searching through the help |*/
/*| of various API calls. |*/
/*| |*/
/*| |*/
/*| REQUIRED FILES: |*/
/*| --------------- |*/
/*| |*/
/*| GREP.C - Source code |*/
/*| GREP.H - Common definitions |*/
/*| GREP.MAK - Make file for this program |*/
/*| HELP.C - Help procedures |*/
/*| |*/
/*| OS2.H - APIs include file |*/
/*| STDLIB.H - Standard library function declarations |*/
/*| STRING.H - String handling function declarations |*/
/*| STDIO.H - Handling IO |*/
/*| CTYPE.H - For mapping different casing |*/
/*| |*/
/*| REQUIRED LIBRARIES: |*/
/*| ------------------- |*/
/*| |*/
/*| OS2386.LIB - Presentation Manager/OS2 library |*/
/*| DDE4SBS.LIB - C Set++ Standard Library |*/
/*| |*/
/*| REQUIRED PROGRAMS: |*/
/*| ------------------ |*/
/*| |*/
/*| IBM C Set++ Compiler |*/
/*| IBM Linker |*/
/*| |*/
/*| |*/
/*+--------------------------------------------------------------------------+*/
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "grep.h"
#ifndef OS2_INCLUDED
#define OS2_INCLUDED
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#endif
static FILEFINDBUF3 findBuffer ;
static FILE *inputFile ;
static char inputLine[MAX_LINE_LENGTH] ;
static char origLine[MAX_LINE_LENGTH] ;
static int inputLineLength ;
static int dummyVal ;
static int printFileName ;
static char *searchPattern = NULL ;
static int fileCount, lineCount ;
static int contextCount ;
static char *theLine ;
static char *tmpLine ;
static char fileMask[255] ;
static char searchPath[260] ;
/*********************/
/* Options variables */
/*********************/
static int helpType ;
static int noLogo = 0 ;
static int caseFlag = 0 ;
static int pauseFlag = 0 ;
static int countFlag = 0 ;
static int lineFlag = 0 ;
static int contextFlag = 0 ;
static int absFlag = 0 ;
static int dirFlag = 0 ;
static int notFlag = 0 ;
static int nameFlag = 0 ;
static int pauseLineCount = 0 ;
/*****************************************************************/
/* The following declarations support simple regular expressions */
/*****************************************************************/
char *regExprKeyChar = "*?" ;
typedef struct structName
{
char * str ; /* Piece of string to search for */
int strType ;
struct structName * next ;
} subStringList ;
subStringList * listHead = NULL ;
subStringList * curPtr = NULL ;
subStringList * prevPtr = NULL ;
int prevStrType , pieceLength ;
char * tmpPtr ;
int foundFlag ;
/*****************************/
/* Function Prototypes */
/*****************************/
void processFile(char *);
int forAllMatch(char * );
void grepHelp(int );
/*********************/
/* Main Program */
/*********************/
int main (int argc, char **argv)
{
if ( argc == 1)
{
grepHelp(LINE_HELP) ;
exit (0) ;
}
argv++;
argc--;
/*******************/
/* Process options */
/*******************/
while ( argc > 0 && (**argv == '-' || **argv == '/' ) )
{
(*argv)++ ;
while (**argv != '\0')
{
switch (**argv)
{
case 'q':
noLogo = 1 ;
break ;
case 'y':
caseFlag = 1 ;
break ;
case 's':
dirFlag = 1 ;
break ;
case 'n':
nameFlag = 1 ;
break ;
case 'p':
pauseFlag = 1 ;
break ;
case 'l':
lineFlag = 1 ;
break ;
case 'a':
absFlag = 1 ;
break ;
case 'c':
countFlag = 1 ;
break ;
case 'v':
notFlag = 1 ;
break ;
case 'C':
contextFlag = 1 ;
(*argv)++;
if ( ! isdigit(**argv) )
printf("'-C' option expected integer, default of 3 is assumed.\n");
else
{
contextCount = **argv ;
(*argv)++;
}
break ;
case 'h':
grepHelp(FULL_HELP);
exit(0);
case 'z':
grepHelp(CMDS_HELP);
exit(0);
default:
printf("Grep: Unrecognized flag '%c' ignored.\n\n",**argv);
break;
}
(*argv)++;
}
argv++ ;
argc-- ;
}
if (argc == 0)
{
printf("grep: incorrect number of parameters\n");
grepHelp(LINE_HELP);
exit(255) ;
}
/******************************/
/* Process the search pattern */
/******************************/
searchPattern = *argv ;
argv++ ;
argc-- ;
if ( ! noLogo )
{
printf("IBM C Set++ Grep Utility\n") ;
printf("Copyright (C) International Business Machines Corp., 1991,1992,1993.\n\n");
}
if ( ! argc)
{
printf("Grep: You must specify at least one file name!\n");
exit (255) ;
}
printf("Searching for \"%s\"\n",searchPattern);
if ( ! caseFlag )
(void)strupr(searchPattern) ;
/***********************************************************/
/* Below, we are building a linked-list of search patterns.*/
/* Each block is composed of the longest substring before */
/* the appearance of any Special Chars (ie ? and * ). */
/* There are two types of blocks, one type is the one */
/* mentioned above, the other type is a block containing */
/* information on how many '?'s we have to match. */
/***********************************************************/
if (absFlag) /* Interpret the search string as absolute. */
{
if ((listHead = (subStringList *)malloc(sizeof(subStringList))) == NULL)
{
printf("grep(1): Unable to get memory!\n");
exit(255);
}
listHead->str = searchPattern ;
listHead->strType = REGULAR_TYPE ;
listHead->next = NULL ;
prevPtr = NULL ;
}
else
/* Parsing of the expression line. */
{
if ((listHead = (subStringList *)malloc(sizeof(subStringList))) == NULL)
{
printf("grep(2): Unable to get memory! \n");
exit(255);
}
curPtr = listHead ;
curPtr->strType = 0 ;
curPtr->str = NULL ;
curPtr->next = NULL ;
prevPtr = NULL ;
tmpPtr = searchPattern ;
while (*tmpPtr != '\0')
{
pieceLength = strcspn(tmpPtr,regExprKeyChar) ;
if (! pieceLength ) /* Found '*' or '?' */
{
if (*tmpPtr == '*' )
++tmpPtr ;
else
{
curPtr->str = NULL ;
curPtr->strType = 1;
++tmpPtr ;
while (*tmpPtr == '?')
{
++tmpPtr ;
curPtr->strType += 1;
}
if ((curPtr->next = (subStringList *)malloc(sizeof(subStringList))) == NULL)
{
printf("grep(3): Unable to get memory!\n");
exit(255);
}
prevPtr = curPtr ;
curPtr = curPtr->next ;
curPtr->next = NULL ;
}
}
else
{
if ((curPtr->str = (char *)malloc(pieceLength+1)) == NULL)
{
printf("grep(4): Unable to get memory!\n");
exit(255);
}
memcpy(curPtr->str,tmpPtr,pieceLength) ;
*(curPtr->str+pieceLength) = '\0' ;
curPtr->strType = REGULAR_TYPE ;
tmpPtr += pieceLength ;
if ((curPtr->next = (subStringList *)malloc(sizeof(subStringList))) == NULL)
{
printf("grep(5): Unable to get memory!\n");
exit(255);
}
prevPtr = curPtr ;
curPtr = curPtr->next ;
curPtr->next = NULL ;
}
}
}
if (prevPtr == NULL && absFlag != 1)
{
printf("grep: You have specified an invalid pattern!\n");
exit(255) ;
}
if (prevPtr != NULL)
prevPtr->next = NULL ; /* Throw away the extra block. */
/* We always allocate one more */
/* block on the list. */
/* Must do a subdirectory search */
fileCount = 0 ;
while(argc--)
{
if ( dirFlag || strchr(*argv,'\\') || strchr(*argv,':'))
{
dirFlag = 1;
tmpPtr = (char *)(*argv + (strlen(*argv) - 1)) ;
while ( *tmpPtr != '\\' && *tmpPtr != ':' && tmpPtr != *argv )
--tmpPtr;
if ( tmpPtr == *argv)
{
strcpy(searchPath,".");
strcpy(fileMask, *argv);
}
else
{
if ( *tmpPtr == '\\')
{
*tmpPtr++ = '\0';
strcpy(fileMask, tmpPtr) ;
strcpy(searchPath, *argv);
}
else /* The case when we have ':' */
{
tmpPtr++ ;
strcpy(fileMask, tmpPtr) ;
*tmpPtr = '\0';
strcpy(searchPath, *argv);
}
}
}
else
{
strcpy(searchPath,".");
strcpy(fileMask, *argv);
}
forAllMatch(searchPath);
argv++ ;
}
return 0;
}
/****************************************/
/* forAllMatch */
/* */
/* Go through each file that match the */
/* file mask. */
/* */
/* Do subdirectory search if requested. */
/* */
/****************************************/
int forAllMatch(char * path)
{
HDIR findHandle = 0xFFFFFFFF ; /* Let OS/2 get us the handle */
int findCount = 1 ;
USHORT rc ;
char newPath[256];
/* Recursively process all subdirectory */
if ( path[strlen(path)-1] == ':')
strcat (path,"*.*");
else
strcat (path,"\\*.*");
if (dirFlag) /* Subdirectory search requested */
{
rc = DosFindFirst(path ,
&findHandle ,
FILE_DIRECTORY ,
&findBuffer ,
(ULONG)sizeof(findBuffer) ,
(PULONG)&findCount ,
(ULONG)0x0001);
if (rc)
return rc;
while (!rc)
{
if (strcmp(findBuffer.achName,".") && strcmp(findBuffer.achName,".."))
{
if (findBuffer.attrFile == FILE_DIRECTORY )
{
strcpy(newPath,path) ;
newPath[strlen(path)-3] = '\0';
strcat(newPath,findBuffer.achName) ;
forAllMatch(newPath) ;
}
}
rc = DosFindNext(findHandle,
&findBuffer,
sizeof(findBuffer),
(PULONG) &findCount);
}
}
/* When we get here, we have in path, the path to the directory we are */
/* going to work with. */
/* Process all normal files that match the fileMask in the current directory */
findHandle = 0xFFFFFFFF;
strcpy(newPath,path) ;
newPath[strlen(path)-3] = '\0';
strcat(newPath,fileMask);
findCount = 1 ;
rc = DosFindFirst(newPath,
&findHandle,
(ULONG)0L,
&findBuffer,
(ULONG)sizeof(findBuffer),
(PULONG)&findCount,
(ULONG)0x0001);
path[strlen(path)-3] = '\0';
while (!rc) /* Process each file that matches the mask */
{
strcpy(newPath,path) ;
strcat(newPath,findBuffer.achName) ;
processFile(newPath) ;
rc = DosFindNext(findHandle,
&findBuffer,
sizeof(findBuffer),
(PULONG)&findCount);
}
return 0 ;
}
/****************************************/
/* processFIle */
/* */
/* fileName contains the name and path */
/* to the file that we will do a */
/* search for the given pattern. */
/* */
/****************************************/
void processFile(char * fileName)
{
fileCount++;
printFileName = 0 ; /* Not yet print file Name */
if ( (inputFile = fopen(fileName,"r") ) == NULL )
printf("Grep: Unable to open %s.\n", fileName) ;
else
{
lineCount = 0 ;
while (fgets(inputLine,MAX_LINE_LENGTH,inputFile) != NULL )
{
strcpy(origLine,inputLine) ;
if (! caseFlag)
(void)strupr(inputLine) ;
inputLine[strlen(inputLine)-1] = '\0' ;
++lineCount;
foundFlag = 0 ;
curPtr = listHead ;
theLine = inputLine ;
prevStrType = 0 ;
/*******************************************/
/* The following code walk the linked-list */
/* of pieces of the string. */
/* if strType is 0 : we match 'str' as-is, */
/* else strType = the number of ?'s in the */
/* regular expression. */
/*******************************************/
while( !foundFlag && curPtr )
{
if (curPtr->strType == 0) /* Match String as-is */
{
if ( (tmpLine = strstr(theLine,curPtr->str)) == NULL)
/* This line does not have the pattern we wanted */
curPtr = NULL ;
else
{
if (prevStrType != 0 && tmpLine != theLine)
curPtr = NULL ;
else
{
prevStrType = 0 ;
theLine = tmpLine + strlen(curPtr->str) ;
curPtr = curPtr->next ;
if ( !curPtr )
foundFlag = 1 ;
}
}
}
else /* We must skip over strType # of ?'s */
{
if ( strlen(theLine) < curPtr->strType)
curPtr = NULL ;
else
{
prevStrType = curPtr->strType ;
theLine += curPtr->strType ;
curPtr = curPtr->next ;
if ( !curPtr )
foundFlag = 1 ;
}
}
} /* end while */
if ( foundFlag && !notFlag )
{
if (nameFlag)
{
if (!printFileName)
{
printFileName = 1 ;
printf("%s\n",fileName);
}
}
else
{
if (!printFileName)
{
printFileName = 1 ;
printf("\n--------------------------------------------------------------------------------\n");
printf("Processing file %s: \n",fileName);
}
if (lineFlag)
printf("%d: %s",lineCount , origLine) ;
else
printf("%s", origLine) ;
if (pauseFlag)
{
++pauseLineCount ;
if (pauseLineCount > MAX_LINE_PER_SCREEN)
{
pauseLineCount = 1 ;
printf("Press a key to continue...\n");
dummyVal = getchar() ;
}
}
}
}
else if ( !foundFlag && notFlag )
{
if (nameFlag)
{
if (!printFileName)
{
printFileName = 1 ;
printf("%s\n",fileName);
}
}
else
{
if (!printFileName)
{
printFileName = 1 ;
printf("\n--------------------------------------------------------------------------------\n");
printf("Processing file %s: \n",fileName);
}
if (lineFlag)
printf("%d: %s",lineCount , origLine) ;
else
printf("%s", origLine) ;
if (pauseFlag)
{
++pauseLineCount ;
if (pauseLineCount > MAX_LINE_PER_SCREEN)
{
pauseLineCount = 1 ;
printf("Press ENTER to continue...\n");
dummyVal = getchar() ;
}
}
}
}
}
fclose (inputFile) ;
}
}