home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 280_01 / change.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-11  |  7.3 KB  |  317 lines

  1. /* [CHANGE.C of JUGPDS Vol.46]*/
  2. /*
  3. *****************************************************************
  4. *                                *
  5. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  6. *            49-114 Kawauchi-Sanjuunin-machi        *
  7. *            Sendai, Miyagi 980                          *
  8. *            Phone: 0222-61-3219                *
  9. *                                *
  10. *       Modifird by Toshiya Oota   (JUG-CPM No.10)              *
  11. *                   Sakae ko-po 205                 *
  12. *            5-19-6 Hosoda                *
  13. *            Katusikaku Tokyo 124            *
  14. *                                *
  15. *        for MS-DOS Lattice C V3.1J & 80186/V20/V30    *
  16. *                                *
  17. *    Compiler Option: -ccu -k0(1) -ms -n -v -w        *
  18. *                                *
  19. *    Edited & tested by Y. Monma (JUG-CP/M Disk Editor)    *
  20. *            &  T. Ota   (JUG-CP/M Sub Disk Editor)    *
  21. *                                *
  22. *****************************************************************
  23. */
  24.  
  25. /* change - change "from" into "to" 
  26.  
  27.     Usage: change [-l][-v] from [to] <infile [>outfile]
  28.  
  29. where
  30.     -l: line # 
  31.     -v: Verify flag
  32.  
  33. */
  34.  
  35. #include "stdio.h"
  36. #include "dos.h"
  37. #include "tools.h"
  38. #include "toolfunc.h"
  39.  
  40. void    copysub(),catsub();
  41.  
  42. void main(argc, argv)
  43. int    argc;
  44. char    **argv;
  45.  
  46. {
  47. char    lin[MAXLINE], pat[MAXPAT], new[MAXLINE+1], sub[10][MAXLINE];
  48. char    cmd[2][MAXLINE];
  49. char    opt_l, opt_v, opt_id ,*ap;
  50. int    i, k, lastm, m, lno, maxsub, nl, nx;
  51.  
  52.    opt_l = opt_v = opt_id = OFF;
  53.    nl = 1; i = 0;
  54.    while (--argc > 0) {
  55.     if ((*++argv)[0] == '-')             /* check option */
  56.        for (ap = argv[0]+1; *ap != '\0'; ap++) {
  57.         if (tolower(*ap) == 'l') {
  58.             opt_l = ON;
  59.             nl = 0;
  60.             for (; isdigit(nx = *(ap+1)); ap++)
  61.             nl = nl*10 + nx - '0';
  62.             nl = (nl == 0 ? 1 : nl);
  63.             }
  64.         else if (tolower(*ap) == 'v')
  65.             opt_v = ON;
  66.         else if (tolower(*ap) == 'i')
  67.             opt_id = ON;
  68.         else
  69.             fprintf(stderr,
  70.             "CHN901 [-%c]:Illigal option\n",tolower(*ap));
  71.         }
  72.         else if (i < 2)
  73.            strcpy(cmd[i++], *argv);
  74.         else
  75.            remark("CHN902 Too many arguments!\n");
  76.         }
  77.     if (i == 0)
  78.        error("CHN999 Usage: change [-ilv] from [to] <infile [>outfile]\n");
  79.     if ((maxsub = getpat(cmd[0], pat)) == ERROR)
  80.         error("CHN903 Illegal from pattern.\n");
  81.     if (i > 1) {
  82.         if (getsub(cmd[1], sub[0]) == ERROR)
  83.         error("CHN904 Illegal to pattern.\n");
  84.         }
  85.     else
  86.         sub[0][0] = EOS;
  87.     printf("CHN101 Changed to "); puts(&sub[0][0]); printf("\n");
  88.     lno = 0;
  89.     while (getlin(lin, MAXLINE) > 0) {
  90.        lno += nl;
  91.        k = 0;
  92.        lastm = -1;
  93.        for (i = 0; lin[i] != EOS; ) {
  94.         m = amatch(lin, i, pat, sub, maxsub);
  95.         if (m >= 0 && lastm != m) {     /* replace matched text */
  96.             catsub(lin, i, m, new, &k, MAXLINE, sub);
  97.             lastm = m;
  98.         }
  99.         if (m == ERROR || m == i) /* no match or null match */
  100.             addset(lin[i++], new, &k, MAXLINE);
  101.         else                /* skip matched text */
  102.             i = m;
  103.         }
  104.         if (k >= MAXLINE) {
  105.             new[MAXLINE] = EOS;
  106.             fprintf(stderr, "CHN905 line truncated.\n:%s", new);
  107.             printf("        %s\n", new);
  108.         }
  109.         else
  110.             new[k] = EOS;
  111.         if (lastm >= 0)
  112.             if (opt_l == ON) {
  113.             if (opt_id == ON )
  114.                 fprintf(stderr, "CHN111 %6d: %s", lno, new);
  115.             else
  116.                 fprintf(stderr, "%6d: %s", lno, new);
  117.             }
  118.             else
  119.             if (opt_id == ON)
  120.                 fprintf(stderr, "CHN112 %s", new);
  121.             else
  122.                 fprintf(stderr, "%s", new);
  123.             if (opt_v == ON)        /* old line display */
  124.             if (opt_l == ON)
  125.                 if (opt_id == ON)
  126.                 printf("CHN121 %6d: %s", lno, lin);
  127.                 else
  128.                 printf("%6d: %s", lno, lin);
  129.             else
  130.                 if (opt_id == ON)
  131.                 printf("CHN122 %s", lin );
  132.                 else
  133.                 printf("%s", lin );
  134.     }
  135. }
  136.  
  137.  
  138. /* catsub - add replacement text to end of new */
  139. void catsub(lin, from, to, new, k, maxnew, sub)
  140. int    from, to, *k, maxnew;
  141. char    lin[], new[], sub[10][MAXPAT];
  142.  
  143. {
  144. int    i, j, ns;
  145.  
  146.     for (i = 0; sub[0][i] != EOS && *k < maxnew; i++) {
  147.     if (sub[0][i] == DITTO) {
  148.         for (j = from; j < to && *k < maxnew; j++)
  149.         new[(*k)++] = lin[j];
  150.     }
  151.     else if (sub[0][i] == SUBSTRG) {
  152.         ns = sub[0][++i] - '0';
  153.         for (j = 0; sub[ns][j] != EOS && *k < maxnew; j++)
  154.         new[(*k)++] = sub[ns][j];
  155.     }
  156.     else if (*k >= maxnew)
  157.         break;
  158.     else
  159.         new[(*k)++] = sub[0][i];
  160.     }
  161. }
  162.  
  163. /* getsub - get substitution pattern into sub */
  164. int  getsub(arg, sub)
  165. char    *arg, *sub;
  166.  
  167. {
  168.     return(maksub(arg, 0, EOS, sub));
  169. }
  170.  
  171. /* maksub -make substitution string in sub */
  172. int  maksub(arg, from, delim, sub)
  173. char    delim, arg[], *sub;
  174. int    from;
  175.  
  176. {
  177. int    i;
  178.  
  179.     for (i = from; arg[i] != delim && arg[i] != EOS; i++)
  180.     if (arg[i] == AND)
  181.         *sub++ = DITTO;
  182.     else if (arg[i] == ESCAPE && (isdigit(arg[i+1]))) {
  183.         *sub++ = SUBSTRG;
  184.         *sub++ = arg[++i];
  185.     }
  186.     else
  187.         *sub++ = esc(arg, &i);
  188.     *sub = EOS;
  189.     if (arg[i] != delim)
  190.     return ERROR;
  191.     if (strlen(sub) > MAXLINE)
  192.     return ERROR;
  193.     return(i);
  194. }
  195.  
  196. /* amatch (non-recursive) - look for match starting at lin(from) */
  197. int amatch(lin, from, pat, sub, maxsub)
  198. char    lin[], pat[], sub[10][MAXPAT];
  199. int    from, maxsub;
  200.  
  201. {
  202. int    i, j, offset, stack, bgn[10], lst[10], l;
  203.  
  204.     stack = 0;
  205.     offset = from;
  206.     for (j = 0; pat[j] != EOS; j += patsiz(pat, j))
  207.     if (pat[j] == BPAT )
  208.         bgn[pat[j+1]-'0'] = offset;
  209.     else if (pat[j] == EPAT)
  210.         lst[pat[j+1]-'0'] = offset-1;
  211.     else if (pat[j] == CLOSURE) {
  212.         stack = j;
  213.         j += CLOSIZE;
  214.         for (i = offset; lin[i] != EOS; )
  215.         if (omatch(lin, &i, pat, j) == NO)
  216.             break;
  217.         pat[stack + COUNT] = i - offset;
  218.         pat[stack + START] = offset;
  219.         offset = i;
  220.         }
  221.     else if (omatch(lin, &offset, pat, j) == NO) {
  222.         for ( ; stack > 0; stack = pat[stack + PREVCL] ) {
  223.         if (pat[stack + COUNT] > 0)
  224.             break;
  225.         }
  226.         if (stack <= 0)
  227.         return(ERROR);
  228.         pat[stack + COUNT]--;
  229.         j = stack + CLOSIZE;
  230.         offset = pat[stack + START] + pat[stack + COUNT];
  231.     }
  232.     for (l = 1; l <= maxsub; l++)
  233.     copysub(lin, bgn[l], lst[l], sub[l]);
  234.     return(offset);
  235. }
  236.  
  237.  
  238. /* patsiz - returns size of pattern entry at pat(n) */
  239. patsiz(pat, n)
  240. char    pat[];
  241. int    n;
  242.  
  243. {
  244.     switch (pat[n]) {
  245.     case BPAT :
  246.     case EPAT :
  247.     case CHAR :
  248.           return(2);
  249.     case BOL :
  250.     case EOL :
  251.     case ANY :
  252.           return(1);
  253.     case CCL :
  254.     case NCCL:
  255.           return (pat[n+1] + 2);
  256.     case CLOSURE :
  257.           return CLOSIZE;
  258.     default  :
  259.           error("CHN911 Internal Error in patsiz: can't happen.\n");
  260.     }
  261. }
  262.  
  263.  
  264. /* omatch - try to match a single pattern at pat(j) */
  265. omatch(lin, i, pat, j)
  266. char    lin[], pat[];
  267. int    *i, j;
  268.  
  269. {
  270. int    bump;
  271. char    c;
  272.  
  273.     c = lin[*i];
  274.     if (c == EOS)
  275.     return(NO);
  276.     bump = -1;
  277.     switch (pat[j]) {
  278.     case BPAT :
  279.     case EPAT : return(YES);
  280.     case CHAR : if (c == pat[j+1])
  281.             bump= 1;
  282.             break;
  283.     case BOL :  if (*i == 0)
  284.             bump = 0;
  285.             break;
  286.     case ANY :  if (c != NEWLINE)
  287.             bump = 1;
  288.             break;
  289.     case EOL :  if (c == NEWLINE)
  290.             bump = 0;
  291.             break;
  292.     case CCL :  if (locate(c, pat, j+1) == YES)
  293.             bump = 1;
  294.             break;
  295.     case NCCL:  if (c != NEWLINE && locate(c, pat, j+1) == NO)
  296.             bump = 1;
  297.             break;
  298.     default  :  remark("CHN912 Internal Error in omatch: can't happen.\n");
  299.     }
  300.     if (bump >= 0) {
  301.     *i += bump;
  302.     return(YES);
  303.     }
  304.     return(NO);
  305. }
  306.  
  307. /* copysub - copy line to sub from b to e */ 
  308. void copysub(lin, b, e, sub)
  309. char    lin[], *sub;
  310. int    b, e;
  311. {
  312.     for( ; b <= e; b++)
  313.     *sub++ = lin[b];
  314.     *sub = EOS;
  315.     return;
  316. }
  317.