home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / c128 / util / 128c.arc / FIND.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-04  |  7.4 KB  |  396 lines

  1. #INCLUDE <STDIO.H>
  2.  
  3. #DEFINE  ═┴╪╠╔╬┼  256
  4. #DEFINE  ═┴╪╨┴╘   256
  5. #DEFINE  ┼╥╥       -3
  6. #DEFINE  ┘┼╙        1
  7. #DEFINE  ╬╧         0
  8. #DEFINE  ├╠╧╙╒╥┼  '*'
  9. #DEFINE  ├╠╧╙╔┌┼    4
  10. #DEFINE  ├╧╒╬╘      1
  11. #DEFINE  ╙╘┴╥╘      3
  12. #DEFINE  ╨╥┼╓├╠     2
  13. #DEFINE  ╧╦         1
  14.  
  15. #DEFINE  ┼╧╙     '\0'
  16. #DEFINE  ├╚╥      'A'
  17. #DEFINE  ┬╧╠      '%'
  18. #DEFINE  ┼╧╠      '$'
  19. #DEFINE  ┴╬┘      '?'
  20. #DEFINE  ├├╠      '['
  21. #DEFINE  ╬├├╠     'N'
  22. #DEFINE  ├├╠┼╬─   ']'
  23. #DEFINE  ╬╧╘      '!'
  24. #DEFINE  ┼╙├┴╨┼   '@'
  25. #DEFINE  ─┴╙╚     '-'
  26.  
  27. CHAR LINE[═┴╪╠╔╬┼];
  28. CHAR *IRET, *JRET;
  29.  
  30.  
  31. MAIN (ARGC, ARGV)
  32. UNSIGNED ARGC;
  33. CHAR **ARGV;
  34.    STATIC CHAR PAT[═┴╪╨┴╘];
  35.    CHAR *S;
  36.    ╞╔╠┼ FIN;
  37.    INT EXCEPT, NUMBER, PRNAME;
  38.  
  39.    EXCEPT = ╬╧;
  40.    NUMBER = ╬╧;
  41.    PRNAME = ╬╧;
  42.    WHILE (--ARGC && **++ARGV == '-')
  43.       FOR (S = *ARGV + 1; *S; S++)
  44.          SWITCH (*S) █
  45.             CASE 'X':
  46.                  EXCEPT = ┘┼╙;
  47.                  BREAK;
  48.             CASE 'N':
  49.                  NUMBER = ┘┼╙;
  50.                  BREAK;
  51.             CASE 'F':
  52.                  PRNAME = ┘┼╙;
  53.                  BREAK;
  54.             DEFAULT:
  55.                  PRINTF ("FIND: ILLEGAL OPTION %C\N", *S);
  56.                  BREAK;
  57.          ▌
  58.  
  59.    IF (ARGC == 0)
  60.       ERROR ("USAGE: FIND [-X] [-N] [-F] PATTERN");
  61.  
  62.    IF (GETPAT (*ARGV, PAT) == ┼╥╥)
  63.       ERROR ("ILLEGAL PATTERN");
  64.  
  65.    IF (ARGC == 1)
  66.       FIND (STDIN, PAT, EXCEPT, NUMBER, PRNAME, "STDIN");
  67.    ELSE
  68.       WHILE (--ARGC) █
  69.          IF ((FIN = FOPEN (*++ARGV, "R")) == ╬╒╠╠ ▀▀ FERROR()) █
  70.             PRINTF ("CAN'T OPEN %S\N", *ARGV);
  71.             EXIT();
  72.          ▌
  73.          FIND (FIN, PAT, EXCEPT, NUMBER, PRNAME, *ARGV);
  74.          FCLOSE (FIN);
  75.       ▌
  76.  
  77. FIND (FIN, PAT, EXCEPT, NUMBER, PRNAME, NAME)
  78. ╞╔╠┼ FIN;
  79. CHAR *PAT, *NAME;
  80.    INT LINENO = 0;
  81.  
  82.    WHILE (FGETS(LINE, ═┴╪╠╔╬┼, FIN) != ╬╒╠╠) █
  83.       LINENO++;
  84.       IF (MATCH(LINE, PAT) != EXCEPT) █
  85.          IF (PRNAME)
  86.             PRINTF ("%S: ", NAME);
  87.          IF (NUMBER)
  88.             PRINTF ("%D: ", LINENO);
  89.          FPUTS (LINE, STDOUT);
  90.          ▌
  91.       ▌
  92.  
  93. ERROR(S)
  94. CHAR *S;
  95.    PUTS(S);
  96.    EXIT();
  97.  
  98. MATCH (LIN, PAT)
  99. CHAR *LIN, *PAT;
  100.    FOR (; *LIN; LIN++)
  101.       IF (AMATCH (LIN, PAT))
  102.          RETURN (┘┼╙);
  103.    RETURN (╬╧);
  104.  
  105. AMATCH (LIN, PAT)
  106. CHAR *LIN, *PAT;
  107.    CHAR *I, *J, *OFFSET, *STACK;
  108.  
  109.    STACK = PAT - 1;
  110.    OFFSET = LIN;
  111.    FOR (J=PAT; *J; J += PATSIZ(J))
  112.       IF (*J == ├╠╧╙╒╥┼) █
  113.          STACK = J;
  114.          J += ├╠╧╙╔┌┼;
  115.          FOR (I=OFFSET; *I; I=IRET)
  116.             IF (OMATCH (I, J) == ╬╧)
  117.                BREAK;
  118.          *(STACK + ├╧╒╬╘) = I - OFFSET;
  119.          *(STACK + ╙╘┴╥╘) = OFFSET - LIN;
  120.          OFFSET = I;
  121.          ▌
  122.       ELSE IF (OMATCH (OFFSET, J) == ╬╧) █
  123.          FOR (; STACK >= PAT; STACK = PAT + *(STACK+╨╥┼╓├╠) - 1)
  124.             IF (*(STACK + ├╧╒╬╘) > 0)
  125.                BREAK;
  126.          IF (STACK < PAT)
  127.             RETURN (0);
  128.          (*(STACK + ├╧╒╬╘))--;
  129.          J = STACK + ├╠╧╙╔┌┼;
  130.          OFFSET = LIN + *(STACK+╙╘┴╥╘) + *(STACK+├╧╒╬╘);
  131.          ▌
  132.       ELSE
  133.          OFFSET = IRET;
  134.    RETURN (OFFSET - LIN + 1);
  135.  
  136. PATSIZ(N)
  137. CHAR *N;
  138.    SWITCH (*N) █
  139.       CASE ├╚╥:
  140.          RETURN 2;
  141.       CASE ┬╧╠:
  142.       CASE ┼╧╠:
  143.       CASE ┴╬┘:
  144.          RETURN 1;
  145.       CASE ├├╠:
  146.       CASE ╬├├╠:
  147.          RETURN *(N+1) + 2;
  148.       CASE ├╠╧╙╒╥┼:
  149.          RETURN ├╠╧╙╔┌┼;
  150.       DEFAULT:
  151.          ERROR ("IN PATSIZ: CAN'T HAPPEN");
  152.    ▌
  153.  
  154. OMATCH (I, J)
  155. CHAR *I, *J;
  156.    INT BUMP;
  157.  
  158.    IRET = I;
  159.    IF (*I == '\0')
  160.       RETURN ╬╧;
  161.    BUMP = -1;
  162.    SWITCH (*J) █
  163.       CASE ├╚╥:
  164.          IF (*I == *(J+1))
  165.             BUMP = 1;
  166.          BREAK;
  167.       CASE ┬╧╠:
  168.          IF (I == LINE)
  169.             BUMP = 0;
  170.          BREAK;
  171.       CASE ┴╬┘:
  172.          IF (*I != '\N')
  173.             BUMP = 1;
  174.          BREAK;
  175.       CASE ┼╧╠:
  176.          IF (*I == '\N')
  177.             BUMP = 0;
  178.          BREAK;
  179.       CASE ├├╠:
  180.          IF (LOCATE(*I, J+1))
  181.             BUMP = 1;
  182.          BREAK;
  183.       CASE ╬├├╠:
  184.          IF (*I != '\N' && LOCATE(*I,J+1) == ╬╧)
  185.             BUMP = 1;
  186.          BREAK;
  187.       DEFAULT:
  188.          ERROR ("IN OMATCH: CAN'T HAPPEN");
  189.    ▌
  190.    IF (BUMP >= 0) █
  191.       IRET = I + BUMP;
  192.       RETURN ┘┼╙;
  193.    ▌
  194.    RETURN ╬╧;
  195.  
  196. LOCATE (C, OFFSET)
  197. CHAR *OFFSET;
  198.    CHAR *I;
  199.  
  200.    FOR (I=OFFSET+*OFFSET; I>OFFSET; I--)
  201.       IF (*I == C)
  202.          RETURN ┘┼╙;
  203.    RETURN ╬╧;
  204.  
  205. GETPAT (ARG, PAT)
  206. CHAR *ARG, *PAT;
  207.    RETURN (MAKPAT(ARG, ┼╧╙, PAT));
  208.  
  209. MAKPAT (FROM, DELIM, PAT)
  210. CHAR *FROM, *PAT;
  211.    CHAR *I, *J, *LASTJ, *LJ, *ADDSET();
  212.    INT LASTCL;
  213.  
  214.    J = PAT;
  215.    LASTJ = PAT;
  216.    LASTCL = 0;
  217.    FOR (I=FROM; *I; I++) █
  218.       LJ = J;
  219.       IF (*I == ┴╬┘)
  220.          J = ADDSET (┴╬┘, J);
  221.       ELSE IF (*I == ┬╧╠ && I == FROM)
  222.          J = ADDSET (┬╧╠, J);
  223.       ELSE IF (*I == ┼╧╠ && *(I+1)==DELIM)
  224.          J = ADDSET (┼╧╠, J);
  225.       ELSE IF (*I == ├├╠) █
  226.          INT TMP;
  227.          TMP = GETCCL (I, J);
  228.          I = IRET;
  229.          J = JRET;
  230.          IF (TMP == ┼╥╥)
  231.             BREAK;
  232.          ▌
  233.       ELSE IF (*I == ├╠╧╙╒╥┼ && I > FROM) █
  234.          LJ = LASTJ;
  235.          IF (*LJ == ┬╧╠ ▀▀ *LJ == ┼╧╠ ▀▀ *LJ == ├╠╧╙╒╥┼)
  236.             BREAK;
  237.          LASTCL = STCLOS (PAT, J, LASTJ, LASTCL);
  238.          J = JRET;
  239.          LASTJ = IRET;
  240.          ▌
  241.       ELSE █
  242.          J = ADDSET (├╚╥, J);
  243.          J = ADDSET (ESC(I), J);
  244.          I = IRET;
  245.          ▌
  246.       LASTJ = LJ;
  247.       ▌
  248.    IF (*I != DELIM)
  249.       RETURN ┼╥╥;
  250.    ADDSET (┼╧╙, J);
  251.    RETURN ╧╦;
  252.  
  253. GETCCL (I, J)
  254. CHAR *I, *J;
  255.    CHAR *ADDSET(), *FILSET();
  256.    CHAR *JSTART;
  257.  
  258.    IF (*++I == ╬╧╘) █
  259.       J = ADDSET (╬├├╠, J);
  260.       I++;
  261.       ▌
  262.    ELSE
  263.       J = ADDSET (├├╠, J);
  264.    JSTART = J;
  265.    J = ADDSET (0, J);
  266.    J = FILSET (├├╠┼╬─, I, J);
  267.    I = IRET;
  268.    *JSTART = J - JSTART - 1;
  269.    JRET = J;
  270.    IF (*I == ├├╠┼╬─)
  271.       RETURN ╧╦;
  272.    RETURN ┼╥╥;
  273.  
  274. STCLOS (PAT, J, LASTJ, LASTCL)
  275. CHAR *PAT, *J, *LASTJ;
  276.    CHAR *JP, *ADDSET();
  277.  
  278.    FOR (JP=J-1; JP >= LASTJ; JP--)
  279.       ADDSET (*JP, JP+├╠╧╙╔┌┼);
  280.    J += ├╠╧╙╔┌┼;
  281.    JP = LASTJ;
  282.    LASTJ = ADDSET (├╠╧╙╒╥┼, LASTJ);
  283.    LASTJ = ADDSET (0, LASTJ);
  284.    LASTJ = ADDSET (LASTCL, LASTJ);
  285.    LASTJ = ADDSET (0, LASTJ);
  286.    JRET = J;
  287.    IRET = LASTJ;
  288.    RETURN (JP - PAT + 1);
  289.  
  290. CHAR *FILSET (DELIM, I, J)
  291. CHAR *I, *J;
  292.    STATIC CHAR DIGITS[] = "0123456789";
  293.    STATIC CHAR LOWALF[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  294.    STATIC CHAR UPALF[]  = "┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌";
  295.    CHAR *ADDSET();
  296.    UNSIGNED INDEX();
  297.  
  298.    FOR (; *I != DELIM && *I != ┼╧╙; I++)
  299.       IF (*I == ┼╙├┴╨┼) █
  300.          J = ADDSET (ESC(I), J);
  301.          I = IRET;
  302.          ▌
  303.       ELSE IF (*I != ─┴╙╚)
  304.          J = ADDSET (*I, J);
  305.       ELSE IF (INDEX (DIGITS, *(J-1)) > 0) █
  306.          DODASH (DIGITS, I, J);
  307.          I = IRET;
  308.          J = JRET;
  309.          ▌
  310.       ELSE IF (INDEX (LOWALF, *(J-1)) > 0) █
  311.          DODASH (LOWALF, I, J);
  312.          I = IRET;
  313.          J = JRET;
  314.          ▌
  315.       ELSE IF (INDEX (UPALF, *(J-1)) > 0) █
  316.          DODASH (UPALF, I, J);
  317.          I = IRET;
  318.          J = JRET;
  319.          ▌
  320.       ELSE
  321.          J = ADDSET (─┴╙╚, J);
  322.       IRET = I;
  323.       RETURN J;
  324.  
  325. ESC(I)
  326. CHAR *I;
  327.    IRET = I;
  328.    IF (*I != ┼╙├┴╨┼)
  329.       RETURN *I;
  330.    IF (*(I+1) == ┼╧╙)
  331.       RETURN ┼╙├┴╨┼;
  332.    IRET = ++I;
  333.    IF (*I == 'N')
  334.       RETURN '\N';
  335.    RETURN *I;
  336.  
  337. DODASH (VALID, I, J)
  338. CHAR *VALID, *I, *J;
  339.    UNSIGNED K, LIMIT, INDEX();
  340.  
  341.    I++;
  342.    J--;
  343.    LIMIT = INDEX (VALID, ESC(I));
  344.    FOR (K = INDEX(VALID, *J); K <= LIMIT; K++)
  345.       J = ADDSET (VALID[K-1], J);
  346.    JRET = J;
  347.  
  348. CHAR *ADDSET (C, J)
  349. CHAR *J;
  350.    *J++ = C;
  351.    RETURN J;
  352.  
  353. UNSIGNED INDEX (STR, C)
  354. CHAR *STR;
  355.    CHAR *I;
  356.  
  357.    FOR (I = STR; *I; I++)
  358.       IF (*I == C)
  359.          RETURN (I - STR + 1);
  360.    RETURN 0;
  361.  
  362.