home *** CD-ROM | disk | FTP | other *** search
- /*+--------------------------------------------------------------------------+*/
- /*| |*/
- /*| PROGRAM NAME: GREP |*/
- /*| ------------- |*/
- /*| A Simple OS/2 GREP program |*/
- /*| |*/
- /*| COPYRIGHT: |*/
- /*| ---------- |*/
- /*| Copyright (C) International Business Machines Corp., 1991,1992. |*/
- /*| |*/
- /*| 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/2 Standard Library |*/
- /*| DDE4SBM.LIB - C Set/2 Migration Library |*/
- /*| |*/
- /*| REQUIRED PROGRAMS: |*/
- /*| ------------------ |*/
- /*| |*/
- /*| IBM C Set/2 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/2 Grep Utility\n") ;
- printf("Copyright (C) International Business Machines Corp., 1991,1992.\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) ;
- }
-
- 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) ;
- }
- }
-
-