home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / ut-c.lbr / CH.CZ / CH.C
Encoding:
C/C++ Source or Header  |  1993-10-25  |  3.5 KB  |  152 lines

  1. /*  ch.c -- UTOOL. Change pattern in text file.
  2.  
  3.      author: David H. Wolen
  4.      last change: 3/4/83
  5.  
  6.      usage:  ch pattern [newstuff]
  7.  
  8.      input:  STDIN
  9.      output: STDOUT
  10.  
  11.      notes:    1.  metacharacters in pattern (same as find)
  12.                     %  begin of line
  13.                     # #  enclose capital letters
  14.                     " "  enclose imbedded blanks
  15.                     ?  match any char except newline
  16.                     $  end of line
  17.                     [c1-c2]  char class
  18.                     [!c1-c2] negated char class
  19.                     *  closure (0 or more occurrences of prev 1 char pattern)
  20.                     escaped chars:  \n (newline) \t (tab) \r (cr) 
  21.                          \f (form feed) \b (backspace) \q (") \p (#)
  22.                2.  If newstuff is omitted, deletion of pattern occurs.
  23.                3.  Newstuff consists of zero or more of the following:
  24.                     c  literal char
  25.                     &  ditto, i.e. whatever was matched
  26.                     \c  escaped char
  27.                     # # and " " as above
  28.  
  29.  
  30.      linkage:  a:clink ch -f dio -ca (uses deff3.crl)
  31. */
  32.  
  33. #include "a:bdscio.h"
  34. #include "dio.h"
  35.  
  36. #define  STDIN  0
  37. #define  DITTO  127      /* rubout */
  38.  
  39. main(argc,argv)
  40. int  argc;
  41. char *argv[];
  42. {
  43.      char lin[MAXLINE], pat[MAXLINE], sub[MAXLINE], arg[MAXLINE];
  44.  
  45.      dioinit(&argc,argv);
  46.  
  47.      if(argc <= 1)
  48.           error("ch: missing pattern");
  49.  
  50.      rcarg(arg,*++argv);
  51.  
  52.      if(!getpat(arg,pat))
  53.           error("ch: illegal 'from' pattern");
  54.  
  55.      if(argc == 2)       /* null 'to' string */
  56.           arg[0]='\0';
  57.      else
  58.           rcarg(arg,*++argv);
  59.  
  60.      if(!getsub(arg,sub))
  61.           error("ch: illegal 'to' string");
  62.  
  63.      while(fgets(lin,STDIN))
  64.           subline(lin,pat,sub);
  65.  
  66.      dioflush();
  67. }
  68.  
  69.  
  70.  
  71. /*  subline -- substitute sub for pat in lin and print */
  72. subline(lin,pat,sub)
  73. char *lin, *pat, *sub;
  74. {
  75.      int  i, lastm, m;
  76.  
  77.      lastm= -1;
  78.      i=0;
  79.  
  80.      while(lin[i] != '\0')
  81.           {m=amatch(lin,i,pat,0);
  82.           if(m >= 0 && lastm != m)      /* replace matched text */
  83.                {putsub(lin,i,m,sub);
  84.                lastm=m;
  85.                }
  86.  
  87.           if(m < 0 || m == i)           /* no match or null match */
  88.                {putchar(lin[i]);
  89.                i++;
  90.                }
  91.           else                          /* skip matched text */
  92.                i=m;
  93.           }
  94. }
  95.  
  96.  
  97.  
  98. /*  getsub -- get substitution string into sub  */
  99. getsub(arg,sub)
  100. char *arg, *sub;
  101. {
  102.      return(makesub(arg,0,'\0',sub) >= 0);
  103. }
  104.  
  105.  
  106.  
  107. /* makesub -- make substitution string from arg in sub */
  108. makesub(arg,from,delim,sub)
  109. char *arg, delim, *sub;
  110. {
  111.      int  i, j;
  112.  
  113.      j=0;
  114.      i=from;
  115.  
  116.      while(arg[i] != delim && arg[i] != '\0')
  117.           {if(arg[i] == '&')
  118.                addstr(DITTO,sub,&j,MAXLINE);
  119.           else
  120.                addstr(esc(arg,&i),sub,&j,MAXLINE);
  121.           i++;
  122.           }
  123.  
  124.      if(arg[i] != delim)      /* missing delimiter */
  125.           return(-1);
  126.      else if(!addstr('\0',sub,&j,MAXLINE))   /* no room */
  127.           return(-1);
  128.      else
  129.           return(i);
  130. }
  131.  
  132.  
  133.  
  134. /* putsub -- output substitution text */
  135. putsub(lin,s1,s2,sub)
  136. char *lin, *sub;
  137. int  s1, s2;
  138. {
  139.      int  i, j;
  140.  
  141.      i=0;
  142.  
  143.      while(sub[i] != '\0')
  144.           {if(sub[i] == DITTO)
  145.                for(j=s1; j <= s2-1; j++)
  146.                     putchar(lin[j]);
  147.           else
  148.                putchar(sub[i]);
  149.           i++;
  150.           }
  151. }
  152.