home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / m2posx14 / src / cstr.ipp < prev    next >
Encoding:
Modula Implementation  |  1994-05-05  |  16.1 KB  |  758 lines

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