home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 143_01 / sub.c < prev    next >
Text File  |  1985-11-14  |  10KB  |  473 lines

  1. /*
  2. %CC1 $1.C -X -E5000
  3. %CLINK $1 DIO -S
  4. %DELETE    $1.CRL 
  5. */
  6. /*********************************************************************
  7. *                  SUB                     *
  8. **********************************************************************
  9. *           COPYRIGHT 1983 EUGENE H. MALLORY             *
  10. *********************************************************************/
  11. #include "BDSCIO.H"
  12. #include "DIO.H"
  13.  
  14. #define    AND &&
  15. #define    OR ||
  16. #define    EQUAL ==
  17. #define    NOTEQUAL !=
  18. #define    NOT !
  19. #define    found 0x80
  20. #define    notfound 0x81
  21. #define    match 0x82
  22. #define    notmatch 0x83
  23. #define    notbegin 0xFF
  24. #define    notend 0x8A
  25. #define    skipany    0x86
  26. #define    skipone    0x87
  27. #define    lineend    0x0A
  28. #define    linestart 0x7F
  29. #define    anyalpha 0x12
  30. #define    anynumber 0x14
  31.       
  32. char string[MAXLINE];
  33. char temps[MAXLINE];
  34. char pattern[MAXLINE];
  35. char replace[MAXLINE];
  36. char anystr[MAXLINE];
  37. int i,j,firstpat,nextpat,start;
  38.     
  39. main(argc,argv)
  40. char **argv;
  41. int argc;
  42.  
  43. BEGIN
  44.     char c;
  45.     int    ii,jj,optionerr;
  46.     char *ss;
  47.  
  48.     dioinit(&argc,argv);
  49.  
  50. /*********************************************************************
  51. ***          ARGUMENT PROCESSING                   ***
  52. *********************************************************************/
  53.     optionerr = FALSE;
  54.     
  55.     for (ii=argc-1;ii>0;ii--)
  56.         if (argv[ii][0] == '-')
  57.         BEGIN
  58.             for    (ss = &argv[ii][1]; *ss    != '\0';)
  59.             BEGIN
  60.                 switch (toupper(*ss++))
  61.                 BEGIN
  62.                     case 'H':
  63.                     optionerr = TRUE;
  64.                     break;
  65.                     default:
  66.                     typef("SUB: Illegal option %c.\n"
  67.                         ,*--ss);
  68.                     ss++;
  69.                     optionerr = TRUE;
  70.                     break;
  71.                 END
  72.                 while (isdigit(*ss)) ss++;
  73.             END
  74.             for    (jj=ii;jj<(argc-1);jj++) argv[jj] = argv[jj+1];
  75.             argc--;
  76.         END
  77.     
  78.  
  79.     if (optionerr) 
  80.         BEGIN
  81.         typef("SUB: Substitutes    Pat2 for Pat1: ONLY option is -H.\n");
  82.         typef("Meta characters are:.\n");
  83.         typef("* - Any character string.\n");
  84.         typef("? - Any single character.\n");
  85.         typef("_ - A space.\n");
  86.         typef("\\ - A literal character    follows.\n");
  87.         typef("{ - Beginning of    line.\n");
  88.         typef("} - End of line.\n");
  89.         typef("@ - Any alphabetic character.\n");
  90.         typef("# - Any numeric character.\n");
  91.         typef("! - NOT the character that follows.\n");
  92.         exit(0);
  93.         END
  94.     
  95. /*********************************************************************
  96. ***             END OF ARGUMENT PROCESSING               ***
  97. *********************************************************************/
  98.     
  99.     firstpat = nextpat = 0;
  100.     if (argc < 2) error("SUB: Needs a pattern argument.");
  101.     setuppat(argv[1],pattern);
  102.     if (argc >=3)
  103.     BEGIN
  104.         replace[0] = 0;
  105.         for(i=2;i<argc;i++)
  106.         BEGIN
  107.         setuprep(argv[i],string);
  108.         strcat(replace,string);
  109.         if (i != argc-1) strcat(replace," ");
  110.         END
  111.     END
  112.     else
  113.     BEGIN
  114.         replace[0] = 0;
  115.     END
  116.     
  117.     while (NOT(getstring(&string[1])))
  118.     BEGIN
  119.         string[0] =    linestart;
  120.         start = 0;
  121. findpat:            
  122.         if (find(start) EQUAL found)
  123.         BEGIN
  124. /*   printf("Firstpat is %d, nextpat is    %d.\n",firstpat,nextpat);   */
  125.             for    (i = 0;i<firstpat;i++)
  126.             temps[i] = string[i];
  127.             temps[i] = 0;
  128.             j=0;
  129.             for    (i=firstpat;i<nextpat;i++)
  130.              anystr[j++] = string[i];
  131.             anystr[j] =    0;
  132. /* printf("replacement str is:%s\n",anystr); */
  133.             catstr(temps,replace,anystr);
  134.             start = strlen(temps);
  135.             if (start>0    && pattern[0] EQUAL notbegin) start--;
  136.             strcat(temps,&string[nextpat]);
  137.             if (string[nextpat]    NOTEQUAL 0)
  138.             BEGIN
  139.                 strcpy(string,temps);
  140.                 goto findpat;
  141.             END
  142.             else
  143.             BEGIN
  144.                 for    (i=0;temps[i];i++)
  145.                 BEGIN
  146.                     c =    temps[i];
  147.                     if (c NOTEQUAL linestart
  148.                     AND
  149.                     c NOTEQUAL lineend)
  150.                         putchar(c);
  151.                 END
  152.                 putchar('\n');
  153.             END
  154.         END
  155.         else
  156.         BEGIN
  157.             for (i=0;string[i];i++)
  158.                 BEGIN
  159.                 c = string[i];
  160.                 if (c NOTEQUAL linestart
  161.                     AND
  162.                     c NOTEQUAL lineend)
  163.                     putchar(c);
  164.                 END
  165.             putchar('\n');
  166.         END
  167.     END
  168.     dioflush();    
  169. END
  170.  
  171. find(first)
  172. int first;
  173.     BEGIN
  174.     i=0;
  175.     j=first;
  176.     firstpat = first;
  177. loop:
  178.     switch(search())
  179.         BEGIN
  180.         case match:
  181.             if (i  EQUAL 0) firstpat = j;
  182.             i++;
  183.             j++;
  184.             if (pattern[i]  EQUAL 0)
  185.             BEGIN
  186.                 nextpat    = j;
  187.                 if (pattern[0] EQUAL notbegin)
  188.                 firstpat++;
  189.                 if (pattern[strlen(pattern)-1] EQUAL notend)
  190.                 nextpat--;
  191.                 return found;
  192.             END
  193.             if (string[j] EQUAL    0) return notfound;
  194.             goto loop;
  195.             
  196.         case notmatch:
  197.             firstpat++;
  198.             j =    firstpat;
  199.             if (string[j] EQUAL    0) return notfound;
  200.             i =    0;
  201.             goto loop;
  202.             
  203.         case found:
  204.             nextpat = j;
  205.             if (pattern[0] EQUAL notbegin)
  206.             firstpat++;
  207.             if (pattern[strlen(pattern)-1] EQUAL notend)
  208.             nextpat--;
  209.             return found;
  210.             
  211.         case notfound:
  212.             return notfound;
  213.         END
  214. END
  215.  
  216. search()
  217. BEGIN
  218.     int    c,isave;
  219.     switch (pattern[i])
  220.     BEGIN
  221.     case 0:
  222.         return found;
  223.     case anyalpha:
  224.         if (isalpha(string[j]))
  225.             return match;
  226.         else return    notmatch;
  227.     case anynumber:
  228.         if (isdigit(string[j]))
  229.             return match;
  230.         else return    notmatch;
  231.     case anyalpha|0x80:
  232.         if (!isalpha(string[j])
  233.            AND j NOTEQUAL 0
  234.            AND string[j] NOTEQUAL lineend)
  235.            return match;
  236.         else return    notmatch;
  237.     case anynumber|0x80:
  238.         if (!isdigit(string[j])
  239.            AND j NOTEQUAL 0
  240.            AND string[j] NOTEQUAL lineend)
  241.            return match;
  242.         else return    notmatch;
  243.     case skipany:
  244.         i++;
  245.         if (pattern[i] EQUAL 0)
  246.         BEGIN
  247.             j =    strlen(string);
  248.             return found;
  249.         END
  250.         isave = i;
  251. loop:        i =    isave;
  252. loop2:        switch(search())
  253.         BEGIN
  254.             case match:
  255.             i++;
  256.             if (pattern[i] EQUAL 0)
  257.                 BEGIN
  258.                    i--;
  259.                    return match;
  260.                 END
  261.             j++;
  262.             if (string[j] EQUAL 0)
  263.                 BEGIN
  264.                    i--;
  265.                    j--;
  266.                    return notfound;
  267.                 END
  268.             goto loop2;
  269.             case notmatch:
  270.             j++;
  271.             if (string[j] EQUAL 0)
  272.                 BEGIN
  273.                 j--;
  274.                 return notmatch;
  275.                 END
  276.             goto loop;
  277.             case found:
  278.             return found;
  279.             case notfound:
  280.             return notfound;
  281.             END
  282.     case skipone:
  283.         if (string[j] EQUAL    '\n') return notfound;
  284.         if (j EQUAL    0) return notmatch;
  285.         i++;
  286.         j++;
  287.         if (string[j] EQUAL    0) return notfound;
  288.         switch(search())
  289.             BEGIN
  290.             case match:
  291.                 return match;
  292.             case notmatch:
  293.                 j--;
  294.                 return notmatch;
  295.             case found:
  296.                 return found;
  297.             case notfound:
  298.                 return notfound;
  299.             END
  300.     default:
  301.         c =     pattern[i];
  302.         if (c & 0x80)
  303.         BEGIN
  304.         if ((c&0x7f) NOTEQUAL toupper(string[j])
  305.             AND    j NOTEQUAL 0
  306.             AND    string[j] NOTEQUAL lineend)
  307.             return match;
  308.         else return notmatch;
  309.         END
  310.         else
  311.         BEGIN
  312.         if (c EQUAL toupper(string[j]))
  313.             return match;
  314.         else return notmatch;
  315.         END
  316.     END
  317. END
  318.  
  319. setuppat(pat,str)
  320. char *pat;
  321. char *str;
  322. BEGIN
  323. int pi,c;
  324. pi = 0;
  325. while (c = pat[pi++])
  326.     BEGIN
  327.     switch (c)
  328.         BEGIN
  329.         case '*':
  330.             *str++ =  skipany;
  331.             if (pat[pi]    EQUAL '!'
  332.             &&
  333.             pat[pi+1] EQUAL    '}')
  334.                 error("SUB:    *!} not    allowed.");
  335.             break;
  336.         case '?':
  337.             *str++ = skipone;
  338.             break;
  339.         case '}':
  340.             *str++ = lineend;
  341.             if (pat[pi]    NOTEQUAL 0)
  342.             error("SUB: } must be last.");
  343.             break;
  344.         case '{':
  345.            *str++ = linestart;
  346.            if (pi NOTEQUAL 1)
  347.             error("SUB: { must be first.");
  348.            break;
  349.         case '@':
  350.            *str++ = anyalpha;
  351.            break;
  352.         case '#':
  353.            *str++ = anynumber;
  354.            break;
  355.         case '_':
  356.             *str++ = ' ';
  357.             break;
  358.         case '\\':
  359.             c =    pat[pi++];
  360.             if (c EQUAL    0 OR c EQUAL '\n')
  361.     error("SUB: Bad    pattern, \\ requires character following.");
  362.             *str++ = c;
  363.             break;
  364.         case '!':
  365.             c =    pat[pi++];
  366.             if (c < 0x20)
  367.             error("SUB: Bad    pattern    after !.");
  368.             switch(c)
  369.             BEGIN
  370.                 case '*':
  371.                 case '?':
  372.                 case '!':
  373.                 case 0:
  374.                 error ("SUB: Bad pattern after !.");
  375.                 case '}':
  376.                 *str++ = notend;
  377.                 if (pat[pi] NOTEQUAL 0)
  378.                     error("SUB:    !} must    be last.");
  379.                 if (pi EQUAL 2)
  380.                     error("SUB:    No pattern before !}.");
  381.                 break;
  382.                 case '{':
  383.                 *str++ = notbegin;
  384.                 if (pi NOTEQUAL    2)
  385.                     error("SUB:    !{ must    be first.");
  386.                 if (pat[pi] EQUAL 0)
  387.                     error("SUB:    No pattern after !{.");
  388.                 if (pat[pi] EQUAL '*')
  389.                     error("SUB:    !{* not    allowed.");
  390.                 if (pat[pi] EQUAL '!'
  391.                     &&
  392.                     pat[pi+1] EQUAL '}')
  393.                     error("SUB:    !{!} not allowed.");
  394.                 break;
  395.                 case '@':
  396.                 *str++ = anyalpha|0x80;
  397.                 break;
  398.                 case '#':
  399.                 *str++ = anynumber|0x80;
  400.                 break;
  401.                 case '_':
  402.                 *str++ = ' '|0x80;
  403.                 break;
  404.                 case '\\':
  405.                 c = pat[pi++];
  406.                 if (c EQUAL 0 OR c EQUAL '\n' OR c < 0x20)
  407.                 error("SUB:    Bad pattern after !\\.");
  408.                 *str++ = c|0x80;
  409.                 break;
  410.                 default:
  411.                 *str++ = c|0x80;
  412.             END
  413.             break;
  414.            default:
  415.            *str++ = c;
  416.         END
  417.     END
  418.     *str = 0;
  419. END
  420.  
  421. setuprep(pat,str)
  422. char *pat;
  423. char *str;
  424. BEGIN
  425. int c;
  426. while (c = *pat++)
  427.     BEGIN
  428.     switch (c)
  429.         BEGIN
  430.         case '_':
  431.             *str++ = ' ';
  432.             break;
  433.         case '*':
  434.             *str++ = skipany;
  435.             break;
  436.         case '\\':
  437.             c =    *pat++;
  438.             if (c == 0 || c == '\n')
  439.     error("SUB: Bad    replace, \\ requires character following.");
  440.             *str++ = c;
  441.             break;
  442.         case '~':
  443.             c =    *pat++;
  444.             if (!isalpha(c))
  445.     error("SUB: Bad    replace, ~ requires a following    alpha.");
  446.             *str++ = tolower(c);
  447.             break;
  448.            default:
  449.            *str++ = c;
  450.         END
  451.     END
  452.     *str = 0;
  453. END
  454.  
  455. catstr(target,source,any)
  456. char *target,*source,*any;
  457. BEGIN
  458.     char *tempany;
  459.     while (*target) target++;
  460.     while (*source)
  461.     BEGIN
  462.         if (*source    != skipany)
  463.         *target++ = *source++;
  464.         else
  465.         BEGIN
  466.             tempany = any;
  467.             while (*tempany) *target++ = *tempany++;
  468.             source++;
  469.         END
  470.     END
  471.     *target = 0;
  472. END
  473.