// bgrep.b                         1038                          5/13/00

// A simple "grep" variant which recognizes the "&" and "#" operators
// to find lines containing "string1" and "string2" or finds line con-
// taining either "string1" or "string2".  The "-n" instruction is ac-
// cepted to list line numbers.  Note that "&" is used to denote "and",
// but Messy-DOS does not accept "|", so "#" is used instead.

// Analysis of command-line forms for "bgrep":

//     1. bgrep foo bar.doc                         (argc = 3)
     
//     2. bgrep -n foo bar.doc                      (argc = 4)
     
//     3. bgrep foo | gip bar.doc                   (argc = 5)
     
//     3. bgrep -n foo & gip bar.doc                (argc = 6)
     
// If argc is less than three or greater than six, the command-
// line is incorrect!


#lib fasmlib;

char fname[20];
char search[201];
char string1[100];
char string2[100];
int logic;
int linum;
int infile;
int line;
int result;

void do_search(void);         // search for matching patterns(s)
void parse_commands(void);    // "dissect" arguments on command line
void print_line(void);        // print line to stdout
void show_usage(void);        // show correct usage and exit

void main(int argc, char *argv[])
     {
     if(argc < 3)
          {
          show_usage();       // show correct usage and exit
          }

     if(argc > 6)
          {
          show_usage();       // show correct usage and exit
          }
          
     parse_commands();        // "dissect" arguments on command line

     infile = fopen(fname, 0);
     if(!infile)
          {
          printf("\n\n\tCannot open %s!\n\n", fname);
          exit(1);
          }
          
     printf("\n\nFILE: %s...\n", fname);

     while(1)
          {
          result = fgets(search, 200, infile);
          line++;
          if(!result) break;  // EOF
          do_search();        // search for matching patterns(s)          
          }
                                      
     fclose(infile);          
     }     
     
void do_search(void)          // search for matching patterns(s)
     {
     switch(logic)
          {
          case 0:             // simple search
                    result = strstr(search, string1);
                    if(result)
                         {
                         print_line(); // print line to stdout
                         }          
                    break;
                    
          case 1:             // "and" (find both patterns)
                    result = strstr(search, string1); // look for first match
                    if(result)
                         {
                         result = strstr(search, string2); // look for second
                         if(result)
                              {
                              print_line(); // print line to stdout
                              }                       
                         }
                    break;   
                    
          case 2:             // "or" (find either pattern)
                    result = strstr(search, string1); // look for first match
                    if(result)
                         {
                         print_line(); // print line to stdout
                         }
                    else
                         {
                         result = strstr(search, string2); // look for second
                         if(result)
                              {
                              print_line(); // print line to stdout
                              }                       
                         }
                    break;                                                                                            
          }
     }                    

void parse_commands(void)     // "dissect" arguments on command line
     {
     char *ptr;
     
     switch(argc)
          {
          case 3:   
                    ptr = argv[1]; // simplest case
                    strcpy(string1, ptr);
                    ptr = argv[2];
                    strcpy(fname, ptr);
                    break;
     
          case 4:   
                    ptr = argv[1]; // line numbers
                    result = strstr(ptr, "-n");
                    if(result)
                         {
                         linum = 1;
                         }
                    else
                         {
                         show_usage();
                         }
                    ptr = argv[2];
                    strcpy(string1, ptr);
                    ptr = argv[3];
                    strcpy(fname, ptr);
                    break;
                    
          case 5:          
                    ptr = argv[1]; // no line numbers - logic
                    strcpy(string1, ptr); // get first "pattern"
                    ptr = argv[2];
                    result = strchr(ptr, '&') // "and" comparison?
                    if(result)
                         {
                         logic = 1; // show "and"
                         }
                    else
                         {
                         result = strchr(ptr, '#') // "or" comparison?
                         if(result)
                              {
                              logic = 2;
                              }
                         else
                              {
                              show_usage();
                              }
                         }
                    ptr = argv[3];
                    strcpy(string2, ptr); // get second "pattern"
                    ptr = argv[4];
                    strcpy(fname, ptr);
                    break;
                    
          case 6:
                    ptr = argv[1]; // line numbers - logic                    
                    result = strstr(ptr, "-n");
                    if(result)
                         {
                         linum = 1;
                         }
                    else
                         {
                         show_usage();
                         }
                    ptr = argv[2];
                    strcpy(string1, ptr);
                    ptr = argv[3];
                    result = strchr(ptr, '&') // "and" comparison?
                    if(result)
                         {
                         logic = 1; // show "and"
                         }
                    else
                         {
                         result = strchr(ptr, '#') // "or" comparison?
                         if(result)
                              {
                              logic = 2;
                              }
                         else
                              {
                              show_usage();
                              }
                         }
                    ptr = argv[4];
                    strcpy(string2, ptr); // get second "pattern"
                    ptr = argv[5];
                    strcpy(fname, ptr);
                    break;

                    
          default:  
                    show_usage();                    
          }
     }                         
               
void print_line(void)         // print line to stdout               
     {
     if(linum)
          {
          printf("%ld: %s", line, search);
          }
     else
          {
          printf("%s", search);
          }
     }
     
void show_usage(void)         // show correct usage and exit
     {
     printf("\n\n\tUSAGE: bgrep [-n] pat1 [&/#] [pat2] file\n\n");
     if(infile)               // should never happen!
          {
          fclose(infile);
          }
          
     exit(1);
     }     
     