home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm86 / trbtol86.lbr / TOOLU.PQS / TOOLU.PAS
Pascal/Delphi Source File  |  1985-10-23  |  13KB  |  681 lines

  1.  
  2. {
  3.         Copyright (c) 1981
  4.         By:     Bell Telephone Laboratories, Inc. and
  5.                 Whitesmith's Ltd.,
  6.  
  7.         This software is derived from the book
  8.                 "Software Tools in Pascal", by
  9.                 Brian W. Kernighan and P. J. Plauger
  10.                 Addison-Wesley, 1981
  11.                 ISBN 0-201-10342-7
  12.  
  13.         Right is hereby granted to freely distribute or duplicate this
  14.         software, providing distribution or duplication is not for profit
  15.         or other commercial gain and that this copyright notice remains
  16.         intact.
  17. }
  18.  
  19. CONST
  20.   IOERROR=0;
  21.   STDIN=1;
  22.   STDOUT=2;
  23.   STDERR=3;
  24. (*IO RELEATED STUFF*)
  25.   MAXOPEN=7;
  26.   IOREAD=0;
  27.   IOWRITE=1;
  28.   MAXCMD=20;
  29.   ENDFILE=255;
  30.   BLANK=32;
  31.   ENDSTR=0;
  32.   MAXSTR=100;
  33.   BACKSPACE=8;
  34.   TAB=9;
  35.   NEWLINE=10;
  36.   EXCLAM=33;
  37.   DQUOTE=34;
  38.   SHARP=35;
  39.   DOLLAR=36;
  40.   PERCENT=37;
  41.   AMPER=38;
  42.   SQUOTE=39;
  43.   ACUTE=SQUOTE;
  44.   LPAREN=40;
  45.   RPAREN=41;
  46.   STAR=42;
  47.   PLUS=43;
  48.   COMMA=44;
  49.   MINUS=45;
  50.   DASH=MINUS;
  51.   PERIOD=46;
  52.   SLASH=47;
  53.   COLON=58;
  54.   SEMICOL=59;
  55.   LESS=60;
  56.   EQUALS=61;
  57.   GREATER=62;
  58.   QUESTION=63;
  59.   ATSIGN=64;
  60.   ESCAPE=ATSIGN;
  61.   LBRACK=91;
  62.   BACKSLASH=92;
  63.   RBRACK=93;
  64.   CARET=94;
  65.   GRAVE=96;
  66.   UNDERLINE=95;
  67.   TILDE=126;
  68.   LBRACE=123;
  69.   BAR=124;
  70.   RBRACE=125;
  71.   
  72. TYPE
  73.    CHARACTER=0..255;
  74.    XSTRING=ARRAY[1..MAXSTR]OF CHARACTER;
  75.   STRING80=string[80];
  76.   FILEDESC=IOERROR..MAXOPEN;
  77.   FILTYP=(CLOSED,STDIO,FIL1,FIL2,FIL3,FIL4);
  78.  
  79. VAR
  80.    KBDN,KBDNEXT:INTEGER;
  81.    KBDLINE:XSTRING;
  82.    CMDARGS:0..MAXCMD;
  83.    CMDIDX:ARRAY[1..MAXCMD] OF 1..MAXSTR;
  84.    CMDLIN:XSTRING;
  85.    CMDLINE:STRING80;
  86.    CMDFIL:ARRAY[STDIN..MAXOPEN]OF FILTYP;
  87.    CMDOPEN:ARRAY[FILTYP]OF BOOLEAN;
  88.    FILE1,FILE2,FILE3,FILE4:TEXT;
  89.    
  90.  
  91.  
  92. FUNCTION GETKBD(VAR C:CHARACTER):CHARACTER;FORWARD;
  93. FUNCTION FGETCF(VAR FIL:TEXT):CHARACTER;FORWARD;
  94. FUNCTION GETCF(VAR C:CHARACTER;FD:FILEDESC):CHARACTER;FORWARD;
  95. FUNCTION GETC(VAR C:CHARACTER):CHARACTER;FORWARD;
  96. PROCEDURE FPUTCF(C:CHARACTER;VAR FIL:TEXT);FORWARD;
  97. PROCEDURE PUTCF(C:CHARACTER;FD:FILEDESC);FORWARD;
  98. PROCEDURE PUTC(C:CHARACTER);FORWARD;
  99. PROCEDURE PUTDEC(N,W:INTEGER);FORWARD;
  100. FUNCTION ITOC(N:INTEGER;VAR S:XSTRING;I:INTEGER):INTEGER;FORWARD;
  101. FUNCTION GETARG(N:INTEGER;VAR S:XSTRING;
  102.   MAXSIZE:INTEGER):BOOLEAN;FORWARD;
  103.   PROCEDURE SCOPY(VAR SRC:XSTRING;I:INTEGER;VAR DEST:XSTRING;J:INTEGER);FORWARD;
  104. PROCEDURE ENDCMD;FORWARD;
  105. PROCEDURE XCLOSE(FD:FILEDESC);FORWARD;
  106. FUNCTION MUSTCREATE(VAR NAME:XSTRING;MODE:INTEGER):
  107. FILEDESC;FORWARD;
  108. FUNCTION CREATE(VAR NAME:XSTRING;MODE:INTEGER):FILEDESC;FORWARD;
  109. FUNCTION XLENGTH(VAR S:XSTRING):INTEGER;FORWARD;
  110. PROCEDURE STRNAME(VAR STR:STRING80;VAR XSTR:XSTRING);FORWARD;
  111. PROCEDURE ERROR(STR:STRING80);FORWARD;
  112. FUNCTION MAX(X,Y:INTEGER):INTEGER;FORWARD;
  113. PROCEDURE REMOVE(NAME:XSTRING);FORWARD;
  114. FUNCTION GETLINE(VAR STR:XSTRING;FD:FILEDESC;
  115.   SIZE:INTEGER):BOOLEAN;FORWARD;
  116.   FUNCTION OPEN(VAR NAME:XSTRING;MODE:INTEGER):
  117. FILEDESC;FORWARD;
  118. FUNCTION FDALLOC:FILEDESC;FORWARD;
  119. FUNCTION FTALLOC:FILTYP;FORWARD;
  120. FUNCTION NARGS:INTEGER;FORWARD;
  121. FUNCTION ADDSTR(C:CHARACTER;VAR OUTSET:XSTRING;
  122.   VAR J:INTEGER;MAXSET:INTEGER):BOOLEAN;FORWARD;
  123. PROCEDURE PUTSTR(STR:XSTRING;FD:FILEDESC);FORWARD;
  124. FUNCTION MUSTOPEN(VAR NAME:XSTRING;MODE:INTEGER):FILEDESC;FORWARD;
  125. FUNCTION MIN(X,Y:INTEGER):INTEGER;FORWARD;
  126. FUNCTION ISUPPER(C:CHARACTER):BOOLEAN;FORWARD;
  127. FUNCTION EQUAL(VAR STR1,STR2:XSTRING):BOOLEAN;FORWARD;
  128. FUNCTION INDEX(VAR S:XSTRING;C:CHARACTER):INTEGER;FORWARD;
  129. FUNCTION ISALPHANUM(C:CHARACTER):BOOLEAN;FORWARD;
  130. FUNCTION ESC(VAR S:XSTRING;VAR I:INTEGER):
  131.      CHARACTER;FORWARD;
  132. PROCEDURE FCOPY(FIN,FOUT:FILEDESC);FORWARD;
  133. FUNCTION CTOI(VAR S:XSTRING;VAR I:INTEGER):INTEGER;FORWARD;
  134. FUNCTION ISDIGIT(C:CHARACTER):BOOLEAN;FORWARD;
  135. FUNCTION ISLOWER(C:CHARACTER):BOOLEAN;FORWARD;
  136. FUNCTION ISLETTER(C:CHARACTER):BOOLEAN;FORWARD;
  137.  
  138. FUNCTION ISDIGIT;
  139. BEGIN
  140.   ISDIGIT:=C IN [ORD('0')..ORD('9')]
  141. END;
  142.  
  143. FUNCTION ISLOWER;
  144. BEGIN
  145.   ISLOWER:=C IN [97..122]
  146. END;
  147.  
  148. FUNCTION ISLETTER;
  149. BEGIN
  150.   ISLETTER:=C IN [65..90]+[97..122]
  151. END;
  152.  
  153. FUNCTION CTOI;
  154. VAR N,SIGN:INTEGER;
  155. BEGIN
  156.   WHILE (S[I]=BLANK) OR (S[I]=TAB)DO
  157.     I:=I+1;
  158.   IF(S[I]=MINUS) THEN
  159.     SIGN:=-1
  160.   ELSE
  161.     SIGN:=1;
  162.   IF(S[I]=PLUS)OR(S[I]=MINUS)THEN
  163.     I:=I+1;
  164.   N:=0;
  165.   WHILE(ISDIGIT(S[I])) DO BEGIN
  166.     N:=10*N+S[I]-ORD('0');
  167.     I:=I+1
  168.   END;
  169.   CTOI:=SIGN*N
  170. END;
  171.  
  172. PROCEDURE FCOPY;
  173. VAR
  174.   C:CHARACTER;
  175. BEGIN
  176.   WHILE(GETCF(C,FIN)<>ENDFILE) DO
  177.     PUTCF(C,FOUT)
  178. END;
  179.  
  180.  
  181.    
  182.  
  183. FUNCTION INDEX;
  184. VAR I:INTEGER;
  185. BEGIN
  186.   I:=1;
  187.   WHILE(S[I]<>C) AND (S[I]<>ENDSTR)DO
  188.     I:=I+1;
  189.   IF (S[I]=ENDSTR) THEN
  190.     INDEX:=0
  191.   ELSE
  192.     INDEX:=I
  193. END;
  194.  
  195. FUNCTION ESC;
  196. BEGIN
  197.   IF(S[I]<>ATSIGN) THEN
  198.     ESC:=S[I]
  199.   ELSE IF(S[I+1]=ENDSTR) THEN (*@ NOT SPECIAL AT END*)
  200.     ESC:=ATSIGN
  201.   ELSE BEGIN
  202.     I:=I+1;
  203.     IF(S[I]=ORD('N'))THEN ESC:=NEWLINE
  204.     ELSE IF (S[I]=ORD('T')) THEN
  205.       ESC:=TAB
  206.     ELSE
  207.       ESC:=S[I]
  208.   END
  209. END;
  210.  
  211. FUNCTION ISALPHANUM;
  212. BEGIN
  213.   ISALPHANUM:=C IN
  214.     [ORD('A')..ORD('Z'),ORD('0')..ORD('9'),
  215.     97..122]
  216. END;
  217.  
  218. FUNCTION MAX;
  219. BEGIN
  220.   IF(X>Y)THEN
  221.     MAX:=X
  222.   ELSE
  223.     MAX:=Y
  224. END;
  225.  
  226.  
  227. FUNCTION MIN;
  228. BEGIN
  229.   IF X<Y THEN
  230.     MIN:=X
  231.   ELSE
  232.     MIN:=Y
  233. END;
  234.  
  235.  
  236. FUNCTION ISUPPER;
  237.   BEGIN
  238.     ISUPPER:=C IN [ORD('A')..ORD('Z')]
  239.   END;
  240.  
  241.  
  242. FUNCTION XLENGTH;
  243. VAR
  244.   N:INTEGER;
  245. BEGIN
  246.   N:=1;
  247.   WHILE(S[N]<>ENDSTR)DO
  248.     N:=N+1;
  249.   XLENGTH:=N-1
  250. END;
  251.  
  252. FUNCTION GETARG;
  253. BEGIN
  254.   IF((N<1)OR(CMDARGS<N))THEN
  255.     GETARG:=FALSE
  256.   ELSE BEGIN
  257.     SCOPY(CMDLIN,CMDIDX[N],S,1);
  258.     GETARG:=TRUE
  259.   END
  260. END;(*GETARG*)
  261.  
  262.  
  263.   PROCEDURE SCOPY;
  264.   BEGIN
  265.     WHILE(SRC[I]<>ENDSTR)DO BEGIN
  266.       DEST[J]:=SRC[I];
  267.       I:=I+1;
  268.       J:=J+1
  269.     END;
  270.     DEST[J]:=ENDSTR;
  271.   END;
  272.   
  273.   
  274.   
  275. (*$I-*)
  276. FUNCTION CREATE;
  277. VAR
  278.   FD:FILEDESC;
  279.   SNM:STRING80;
  280. BEGIN
  281.   FD:=FDALLOC;
  282.   IF(FD<>IOERROR)THEN BEGIN
  283.   STRNAME(SNM,NAME);
  284.   CASE (CMDFIL[FD])OF
  285.   FIL1:
  286.     begin assign(FILE1,SNM);rewrite(FILE1) end;
  287.   FIL2:begin assign(FILE2,SNM);rewrite(FILE2) end;
  288.   FIL3:begin assign(FILE3,SNM);rewrite(FILE3) end;
  289.   FIL4:begin assign(FILE4,SNM);rewrite(FILE4) end
  290.   END;
  291.   IF(IORESULT<>0)THEN BEGIN
  292.     XCLOSE(FD);
  293.     FD:=IOERROR
  294.   END
  295. END;
  296. CREATE:=FD;
  297. END;
  298. (*$I+*)
  299.  
  300. PROCEDURE STRNAME;
  301. VAR I:INTEGER;
  302. BEGIN
  303.   STR:='.PAS';
  304.   I:=1;
  305.   WHILE(XSTR[I]<>ENDSTR)DO BEGIN
  306.     INSERT('X',STR,I);
  307.     STR[I]:=CHR(XSTR[I]);
  308.     I:=I+1
  309.   END
  310. END;
  311. PROCEDURE ERROR;
  312. BEGIN
  313.   WRITELN(STR);
  314.   HALT
  315. END;
  316.  
  317. FUNCTION MUSTCREATE;
  318. VAR
  319.   FD:FILEDESC;
  320. BEGIN
  321.   FD:=CREATE(NAME,MODE);
  322.   IF(FD=IOERROR)THEN BEGIN
  323.     PUTSTR(NAME,STDERR);
  324.     ERROR('  :CAN''T CREATE FILE')
  325.   END;
  326.   MUSTCREATE:=FD
  327. END;
  328.  
  329. FUNCTION NARGS;
  330. BEGIN
  331.   NARGS:=CMDARGS
  332. END;
  333.  
  334. PROCEDURE REMOVE;
  335. VAR
  336.   FD:FILEDESC;
  337. BEGIN
  338.   FD:=OPEN(NAME,IOREAD);
  339.   IF(FD=IOERROR)THEN
  340.   WRITELN('CAN''T REMOVE FILE')
  341.   ELSE BEGIN
  342.     CASE (CMDFIL[FD]) OF
  343.     FIL1:CLOSE(FILE1);
  344.     FIL2:CLOSE(FILE2);
  345.     FIL3:CLOSE(FILE3);
  346.     FIL4:CLOSE(FILE4);
  347.     END
  348.   END;
  349.   CMDFIL[FD]:=CLOSED
  350. END;
  351.  
  352. FUNCTION GETLINE;
  353. VAR I,ii:INTEGER;
  354.     DONE:BOOLEAN;
  355.     CH:CHARACTER;
  356. BEGIN
  357.  I:=0;
  358.  REPEAT
  359.    DONE:=TRUE;
  360.    CH:=GETCF(CH,FD);
  361.    IF(CH=ENDFILE) THEN
  362.      I:=0
  363.    ELSE IF (CH=NEWLINE) THEN BEGIN
  364.      I:=I+1;
  365.      STR[I]:=NEWLINE
  366.    END
  367.    ELSE IF (SIZE-2<=I) THEN BEGIN
  368.      WRITELN('LINE TOO LONG');
  369.      I:=I+1;
  370.      STR[I]:=NEWLINE
  371.    END
  372.    ELSE BEGIN
  373.      DONE:=FALSE;
  374.      I:=I+1;
  375.      STR[I]:=CH;
  376.    END
  377.  UNTIL(DONE);
  378.  STR[I+1]:=ENDSTR;
  379. GETLINE:=(0<I)
  380. END;(*GETLINE*)
  381.  
  382. (*$I-*)
  383. FUNCTION OPEN;
  384. VAR FD:FILEDESC;
  385. SNM:STRING80;
  386. BEGIN
  387.   FD:=FDALLOC;
  388.   IF(FD<>IOERROR) THEN BEGIN
  389.     STRNAME(SNM,NAME);
  390.     CASE (CMDFIL[FD]) OF
  391.     FIL1:begin assign(FILE1,SNM);RESET(FILE1) end;
  392.     FIL2:begin assign(FILE2,SNM);RESET(FILE2) end;
  393.     FIL3:begin assign(FILE3,SNM);RESET(FILE3) end;
  394.     FIL4:begin assign(FILE4,SNM);RESET(FILE4) end
  395.     END;
  396.     IF(IORESULT<>0) THEN BEGIN
  397.       XCLOSE(FD);
  398.       FD:=IOERROR
  399.     END
  400.   END;
  401.   OPEN:=FD
  402. END;
  403. (*$I+*)
  404.  
  405. FUNCTION FTALLOC;
  406. VAR DONE:BOOLEAN;
  407.    FT:FILTYP;
  408. BEGIN
  409.   FT:=FIL1;
  410.   REPEAT
  411.     DONE:=(NOT CMDOPEN[FT] OR (FT=FIL4));
  412.     IF(NOT DONE) THEN
  413.       FT:=SUCC(FT)
  414.   UNTIL (DONE);
  415.   IF(CMDOPEN[FT]) THEN
  416.     FTALLOC:=CLOSED
  417.   ELSE
  418.     FTALLOC:=FT
  419. END;
  420.  
  421. FUNCTION FDALLOC;
  422. VAR DONE:BOOLEAN;
  423. FD:FILEDESC;
  424. BEGIN
  425.   FD:=STDIN;
  426.   DONE:=FALSE;
  427.   WHILE(NOT DONE) DO
  428.     IF((CMDFIL[FD]=CLOSED) OR (FD=MAXOPEN))THEN
  429.       DONE:=TRUE
  430.     ELSE FD:=SUCC(FD);
  431.   IF(CMDFIL[FD]<>CLOSED) THEN
  432.     FDALLOC:=IOERROR
  433.   ELSE BEGIN
  434.     CMDFIL[FD]:=FTALLOC;
  435.     IF(CMDFIL[FD]=CLOSED) THEN
  436.       FDALLOC:=IOERROR
  437.     ELSE BEGIN
  438.       CMDOPEN[CMDFIL[FD]]:=TRUE;
  439.       FDALLOC:=FD
  440.     END
  441.   END
  442. END;(*FDALLOC*)
  443.  
  444.     PROCEDURE ENDCMD;
  445. VAR FD:FILEDESC;
  446. BEGIN
  447.   FOR FD:=STDIN TO MAXOPEN DO
  448.     XCLOSE(FD)
  449. END;
  450.  
  451. PROCEDURE XCLOSE;
  452. BEGIN
  453.   CASE (CMDFIL[FD])OF
  454.   CLOSED,STDIO:;
  455.   FIL1:CLOSE(FILE1);
  456.   FIL2:CLOSE(FILE2);
  457.   FIL3:CLOSE(FILE3);
  458.   FIL4:CLOSE(FILE4)
  459.   END;
  460.   CMDOPEN[CMDFIL[FD]]:=FALSE;
  461.   CMDFIL[FD]:=CLOSED
  462. END;
  463.  
  464. FUNCTION ADDSTR;
  465. BEGIN
  466.   IF(J>MAXSET)THEN
  467.     ADDSTR:=FALSE
  468.   ELSE BEGIN
  469.     OUTSET[J]:=C;
  470.     J:=J+1;
  471.     ADDSTR:=TRUE
  472.   END
  473. END;
  474.  
  475. PROCEDURE PUTSTR;
  476. VAR I:INTEGER;
  477. BEGIN
  478.   I:=1;
  479.   WHILE(STR[I]<>ENDSTR) DO BEGIN
  480.     PUTCF(STR[I],FD);
  481.     I:=I+1
  482.   END
  483. END;
  484. FUNCTION MUSTOPEN;
  485. VAR FD:FILEDESC;
  486. BEGIN
  487.   FD:=OPEN(NAME,MODE);
  488.   IF(FD=IOERROR)THEN BEGIN
  489.     PUTSTR(NAME,STDERR);
  490.     WRITELN(':  CAN''T OPEN FILE')
  491.   END;
  492.   MUSTOPEN:=FD
  493. END;
  494.  
  495. FUNCTION GETKBD;
  496.  
  497. VAR
  498.     DONE:BOOLEAN;
  499.     i:integer;
  500.     ch:char;
  501.  
  502. BEGIN
  503. IF (KBDN<=0)
  504. THEN
  505.     BEGIN
  506.     KBDNEXT:=1;
  507.     DONE:=FALSE;
  508.     if (kbdn=-2)
  509.     then
  510.         begin
  511.         readln;
  512.         kbdn:=0
  513.         end
  514.     else if (kbdn<0)
  515.     then
  516.         done:=true;
  517.     WHILE(NOT DONE)
  518.     DO
  519.         BEGIN
  520.         kbdn:=kbdn+1;
  521.         DONE:=TRUE;
  522.         if (eof(TRM))
  523.         then
  524.             kbdn:=-1
  525.         else if eoln(TRM)
  526.         then
  527.             begin
  528.             kbdline[kbdn]:=NEWLINE;
  529.             readln(TRM);
  530.             end
  531.         else if (MAXSTR-1<=kbdn)
  532.         then
  533.             begin
  534.             writeln('Line too long');
  535.             kbdline[kbdn]:=newline
  536.             end
  537.         ELSE
  538.             begin
  539.             read(TRM,ch);
  540.             kbdline[kbdn]:=ord(ch);
  541.             if (ord(ch)in [0..7,9..12,14..31])
  542.             then
  543.                 write('^',chr(ord(ch)+64))
  544.             else if (kbdline[kbdn]<>BACKSPACE)
  545.             then
  546.                 {do nothing}
  547.             ELSE
  548.                 begin
  549.                 write(ch,' ',ch);
  550.                 if (1<kbdn)
  551.                 then
  552.                     begin
  553.                     kbdn:=kbdn-2;
  554.                     if kbdline[kbdn+1]in[0..31]
  555.                     then
  556.                         write(ch,' ',ch)
  557.                     end
  558.                 ELSE
  559.                     kbdn:=kbdn-1
  560.                 end;
  561.             done:=false
  562.             end;
  563.         END
  564.     END;
  565. reset(TRM);
  566. IF(KBDN<=0)
  567. THEN
  568.     C:=ENDFILE
  569. ELSE
  570.     BEGIN
  571.     C:=KBDLINE[KBDNEXT];
  572.     KBDNEXT:=KBDNEXT+1;
  573.     if (c=NEWLINE)
  574.     then
  575.         begin
  576.         reset(TRM);
  577.         kbdn:=-2;
  578.         end
  579.     ELSE
  580.         KBDN:=KBDN-1
  581.     END;
  582.     GETKBD:=C
  583. END;
  584.  
  585.  FUNCTION FGETCF;
  586.  VAR CH:CHAR;
  587.  BEGIN
  588.    IF(EOF(FIL))THEN
  589.       FGETCF:=ENDFILE
  590.    ELSE IF(EOLN(FIL)) THEN BEGIN
  591.       READLN(FIL);
  592.       FGETCF:=NEWLINE
  593.    END
  594.    ELSE BEGIN
  595.      READ(FIL,CH);
  596.      FGETCF:=ORD(CH);
  597.    END;
  598.  END;
  599.  
  600.  FUNCTION GETCF;
  601.  BEGIN
  602.    CASE(CMDFIL[FD])OF
  603.    STDIO:C:=GETKBD(C);
  604.    FIL1:C:=FGETCF(FILE1);
  605.    FIL2:C:=FGETCF(FILE2);
  606.    FIL3:C:=FGETCF(FILE3);
  607.    FIL4:C:=FGETCF(FILE4);
  608.    END;
  609.  
  610.    GETCF:=C
  611.  END;
  612.  
  613. FUNCTION GETC;
  614. BEGIN
  615.   GETC:=GETCF(C,STDIN)
  616. END;
  617.  
  618.  PROCEDURE FPUTCF;
  619.  BEGIN
  620.   IF(C=NEWLINE)THEN
  621.     WRITELN(FIL)
  622.   ELSE
  623.     WRITE(FIL,CHR(C))
  624. END;
  625.  
  626. PROCEDURE PUTCF;
  627. BEGIN
  628.   CASE (CMDFIL[FD]) OF
  629.   STDIO:FPUTCF(C,CON);
  630.   FIL1:FPUTCF(C,FILE1);
  631.   FIL2:FPUTCF(C,FILE2);
  632.   FIL3:FPUTCF(C,FILE3);
  633.   FIL4:FPUTCF(C,FILE4)
  634.   END
  635. END;
  636.  
  637.  
  638. PROCEDURE PUTC;
  639. BEGIN
  640.   PUTCF(C,STDOUT);
  641. END;
  642.  
  643. FUNCTION ITOC;
  644. BEGIN
  645.   IF(N<0)THEN BEGIN
  646.     S[I]:=ORD('-');
  647.     ITOC:=ITOC(-N,S,I+1);
  648.   END
  649.   ELSE BEGIN
  650.     IF (N>=10)THEN
  651.       I:=ITOC(N DIV 10,S, I);
  652.     S[I]:=N MOD 10 + ORD('0');
  653.     S[I+1]:=ENDSTR;
  654.     ITOC:=I+1;
  655.   END
  656. END;
  657.  
  658. PROCEDURE PUTDEC;
  659. VAR I,ND:INTEGER;
  660.   S:XSTRING;
  661. BEGIN
  662.   ND:=ITOC(N,S,1);
  663.   FOR I:=ND TO W DO
  664.     PUTC(BLANK);
  665.   FOR I:=1 TO ND-1 DO
  666.     PUTC(S[I])
  667. END;
  668.   
  669. FUNCTION EQUAL;
  670. VAR
  671.   I:INTEGER;
  672. BEGIN
  673.   I:=1;
  674.   WHILE(STR1[I]=STR2[I])AND(STR1[I]<>ENDSTR) DO
  675.     I:=I+1;
  676.   EQUAL:=(STR1[I]=STR2[I])
  677. END;
  678.  
  679.  
  680.  
  681.