home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / GRES2.ZIP / GRES.C next >
C/C++ Source or Header  |  1989-12-27  |  7KB  |  254 lines

  1. /* gres - grep and substitute        Author: Martin C. Atkins */
  2.  
  3. /* $Header: d:/rcs/D:/RCS/RCS/gres.c 1.1 89/12/27 03:54:15 RCA Exp $
  4.  * $Log:    gres.c $
  5.  * Revision 1.1  89/12/27  03:54:15  RCA
  6.  * Initial revision
  7.  * 
  8.  */
  9.  
  10. /*
  11.  * globally search, and replace 
  12.  *
  13.  * <-xtx-*>cc -o gres gres.c -lregexp 
  14.  */
  15. /*
  16.  * From Minix to DOS to OS/2 by R. Ames
  17.  */
  18. /*
  19.  * This program was written by: Martin C. Atkins, University of
  20.  * York, Heslington, York. Y01 5DD England and is released into
  21.  * the public domain, on the condition that this comment is
  22.  * always included without alteration. 
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include "regexp.h"
  27.  
  28. #define MAXLINE (1024)
  29.  
  30. int     status = 1;
  31. /*
  32.  * char *usagemsg = "Usage: gres [-g] search replace [file
  33.  * ...]\n"; 
  34.  */
  35. char   *progname;
  36. int     gflag = 0;    /* != 0 => only do first substitution on
  37.              * line */
  38. /*
  39.  * STRCHR, not INDEX extern char *index(); 
  40.  */
  41.  
  42. FILE   *fopen();
  43. main(argc, argv)
  44.    int     argc;
  45.    char   *argv[];
  46. {
  47. regexp *exp;
  48. char   *repstr;
  49. char  **argp = &argv[1];
  50.    progname = argv[0];
  51.    if (*argp != 0 && argp[0][0] == '-' && argp[0][1] == 'g')
  52.    {
  53.       gflag = 1;
  54.       argp++, argc--;
  55.    }
  56.    if (argc < 3)
  57.    {
  58.       printf("▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\n");
  59.       printf("█ GRES (Global Regular Expression Substitute) $Author: RCA $ █\n");
  60.       printf("█      $Date: 89/12/27 03:54:15 $           $Revision: 1.1 $ █\n");
  61.       printf("█ Usage: GRES [-g] \"search\" \"replace\" <infile >outfile       █\n");
  62.       printf("█ Purpose: Search by regular expression (like GREP) and      █\n");
  63.       printf("█      substitute a string. The -g flag only changes the     █\n");
  64.       printf("█      first occurrence per line.                            █\n");
  65.       printf("█ OS:  DOS or OS/2.                                          █\n");
  66.       printf("█ Credits: M.C. Atkins, H. Spencer                           █\n");
  67.       printf("▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n");
  68.       printf("- more -\n");
  69.       getch();
  70.  
  71.       printf("▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\n");
  72.       printf("█ Expressions:                                               █\n");
  73.       printf("█      1. Any displayable character matches itself.          █\n");
  74.       printf("█      2. . (period) matches any character except line feed. █\n");
  75.       printf("█      3. ^ (caret) matches the start of a line.             █\n");
  76.       printf("█      4. $ (dollar sign) matches the end of a line.         █\n");
  77.       printf("█      5. \\c matches character c (including period, etc).    █\n");
  78.       printf("█      6. [string] matches any characters in the string.     █\n");
  79.       printf("█      7. [^string] matches any characters EXCEPT in string. █\n");
  80.       printf("█      8. [x-y] matches any characters between x and y.      █\n");
  81.       printf("█      9. pattern* matches any number of occurrences of      █\n");
  82.       printf("█         pattern.                                           █\n");
  83.       printf("█  Examples:                                                 █\n");
  84.       printf("█      Guild     matches any occurrence of \"Guild\"           █\n");
  85.       printf("█      ^$        matches any empty line                      █\n");
  86.       printf("█      ^A.*\\.$   matches any line beginning with A, ending   █\n");
  87.       printf("█                with period.                                █\n");
  88.       printf("█      ^[A-Z]*$  matches any line containing only capital    █\n");
  89.       printf("█                letters (or empty)                          █\n");
  90.       printf("█                                                            █\n");
  91.       printf("▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n");
  92.  
  93.       done(2);
  94.    }
  95.    if (argp[0][0] == '\0')
  96.    {
  97.       printf("gres: null match string is silly\n");
  98.       done(2);
  99.    }
  100.    if ((exp = regcomp(*argp++)) == NULL)
  101.    {
  102.       printf("gres: regcomp failed\n");
  103.       done(2);
  104.    }
  105.    repstr = *argp++;
  106.    if (*argp == 0)
  107.       process(stdin, exp, repstr);
  108.    else
  109.       while (*argp)
  110.       {
  111. FILE   *inf;
  112.      if (strcmp(*argp, "-") == 0)
  113.         process(stdin, exp, repstr);
  114.      else
  115.      {
  116.         if ((inf = fopen(*argp, "r")) == NULL)
  117.         {
  118.            printf("gres: Can't open ");
  119.            printf(*argp);
  120.            printf("\n");
  121.            status = 2;
  122.         } else
  123.         {
  124.            process(inf, exp, repstr);
  125.            fclose(inf);
  126.         }
  127.      }
  128.      argp++;
  129.       }
  130.    done(status);
  131. }
  132. /*
  133.  * This routine does the processing 
  134.  */
  135. process(inf, exp, repstr)
  136.    FILE   *inf;
  137.    regexp *exp;
  138.    char   *repstr;
  139. {
  140. char    ibuf[MAXLINE];
  141.    while (fgets(ibuf, MAXLINE, inf) != NULL)
  142.    {
  143.    /*
  144.     * char *cr = index(ibuf,'\n'); 
  145.     */
  146. char   *cr = strchr(ibuf, '\n');
  147.       if (cr == 0)
  148.      printf("gres: Line broken\n");
  149.       else
  150.      *cr = '\0';
  151.       if (regexec(exp, ibuf, 1))
  152.       {
  153.      pline(exp, ibuf, repstr);
  154.      if (status != 2)
  155.         status = 0;
  156.       } else
  157.      printf("%s\n", ibuf);
  158.    }
  159. }
  160.  
  161. void
  162. regerror(s)
  163.    char   *s;
  164. {
  165.    printf("gres: ");
  166.    printf(s);
  167.    printf("\n");
  168.    done(2);
  169. }
  170.  
  171. char   *
  172. getbuf(exp, repstr)
  173.    regexp *exp;
  174.    char   *repstr;
  175. {
  176. char   *malloc();
  177. void    free();
  178. static  bufsize = 0;
  179. static char *buf = 0;
  180. int     guess = 10;
  181. int     ch;
  182.    while (*repstr)
  183.    {
  184.       switch (*repstr)
  185.       {
  186.       case '&':
  187.      guess += exp->endp[0] - exp->startp[0];
  188.      break;
  189.       case '\\':
  190.      if ((ch = *++repstr) < '0' || ch > '9')
  191.         guess += 2;
  192.      else
  193.      {
  194.         ch -= '0';
  195.         guess += exp->endp[ch] - exp->startp[ch];
  196.      }
  197.      break;
  198.       default:
  199.      guess++;
  200.       }
  201.       repstr++;
  202.    }
  203.    if (bufsize < guess)
  204.    {
  205.       if (buf != 0)
  206.      free((char *) buf);
  207.       buf = malloc(guess);
  208.    }
  209.    return buf;
  210. }
  211. pline(exp, ibuf, repstr)
  212.    regexp *exp;
  213.    char    ibuf[];
  214. char   *repstr;
  215. {
  216.    do
  217.    {
  218.       dosub(exp, ibuf, repstr);
  219.       ibuf = exp->endp[0];
  220.       if (*ibuf == '\0')
  221.      break;
  222.       if (ibuf == exp->startp[0])
  223.      putchar(*ibuf++);
  224.    } while (!gflag && regexec(exp, ibuf, 0));
  225.    printf("%s\n", ibuf);
  226. }
  227. /*
  228.  * print one subsitution 
  229.  */
  230. dosub(exp, ibuf, repstr)
  231.    regexp *exp;
  232.    char    ibuf[];
  233. char   *repstr;
  234. {
  235. char   *buf = getbuf(exp, repstr);
  236. char   *end = exp->startp[0];
  237. int     ch = *end;
  238.    *end = '\0';
  239.    fputs(ibuf, stdout);        /* output the initial part of
  240.                  * line */
  241.    *end = ch;
  242.    regsub(exp, repstr, buf);
  243.    fputs(buf, stdout);
  244. }
  245. done(n)
  246.    int     n;
  247. {
  248. /*
  249.  * _cleanup();            || flush stdio's internal buffers
  250.  * || 
  251.  */
  252.    exit(n);
  253. }
  254.