home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MAGAZINE / MISC / COMP8809.ZIP / SOURCE.EXE / S.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-08-30  |  7.8 KB  |  326 lines

  1. /* s - change string1 into string2
  2. * usage: s string1 [string2]
  3. * special chars : /  - (by itself) null
  4. *                          ? - question mark matches any char
  5. *                          @ matches any letter
  6. *                          # matches any number (0-9)
  7. *                          !@ or !# means not a letter (or number)
  8. *                          ^ matches first char on a line.
  9. *                          $ matches last  char on a line (newline).
  10. *                          /c character c
  11. *                    %c control character c
  12. *                       /n - newline
  13. *                 /t - tab
  14. *                          /f - form feed
  15. *                          /" - single quote (usually stripped by dos)
  16. * if string 2 is null, string 1 is removed from the input
  17. * ex:
  18. *       s abc /n/       - changes all occurences of 'abc' into
  19. *       a newline followed by a space
  20. *       s "abc" " /n " does the same thing.
  21. *       s c?t r?t changes cat to rat, cot to rot, etc.
  22. *    s ?@# #?@ changes +A4 to 4+A , and DA2 to D2A, etc.
  23. * added control characters ver 4.0
  24. * Fri Aug 21 11:38:28 1987
  25. */
  26.   
  27. #include <ctype.h>
  28.  
  29. #include <stdio.h>
  30. #include <copywrit.h>
  31. #define VER "4.0\0"
  32. #define WILD '\376'     /* ascii 254 */
  33. #define NUMBER '\375'
  34. #define LETTER '\374'
  35. #define NOTLETTER '\373'
  36. #define NOTNUMBER '\372'
  37. #define BEGINLINE '\371'
  38. #define ENDLINE '\370'
  39. #define STRMAX 255
  40. #define FALSE 0
  41. #define TRUE !FALSE
  42. #define NUMWILD 7
  43. /* globals */
  44. int i,j=0; char c;
  45. int numwild1,numwild2;
  46. char from[STRMAX], to[STRMAX]; char temp[STRMAX];
  47. /* command line parsing routine */  
  48. /* sinput - change /n into newline, etc */
  49. /* also count wildcard chars */
  50. sinput(s)
  51. char s[];
  52. {
  53.   
  54.   char t[STRMAX]; /* better not be a string longer than STRMAX */
  55.   int i=0; int j=0; int flag;
  56.   int numwild=0;
  57.   while( i < strlen(s))
  58.   {
  59.     flag=FALSE;
  60.     if (i>= strlen(s)) break;
  61.     /* handle negation op */
  62.     if (s[i]=='!' && i<strlen(s))
  63.                            /* negation operator */
  64.     {
  65.       switch (s[++i])
  66.       {
  67.         case '#' :t[j++]=NOTNUMBER;i++;numwild++ ;break;
  68.         case '@' :t[j++]=NOTLETTER;i++;numwild++; break;
  69.   
  70.         default: fprintf(stderr,"sinput: ! ignored\n");
  71.         break;
  72.   
  73.       }
  74.     }
  75.     /* handle control chars */
  76.     if (s[i]=='%' && i<strlen(s))
  77.     {
  78.         t[j++] = s[++i] - 'A'+1; /* make into control character */
  79.      t[j] = NULL;
  80.         i++; /* ready for next char */
  81.      continue;
  82.     }
  83.     if (s[i]!='!')
  84.     {
  85.       if (s[i]=='?')
  86.         { t[j++]=WILD; t[j]=NULL; numwild++ ; i++; }
  87.                  /* beginline */
  88.       else     if (s[i]=='^')
  89.         { t[j++]=BEGINLINE; t[j]=NULL; numwild++ ; i++; }
  90.                  /* endline - any char before a newline */
  91.       else     if (s[i]=='$')
  92.         { t[j++]=ENDLINE; t[j]=NULL; numwild++; i++; }
  93.       else     /* letter wildcard */
  94.         if (s[i]=='@')
  95.           { t[j++]=LETTER; t[j]=NULL; numwild++ ; i++; }
  96.         else
  97.           if (s[i]=='#')
  98.             { t[j++]=NUMBER; t[j]=NULL; numwild++ ; i++; }
  99.           else
  100.             if (s[i] != '/') { t[j++]=s[i++]; t[j]=NULL; }
  101.             else
  102.             {
  103.               flag=(s[i]=='/');
  104.               if (flag)
  105.               {
  106.                 i++;
  107.                 switch (s[i])  {
  108.                   case 'n' : {  t[j]='\n';j++;  i++; } break;
  109.                   case 't' : {  t[j]='\t';j++;  i++; } break;
  110.                   case 'f' : {  t[j]='\014';j++;  i++; } break;
  111.                   case NULL: {  t[j]=' '; j++;  i++; } break;
  112.                   default        : { t[j]=s[i]; j++; i++; } break;
  113.                 }
  114.               
  115.               }
  116.               t[j]=NULL;
  117.             }
  118.     }
  119.   }
  120.   strncpy(s,t,strlen(t));
  121.   s[strlen(t)]=NULL;
  122. /*          printf("%s\n",s); */
  123.   return(numwild);
  124. }
  125. /* skip to the r+1th wildcard of type w in s */
  126. skip(r,s,w)
  127. int r;  char s[]; char w;
  128. {
  129.   int found;
  130.   int cnt=0,i, j;
  131.   if (r>numwild2) r=0;
  132.   found=0;
  133.   j=0;
  134.   while (j<=r)
  135.   {
  136.     for (i=0; i<strlen(s); i++)
  137.     {
  138.       if (s[i]==w)
  139.       { found=1;
  140.         j++;
  141.       }
  142.       if (j>r) break;
  143.     }
  144.     if (!found) return(-1);
  145.   }
  146.   
  147.   return(i);
  148. }
  149. /* firstflag is true if this is the first char read. */
  150. int firstflag=1;
  151.   
  152. ismatch(c,oldc,d)
  153. char c; char oldc; char d;
  154. {    /* see if its an endline (non-newline before a newline) */
  155.   if (d==ENDLINE && (!firstflag && c=='\n' && oldc !='\n'))
  156.     return(1);
  157.   if (d==BEGINLINE &&
  158.     ((c !='\n' && oldc == '\n') || firstflag)) return(1);
  159.   return(c==d | d==WILD | (d==LETTER && isalpha(c))
  160.   | (d==NUMBER && isdigit(c)) |(d==NOTLETTER && !isalpha(c))
  161.   | (d==NOTNUMBER && !isdigit(c)));
  162.   
  163. }
  164.   
  165. iswild(c)
  166. char c;
  167. {
  168.   return(c==WILD | c==LETTER | c==NUMBER
  169.   | c==NOTNUMBER | c==NOTLETTER | c==BEGINLINE | c==ENDLINE);
  170. }
  171. /* sum the first n elts of r */
  172.   
  173. sum(q,n)
  174. int q[]; int n;
  175. { int j,s;
  176.   s=0;
  177.   for (j=1; j<=n;j++)
  178.     s += q[j];
  179.   return(s);
  180. }
  181. replace(i)
  182. int i;
  183. { int j=0,p;     int q[NUMWILD]; int k=0; int f;
  184.   int index;
  185. /* q1 = # of '?' repaced
  186. * q2 = # of '@' replaced
  187. * q3 = # of '#' replaced
  188. * q4 = # of '!@'(not letter)
  189. * q5 = # of '!#'(not number)
  190. * q6 = # of '^' (beginline)
  191. * q7 = # of '$' (endline)
  192. */
  193.   
  194.   for (j=0;j<=NUMWILD;j++)
  195.   {
  196.     q[j]=0;
  197.   }
  198.   f=0;
  199.   for (j=0; j < strlen(to) ; j++)
  200.   
  201.     if (iswild(to[j]) && (sum(q,NUMWILD) < numwild2))
  202.     {    /* if we found a matching wildcard , replace    */
  203.                         /* it, otherwise delete the wild char from 'to' */
  204.       index=0;
  205.       switch (to[j])
  206.       {
  207.         case WILD  : index=1; break;
  208.         case LETTER: index=2; break;
  209.         case NUMBER: index=3; break;
  210.         case NOTLETTER: index=4; break;
  211.         case NOTNUMBER: index=5; break;
  212.         case BEGINLINE: index=6; break;
  213.         case ENDLINE:   index=7; break;
  214.       }
  215.       k=skip(q[index],from,to[j]); q[index]++;
  216.       if (k>=0) to[j]=temp[k];
  217.       else /* remove the non-matching wild char */
  218.         for (k=j-- ; k< (strlen(to)); to[k]=to[k+1],
  219.           k++);
  220.       if (sum(q,NUMWILD)>=numwild2) break;
  221.                         /* now done with translation */
  222.     }
  223. }
  224.   
  225. /* the firstflag flag is global */
  226. translat()
  227. {
  228.   char tmp[STRMAX];
  229.   int i,j,k,l;
  230.   char c=' ';
  231.   char oldc; /* last char read */
  232.   int flag=1; int lastmatch;
  233.   i=0; oldc=c;
  234.   while (c != EOF)
  235.   {
  236.     lastmatch=0;
  237.     strncpy(tmp,to,strlen(to)); tmp[strlen(to)]=NULL;
  238.     if (flag) c=getchar(); else flag=1;
  239.     if (c==EOF) {
  240.       printf("%s",temp);
  241.       break;
  242.     }
  243.     temp[i]=c; temp[i+1]=NULL;
  244.   
  245.     if (ismatch(c,oldc,from[i]))
  246.     {    /* first see if there is a matching 'to' wildcard */
  247.                         /* and replace it */
  248.       replace(i);
  249.       lastmatch=1;
  250.       i++;
  251.       if (i == strlen(from)) { i=0;
  252.       printf("%s",to); flag=1;}
  253.     }
  254.     else
  255.   
  256.         /* not a match. see if it matches first char. */
  257.     {     /* at least one char has matched so far */
  258.       if ((ismatch(c,oldc,from[0])) && i>0 )
  259.       { flag=0;   temp[i]=NULL;
  260.       }
  261.       printf("%s",temp);
  262.       i=0;
  263.     }
  264.     strncpy(to,tmp,strlen(tmp));
  265.     if (firstflag==1) firstflag=0;
  266.     oldc=c;
  267.   }
  268. }
  269. main(argc,argv)
  270.   
  271. int argc;
  272. char *argv[];
  273. {    char *copyright = COPYRIGHT;
  274.   
  275.   fprintf(stderr,"%s\n",copyright);
  276.   if (argc<2)
  277.   {
  278.     printf("usage - %s [pattern1 pattern2]\n",argv[0]);
  279.     printf("vers %s\n",VER);
  280.     exit(0);
  281.   }
  282.   i=strlen(argv[1]);
  283.   strncpy(from,argv[1],i);
  284.   from[i]=NULL;
  285.   
  286.   numwild1=sinput(from);
  287.   if (argc==2) /* replace from by null */
  288.     to[0]=NULL;
  289.   
  290.   else {
  291.     i=strlen(argv[2]);
  292.     strncpy(to,argv[2],i);
  293.     to[i]=NULL;
  294.     numwild2 = sinput(to);
  295.   }
  296.      /* printf("%d and %d ?\n",numwild1,numwild2); */
  297.   translat();
  298. }
  299.   
  300.   
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.