home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / m2posx02 / pstring.ipp < prev    next >
Encoding:
Modula Implementation  |  1993-10-23  |  17.4 KB  |  763 lines

  1. IMPLEMENTATION MODULE pSTRING;
  2. (*__NO_CHECKS__*)
  3. (*****************************************************************************)
  4. (* 14-Feb-93, Holger Kleinschmidt                                            *)
  5. (* --------------------------------------------------------------------------*)
  6. (* STATUS: OK                                                                *)
  7. (*****************************************************************************)
  8.  
  9. VAL_INTRINSIC
  10. CAST_IMPORT
  11.  
  12. FROM types IMPORT
  13. (* CONST*) NULL;
  14.  
  15. FROM CTYPE IMPORT
  16. (* PROC *) TOLOWER, TOUPPER, ISSPACE;
  17.  
  18. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  19.  
  20. CONST
  21. #if no_MIN_MAX
  22.   MAXCARD  = CAST(CARDINAL,-1);
  23. #else
  24.   MAXCARD  = MAX(CARDINAL);
  25. #endif
  26.   NOTFOUND = -1;
  27.  
  28. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  29.  
  30. PROCEDURE SLEN ((* EIN/ -- *) REF s : ARRAY OF CHAR ): CARDINAL;
  31. (*T*)
  32. #if ISOM2 || MM2
  33. BEGIN
  34.  RETURN(LENGTH(s));
  35. #else
  36. VAR i : CARDINAL;
  37. BEGIN
  38.  i := 0;
  39.  WHILE (i <= VAL(CARDINAL,HIGH(s))) AND (s[i] <> EOS) DO
  40.    INC(i);
  41.  END;
  42.  RETURN(i);
  43. #endif
  44. END SLEN;
  45.  
  46. (*---------------------------------------------------------------------------*)
  47.  
  48. PROCEDURE ASSIGN ((* EIN/ -- *) REF src : ARRAY OF CHAR;
  49.                   (* -- /AUS *) VAR dst : ARRAY OF CHAR );
  50. (*T*)
  51. VAR i   : CARDINAL;
  52.     max : CARDINAL;
  53.  
  54. BEGIN
  55.  IF HIGH(src) > HIGH(dst) THEN
  56.    max := VAL(CARDINAL,HIGH(dst));
  57.  ELSE
  58.    max := VAL(CARDINAL,HIGH(src));
  59.  END;
  60.  
  61.  i := 0;
  62.  WHILE (i <= max) AND (src[i] <> EOS) DO
  63.    dst[i] := src[i];
  64.    INC(i);
  65.  END;
  66.  IF i <= VAL(CARDINAL,HIGH(dst)) THEN
  67.    dst[i] := EOS;
  68.  END;
  69. END ASSIGN;
  70.  
  71. (*---------------------------------------------------------------------------*)
  72.  
  73. PROCEDURE CONCAT ((* EIN/ -- *)     s1  : ARRAY OF CHAR;
  74.                   (* EIN/ -- *)     s2  : ARRAY OF CHAR;
  75.                   (* -- /AUS *) VAR dst : ARRAY OF CHAR );
  76. (*T*)
  77. VAR i1, i2 : INTEGER;
  78.     max    : INTEGER;
  79.  
  80. BEGIN
  81.  IF HIGH(s1) > HIGH(dst) THEN
  82.    max := INT(HIGH(dst));
  83.  ELSE
  84.    max := INT(HIGH(s1));
  85.  END;
  86.  
  87.  i1 := 0;
  88.  WHILE (i1 <= max) AND (s1[i1] <> EOS) DO
  89.    dst[i1] := s1[i1];
  90.    INC(i1);
  91.  END;
  92.  
  93.  IF INT(HIGH(s2)) > (INT(HIGH(dst)) - i1) THEN
  94.    max := INT(HIGH(dst)) - i1;
  95.  ELSE
  96.    max := INT(HIGH(s2));
  97.  END;
  98.  
  99.  i2 := 0;
  100.  WHILE (i2 <= max) AND (s2[i2] <> EOS) DO
  101.    dst[i1] := s2[i2];
  102.    INC(i1);
  103.    INC(i2);
  104.  END;
  105.  
  106.  IF i1 <= INT(HIGH(dst)) THEN
  107.    dst[i1] := EOS;
  108.  END;
  109. END CONCAT;
  110.  
  111. (*---------------------------------------------------------------------------*)
  112.  
  113. PROCEDURE iappend (    len : CARDINAL;
  114.                    VAR app : ARRAY OF CHAR;
  115.                    VAR dst : ARRAY OF CHAR );
  116. VAR dIdx : CARDINAL;
  117.     aIdx : CARDINAL;
  118.     max  : CARDINAL;
  119.  
  120. BEGIN
  121.  dIdx := SLEN(dst);
  122.  max  := (VAL(CARDINAL,HIGH(dst)) + 1) - dIdx;
  123.  IF max > len THEN
  124.    max := len;
  125.  END;
  126.  IF max > VAL(CARDINAL,HIGH(app)) THEN
  127.    max := VAL(CARDINAL,HIGH(app)) + 1;
  128.  END;
  129.  
  130.  aIdx := 0;
  131.  WHILE (aIdx < max) AND (app[aIdx] <> EOS) DO
  132.    dst[dIdx] := app[aIdx];
  133.    INC(aIdx);
  134.    INC(dIdx);
  135.  END;
  136.  
  137.  IF dIdx <= VAL(CARDINAL,HIGH(dst)) THEN
  138.    dst[dIdx] := EOS;
  139.  END;
  140. END iappend;
  141.  
  142. (*---------------------------------------------------------------------------*)
  143.  
  144. PROCEDURE APPEND ((* EIN/ -- *)     app : ARRAY OF CHAR;
  145.                   (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  146. (*T*)
  147. BEGIN
  148.  iappend(MAXCARD, app, dst);
  149. END APPEND;
  150.  
  151. (*---------------------------------------------------------------------------*)
  152.  
  153. PROCEDURE APPENDN ((* EIN/ -- *)     len : CARDINAL;
  154.                    (* EIN/ -- *)     app : ARRAY OF CHAR;
  155.                    (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  156. (*T*)
  157. BEGIN
  158.  iappend(len, app, dst);
  159. END APPENDN;
  160.  
  161. (*---------------------------------------------------------------------------*)
  162.  
  163. PROCEDURE APPENDCHR ((* EIN/ -- *)     c   : CHAR;
  164.                      (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  165. (*T*)
  166. VAR dIdx : CARDINAL;
  167.  
  168. BEGIN
  169.  dIdx := SLEN(dst);
  170.  IF dIdx <= VAL(CARDINAL,HIGH(dst)) THEN
  171.    dst[dIdx] := c;
  172.    IF dIdx < VAL(CARDINAL,HIGH(dst)) THEN
  173.      dst[dIdx+1] := EOS;
  174.    END;
  175.  END;
  176. END APPENDCHR;
  177.  
  178. (*---------------------------------------------------------------------------*)
  179.  
  180. PROCEDURE COPY ((* EIN/ -- *)     from : CARDINAL;
  181.                 (* EIN/ -- *)     len  : CARDINAL;
  182.                 (* EIN/ -- *)     src  : ARRAY OF CHAR;
  183.                 (* -- /AUS *) VAR dst  : ARRAY OF CHAR );
  184. (*T*)
  185. VAR  srcLen : CARDINAL;
  186.      cnt    : CARDINAL;
  187.      dIdx   : INTEGER;
  188.      max    : INTEGER;
  189.  
  190. BEGIN
  191.  srcLen := SLEN(src);
  192.  
  193.  IF (len > MAXCARD - from) OR (from + len > srcLen) THEN
  194.    IF from < srcLen THEN
  195.      cnt := srcLen - from;
  196.    ELSE
  197.      cnt := 0;
  198.    END;
  199.  ELSE
  200.    cnt := len;
  201.  END;
  202.  
  203.  IF cnt > VAL(CARDINAL,HIGH(dst)) THEN
  204.    max := INT(HIGH(dst));
  205.  ELSE
  206.    max := CAST(INTEGER,cnt) - 1;
  207.  END;
  208.  
  209.  dIdx := 0;
  210.  WHILE dIdx <= max DO
  211.    dst[dIdx] := src[from];
  212.    INC(dIdx);
  213.    INC(from);
  214.  END;
  215.  
  216.  IF dIdx <= INT(HIGH(dst)) THEN
  217.    dst[dIdx] := EOS;
  218.  END;
  219. END COPY;
  220.  
  221. (*---------------------------------------------------------------------------*)
  222.  
  223. PROCEDURE INSERT ((* EIN/ -- *)     at  : CARDINAL;
  224.                   (* EIN/ -- *)     ins : ARRAY OF CHAR;
  225.                   (* EIN/AUS *) VAR s   : ARRAY OF CHAR );
  226. (*T*)
  227. VAR spc  : INTEGER;
  228.     sLen : INTEGER;
  229.     iLen : INTEGER;
  230.     i    : INTEGER;
  231.  
  232. BEGIN
  233.  sLen := CAST(INTEGER,SLEN(s));
  234.  iLen := CAST(INTEGER,SLEN(ins));
  235.  
  236.  IF at > CAST(CARDINAL,sLen) THEN
  237.    at := sLen;
  238.  END;
  239.  
  240.  spc := (INT(HIGH(s)) + 1 - sLen) - iLen;
  241.  
  242.  IF spc < 0 THEN
  243.    INC(sLen, spc);
  244.    IF INT(HIGH(s)) + 1 - CAST(INTEGER,at) < iLen THEN
  245.      iLen := INT(HIGH(s)) + 1 - CAST(INTEGER,at);
  246.    END;
  247.  ELSIF spc > 0 THEN
  248.    s[sLen+iLen] := EOS;
  249.  END;
  250.  
  251.  FOR i := sLen - 1 TO CAST(INTEGER,at) BY -1 DO
  252.    s[i+iLen] := s[i];
  253.  END;
  254.  
  255.  FOR i := 0 TO iLen - 1 DO
  256.    s[CAST(INTEGER,at)+i] := ins[i];
  257.  END;
  258. END INSERT;
  259.  
  260. (*---------------------------------------------------------------------------*)
  261.  
  262. PROCEDURE DELETE ((* EIN/ -- *)     from : CARDINAL;
  263.                   (* EIN/ -- *)     len  : CARDINAL;
  264.                   (* EIN/AUS *) VAR s    : ARRAY OF CHAR );
  265. (*T*)
  266. VAR strLen : CARDINAL;
  267.  
  268. BEGIN
  269.  strLen := SLEN(s);
  270.  
  271.  IF from < MAXCARD - len THEN
  272.    INC(len, from);
  273.  ELSE
  274.    len := MAXCARD;
  275.  END;
  276.  
  277.  WHILE len < strLen  DO
  278.    s[from] := s[len];
  279.    INC(from);
  280.    INC(len);
  281.  END;
  282.  
  283.  IF from <= VAL(CARDINAL,HIGH(s)) THEN
  284.    s[from] := EOS;
  285.  END;
  286. END DELETE;
  287.  
  288. (*---------------------------------------------------------------------------*)
  289.  
  290. PROCEDURE LOWER ((* EIN/AUS *) VAR s : ARRAY OF CHAR );
  291. (*T*)
  292. VAR i : CARDINAL;
  293.  
  294. BEGIN
  295.  i := 0;
  296.  WHILE (i <= VAL(CARDINAL,HIGH(s))) AND (s[i] <> EOS) DO
  297.    s[i] := TOLOWER(s[i]);
  298.    INC(i);
  299.  END;
  300. END LOWER;
  301.  
  302. (*---------------------------------------------------------------------------*)
  303.  
  304. PROCEDURE UPPER ((* EIN/AUS *) VAR s : ARRAY OF CHAR );
  305. (*T*)
  306. VAR i : CARDINAL;
  307.  
  308. BEGIN
  309.  i := 0;
  310.  WHILE (i <= VAL(CARDINAL,HIGH(s))) AND (s[i] <> EOS) DO
  311.    s[i] := TOUPPER(s[i]);
  312.    INC(i);
  313.  END;
  314. END UPPER;
  315.  
  316. (*---------------------------------------------------------------------------*)
  317.  
  318. PROCEDURE compare (    len : CARDINAL;
  319. #if has_REF
  320.                    REF s1  : ARRAY OF CHAR;
  321.                    REF s2  : ARRAY OF CHAR ): INTEGER;
  322. #else
  323.                    VAR s1  : ARRAY OF CHAR;
  324.                    VAR s2  : ARRAY OF CHAR ): INTEGER;
  325. #endif
  326. CONST less    = -1;
  327.       equal   =  0;
  328.       greater =  1;
  329.  
  330. VAR i   : CARDINAL;
  331.     max : CARDINAL;
  332.     ch  : CHAR;
  333.  
  334. BEGIN
  335.  IF len = 0 THEN
  336.    RETURN(equal);
  337.  ELSE
  338.    DEC(len);
  339.  END;
  340.  IF HIGH(s1) > HIGH(s2) THEN
  341.    max := VAL(CARDINAL,HIGH(s2));
  342.  ELSE
  343.    max := VAL(CARDINAL,HIGH(s1));
  344.  END;
  345.  IF max > len THEN
  346.    max := len;
  347.  END;
  348.  
  349.  i := 0;
  350.  REPEAT
  351.    ch := s1[i];
  352.    IF ch <> s2[i]  THEN
  353.      IF ch < s2[i]  THEN
  354.        RETURN(less);
  355.      ELSE
  356.        RETURN(greater);
  357.      END;
  358.    ELSIF ch = EOS THEN
  359.      RETURN(equal);
  360.    END;
  361.  
  362.    INC(i);
  363.  UNTIL i > max;
  364.  
  365. (* Bis hierher waren die beiden Strings gleich *)
  366.  
  367.  IF max = len THEN
  368.    RETURN(equal);
  369.  ELSIF HIGH(s1) < HIGH(s2) THEN
  370.    (* i <= HIGH(s2) *)
  371.    IF s2[i] = EOS THEN
  372.      RETURN(equal);
  373.    ELSE
  374.      RETURN(less);
  375.    END;
  376.  ELSIF HIGH(s1) > HIGH(s2) THEN
  377.    (* i <= HIGH(s1) *)
  378.    IF s1[i] = EOS  THEN
  379.      RETURN(equal);
  380.    ELSE
  381.      RETURN(greater);
  382.    END;
  383.  ELSE (* HIGH(s1) = HIGH(s2) *)
  384.    RETURN(equal);
  385.  END;
  386. END compare;
  387.  
  388. (*---------------------------------------------------------------------------*)
  389.  
  390. PROCEDURE EQUAL ((* EIN/ -- *) REF s1 : ARRAY OF CHAR;
  391.                  (* EIN/ -- *) REF s2 : ARRAY OF CHAR ): BOOLEAN;
  392. (*T*)
  393. BEGIN
  394.  RETURN(compare(MAXCARD, s1, s2) = 0);
  395. END EQUAL;
  396.  
  397. (*---------------------------------------------------------------------------*)
  398.  
  399. PROCEDURE EQUALN ((* EIN/ -- *)     len : CARDINAL;
  400.                   (* EIN/ -- *) REF s1  : ARRAY OF CHAR;
  401.                   (* EIN/ -- *) REF s2  : ARRAY OF CHAR ): BOOLEAN;
  402. (*T*)
  403. BEGIN
  404.  RETURN(compare(len, s1, s2) = 0);
  405. END EQUALN;
  406.  
  407. (*---------------------------------------------------------------------------*)
  408.  
  409. PROCEDURE COMPARE ((* EIN/ -- *) REF s1 : ARRAY OF CHAR;
  410.                    (* EIN/ -- *) REF s2 : ARRAY OF CHAR ): INTEGER;
  411. (*T*)
  412. BEGIN
  413.  RETURN(compare(MAXCARD, s1, s2));
  414. END COMPARE;
  415.  
  416. (*---------------------------------------------------------------------------*)
  417.  
  418. PROCEDURE COMPAREN ((* EIN/ -- *)     len : CARDINAL;
  419.                     (* EIN/ -- *) REF s1  : ARRAY OF CHAR;
  420.                     (* EIN/ -- *) REF s2  : ARRAY OF CHAR ): INTEGER;
  421. (*T*)
  422. BEGIN
  423.  RETURN(compare(len, s1, s2));
  424. END COMPAREN;
  425.  
  426. (*---------------------------------------------------------------------------*)
  427.  
  428. PROCEDURE LPOS ((* EIN/ -- *)     from : CARDINAL;
  429.                 (* EIN/ -- *) REF pat  : ARRAY OF CHAR;
  430.                 (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  431. (*T*)
  432. VAR sLen  : CARDINAL;
  433.     pLen  : CARDINAL;
  434.     tries : CARDINAL;
  435.     pIdx  : CARDINAL;
  436.  
  437. BEGIN
  438.  sLen := SLEN(s);;
  439.  pLen := SLEN(pat);
  440.  
  441.  IF (pLen = 0) OR (pLen > sLen) OR (from > sLen - pLen) THEN
  442.    RETURN(NOTFOUND);
  443.  ELSE
  444.    tries := sLen - pLen - from;
  445.  END;
  446.  
  447.  LOOP
  448.    pIdx := 0;
  449.    WHILE (pIdx < pLen) AND (s[from] = pat[pIdx]) DO
  450.      INC(from);
  451.      INC(pIdx);
  452.    END;
  453.    DEC(from, pIdx);
  454.  
  455.    IF pIdx = pLen THEN
  456.      RETURN(CAST(INTEGER,from));
  457.    ELSIF tries = 0 THEN
  458.      RETURN(NOTFOUND);
  459.    END;
  460.  
  461.    INC(from);
  462.    DEC(tries);
  463.  END;
  464. END LPOS;
  465.  
  466. (*---------------------------------------------------------------------------*)
  467.  
  468. PROCEDURE RPOS ((* EIN/ -- *)     from : CARDINAL;
  469.                 (* EIN/ -- *) REF pat  : ARRAY OF CHAR;
  470.                 (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  471. (*T*)
  472. VAR sLen  : CARDINAL;
  473.     pLen  : CARDINAL;
  474.     pIdx  : CARDINAL;
  475.  
  476. BEGIN
  477.  sLen := SLEN(s);;
  478.  pLen := SLEN(pat);
  479.  
  480.  IF (pLen = 0) OR (pLen > sLen) THEN
  481.    RETURN(NOTFOUND);
  482.  END;
  483.  IF from > sLen - pLen THEN
  484.    from := sLen - pLen;
  485.  END;
  486.  
  487.  LOOP
  488.    pIdx := 0;
  489.    WHILE (pIdx < pLen) AND (s[from] = pat[pIdx]) DO
  490.      INC(from);
  491.      INC(pIdx);
  492.    END;
  493.    DEC(from, pIdx);
  494.  
  495.    IF pIdx = pLen THEN
  496.      RETURN(CAST(INTEGER,from));
  497.    ELSIF from = 0 THEN
  498.      RETURN(NOTFOUND);
  499.    END;
  500.  
  501.    DEC(from);
  502.  END;
  503. END RPOS;
  504.  
  505. (*---------------------------------------------------------------------------*)
  506.  
  507. PROCEDURE LPOSCHR ((* EIN/ -- *)     from : CARDINAL;
  508.                    (* EIN/ -- *)     c    : CHAR;
  509.                    (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  510. (*T*)
  511. VAR len : CARDINAL;
  512.  
  513. BEGIN
  514.  len := SLEN(s);
  515.  
  516.  WHILE (from < len) AND (s[from] <> c) DO
  517.    INC(from);
  518.  END;
  519.  
  520.  IF from >= len THEN
  521.    RETURN(NOTFOUND);
  522.  ELSE
  523.    RETURN(CAST(INTEGER,from));
  524.  END;
  525. END LPOSCHR;
  526.  
  527. (*---------------------------------------------------------------------------*)
  528.  
  529. PROCEDURE RPOSCHR ((* EIN/ -- *)     from : CARDINAL;
  530.                    (* EIN/ -- *)     c    : CHAR;
  531.                    (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  532. (*T*)
  533. VAR len : CARDINAL;
  534.  
  535. BEGIN
  536.  len := SLEN(s);
  537.  
  538.  IF len = 0 THEN
  539.    RETURN(NOTFOUND);
  540.  ELSIF from >= len THEN
  541.    from := len - 1;
  542.  END;
  543.  
  544.  WHILE (from > 0) AND (s[from] <> c) DO
  545.    DEC(from);
  546.  END;
  547.  IF s[from] = c THEN
  548.    RETURN(CAST(INTEGER,from));
  549.  ELSE
  550.    RETURN(NOTFOUND);
  551.  END;
  552. END RPOSCHR;
  553.  
  554. (*---------------------------------------------------------------------------*)
  555.  
  556. PROCEDURE LPOSCHRSET ((* EIN/ -- *)     from : CARDINAL;
  557.                       (* EIN/ -- *) REF set  : ARRAY OF CHAR;
  558.                       (* EIN/ -- *) REF str  : ARRAY OF CHAR ): INTEGER;
  559. (*T*)
  560. VAR strLen, setLen : CARDINAL;
  561.     setIdx         : CARDINAL;
  562.     c              : CHAR;
  563.  
  564. BEGIN
  565.  strLen := SLEN(str);
  566.  setLen := SLEN(set);
  567.  IF (from >= strLen) OR (setLen = 0) THEN
  568.    RETURN(NOTFOUND);
  569.  END;
  570.  
  571.  LOOP
  572.    c      := str[from];
  573.    setIdx := 0;
  574.    WHILE (setIdx < setLen) AND (c <> set[setIdx]) DO
  575.      INC(setIdx);
  576.    END;
  577.  
  578.    IF setIdx < setLen THEN
  579.      RETURN(CAST(INTEGER,from));
  580.    ELSIF from >= strLen THEN
  581.      RETURN(NOTFOUND);
  582.    ELSE
  583.      INC(from);
  584.    END;
  585.  END;
  586. END LPOSCHRSET;
  587.  
  588. (*---------------------------------------------------------------------------*)
  589.  
  590. PROCEDURE RPOSCHRSET ((* EIN/ -- *)     from : CARDINAL;
  591.                       (* EIN/ -- *) REF set  : ARRAY OF CHAR;
  592.                       (* EIN/ -- *) REF str  : ARRAY OF CHAR ): INTEGER;
  593. (*T*)
  594. VAR strLen, setLen : CARDINAL;
  595.     setIdx         : CARDINAL;
  596.     c              : CHAR;
  597.  
  598. BEGIN
  599.  strLen := SLEN(str);
  600.  setLen := SLEN(set);
  601.  
  602.  IF (setLen = 0) OR (strLen = 0) THEN
  603.    RETURN(NOTFOUND);
  604.  ELSIF from >= strLen THEN
  605.    from := strLen - 1;
  606.  END;
  607.  
  608.  LOOP
  609.    c      := str[from];
  610.    setIdx := 0;
  611.    WHILE (setIdx < setLen) AND (c <> set[setIdx]) DO
  612.      INC(setIdx);
  613.    END;
  614.  
  615.    IF setIdx < setLen THEN
  616.      RETURN(CAST(INTEGER,from));
  617.    ELSIF from = 0 THEN
  618.      RETURN(NOTFOUND);
  619.    ELSE
  620.      DEC(from);
  621.    END;
  622.  END;
  623. END RPOSCHRSET;
  624.  
  625. (*---------------------------------------------------------------------------*)
  626.  
  627. PROCEDURE TOKEN ((* EIN/ -- *)     str   : ARRAY OF CHAR;
  628.                  (* EIN/ -- *)     stop  : ARRAY OF CHAR;
  629.                  (* EIN/AUS *) VAR idx   : CARDINAL;
  630.                  (* EIN/AUS *) VAR l1    : CARDINAL;
  631.                  (* EIN/AUS *) VAR l2    : CARDINAL;
  632.                  (* -- /AUS *) VAR token : ARRAY OF CHAR ): BOOLEAN;
  633. (*T*)
  634. VAR end      : INTEGER;
  635.     min, max : CARDINAL;
  636.     strLen   : CARDINAL;
  637.     stpLen   : CARDINAL;
  638.  
  639. BEGIN
  640.  IF l1 = 0 THEN
  641.    (* Beim ersten Aufruf muessen die Stringlaengen berechnet werden.
  642.     * Sie werden fuer spaetere Aufrufe gemerkt.
  643.     *)
  644.    l1 := SLEN(str);
  645.    l2 := SLEN(stop);
  646.  END;
  647.  strLen := l1;
  648.  stpLen := l2;
  649.  
  650.  min := idx;
  651.  IF (min >= strLen) OR (stpLen = 0) THEN
  652.    (* <str> vollstaendig durchsucht *)
  653.    token[0] := EOS;
  654.    RETURN(FALSE);
  655.  END;
  656.  
  657.  WHILE (min < strLen) AND ISSPACE(str[min]) DO
  658.    (* fuehrende Leerzeichen ueberlesen *)
  659.    INC(min);
  660.  END;
  661.  
  662.  (* abschliessendes Trennzeichen suchen, das fuehrende wurde schon
  663.   * beim letzten Mal ueberlesen, oder es ist das erste Token im String.
  664.   *)
  665.  end := LPOSCHRSET(min, stop, str);
  666.  IF end < 0 THEN
  667.    (* Kein Trennzeichen mehr -> jetzt kommt letztes Token, oder der
  668.     * String ist zuende.
  669.     *)
  670.    max := strLen;
  671.    idx := MAXCARD; (* beim naechsten Mal abbrechen *)
  672.  ELSE
  673.    max := CAST(CARDINAL,end);
  674.    idx := max + 1; (* beim naechsten Mal hinter dem Trenner starten *)
  675.  END;
  676.  
  677.  WHILE (max > min) AND ISSPACE(str[max-1]) DO
  678.    (* abschliessende Leerzeichen ueberlesen *)
  679.    DEC(max);
  680.  END;
  681.  
  682.  (* Token ohne fuehrende und abschliessende Leerzeichen abspeichern *)
  683.  COPY(min, max - min, str, token);
  684.  RETURN(TRUE);
  685. END TOKEN;
  686.  
  687. (*---------------------------------------------------------------------------*)
  688.  
  689. PROCEDURE LenC ((* EIN/ -- *) strC : StrPtr ): CARDINAL;
  690. (*T*)
  691. VAR len : StrRange;
  692.  
  693. BEGIN
  694.  IF (strC = NIL) OR (strC = NULL) THEN
  695.    RETURN(0);
  696.  END;
  697.  len := 0;
  698.  WHILE strC^[len] <> 0C DO
  699.    INC(len);
  700.  END;
  701.  RETURN(VAL(CARDINAL,len));
  702. END LenC;
  703.  
  704. (*---------------------------------------------------------------------------*)
  705.  
  706. PROCEDURE AssignM2ToC ((* EIN/ -- *) strM2 : ARRAY OF CHAR;
  707.                        (* EIN/ -- *) sizeC : StrRange;
  708.                        (* EIN/ -- *) strC  : StrPtr        );
  709. (*T*)
  710. VAR idx : StrRange;
  711.  
  712. BEGIN
  713.  IF (strC = NIL) OR (strC = NULL) THEN
  714.    RETURN;
  715.  END;
  716.  IF sizeC = 0 THEN
  717.    RETURN;
  718.  ELSE
  719.    DEC(sizeC); (* Platz fuer das Nullbyte abziehen *)
  720.  END;
  721.  
  722.  IF VAL(StrRange,HIGH(strM2)) < sizeC THEN
  723.    sizeC := VAL(StrRange,HIGH(strM2)) + 1;
  724.    (* Plus eins, da der M2-String nicht mit einem Nullbyte abgeschlossen sein
  725.     * muss; er kann also bis zum Ende des Feldes gehen.
  726.     *)
  727.  END;
  728.  idx := 0;
  729.  WHILE (idx < sizeC) AND (strM2[idx] <> EOS) DO
  730.    strC^[idx] := strM2[idx];
  731.    INC(idx);
  732.  END;
  733.  strC^[idx] := 0C;
  734. END AssignM2ToC;
  735.  
  736. (*---------------------------------------------------------------------------*)
  737.  
  738. PROCEDURE AssignCToM2 ((* EIN/ -- *)     strC  : StrPtr;
  739.                        (* -- /AUS *) VAR strM2 : ARRAY OF CHAR );
  740. (*T*)
  741. VAR idx : StrRange;
  742.     c   : CHAR;
  743.  
  744. BEGIN
  745.  IF (strC = NIL) OR (strC = NULL) THEN
  746.    strM2[0] := EOS;
  747.    RETURN;
  748.  END;
  749.  idx := 0;
  750.  c   := strC^[0];
  751.  WHILE (idx <= VAL(StrRange,HIGH(strM2))) AND (c <> 0C) DO
  752.    strM2[idx] := c;
  753.    INC(idx);
  754.    c := strC^[idx];
  755.  END;
  756.  IF idx <= VAL(StrRange,HIGH(strM2)) THEN
  757.    strM2[idx] := EOS;
  758.  END;
  759. END AssignCToM2;
  760.  
  761. END pSTRING.
  762.  
  763.