home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / TURBTOOL.ARC / TOOLU.PAS < prev   
Pascal/Delphi Source File  |  1989-09-27  |  13KB  |  677 lines

  1.  
  2. {toolu.pas}
  3.  
  4. {
  5.         Copyright (c) 1981
  6.         By:     Bell Telephone Laboratories, Inc. and
  7.                 Whitesmith's Ltd.,
  8.  
  9.         This software is derived from the book
  10.                 "Software Tools in Pascal", by
  11.                 Brian W. Kernighan and P. J. Plauger
  12.                 Addison-Wesley, 1981
  13.                 ISBN 0-201-10342-7
  14.  
  15.         Right is hereby granted to freely distribute or duplicate this
  16.         software, providing distribution or duplication is not for profit
  17.         or other commercial gain and that this copyright notice remains
  18.         intact.
  19. }
  20.  
  21. CONST
  22.   IOERROR=0;
  23.   STDIN=1;
  24.   STDOUT=2;
  25.   STDERR=3;
  26. (*IO RELEATED STUFF*)
  27.   MAXOPEN=7;
  28.   IOREAD=0;
  29.   IOWRITE=1;
  30.   MAXCMD=20;
  31.   ENDFILE=255;
  32.   BLANK=32;
  33.   ENDSTR=0;
  34.   MAXSTR=100;
  35.   BACKSPACE=8;
  36.   TAB=9;
  37.   NEWLINE=10;
  38.   EXCLAM=33;
  39.   DQUOTE=34;
  40.   SHARP=35;
  41.   DOLLAR=36;
  42.   PERCENT=37;
  43.   AMPER=38;
  44.   SQUOTE=39;
  45.   ACUTE=SQUOTE;
  46.   LPAREN=40;
  47.   RPAREN=41;
  48.   STAR=42;
  49.   PLUS=43;
  50.   COMMA=44;
  51.   MINUS=45;
  52.   DASH=MINUS;
  53.   PERIOD=46;
  54.   SLASH=47;
  55.   COLON=58;
  56.   SEMICOL=59;
  57.   LESS=60;
  58.   EQUALS=61;
  59.   GREATER=62;
  60.   QUESTION=63;
  61.   ATSIGN=64;
  62.   ESCAPE=ATSIGN;
  63.   LBRACK=91;
  64.   BACKSLASH=92;
  65.   RBRACK=93;
  66.   CARET=94;
  67.   GRAVE=96;
  68.   UNDERLINE=95;
  69.   TILDE=126;
  70.   LBRACE=123;
  71.   BAR=124;
  72.   RBRACE=125;
  73.   
  74. type
  75.   character=0..255;
  76.   xstring=array[1..MAXSTR] of character;
  77.   string80=string[80];
  78.   filedesc=IOERROR..MAXOPEN;
  79.   filtyp=(CLOSED,STDIO,FIL1,FIL2,FIL3,FIL4);
  80.  
  81. var
  82.    kbdn,kbdnext:integer;
  83.    kbdline:xstring;
  84.    cmdargs:0..MAXCMD;
  85.    cmdidx:array[1..MAXCMD] of 1..MAXSTR;
  86.    cmdlin:xstring;
  87.    cmdline:string80;
  88.    cmdfil:array[STDIN..MAXOPEN] of filtyp;
  89.    cmdopen:array[FILTYP] of boolean;
  90.    file1,file2,file3,file4:text;
  91.  
  92.  
  93. function getkbd(var c:character):character;forward;
  94. function fgetcf(var fil:text):character;forward;
  95. function getcf(var c:character;fd:filedesc):character;forward;
  96. function getc(var c:character):character;forward;
  97. procedure fputcf(c:character;var fil:text);forward;
  98. procedure putcf(c:character;fd:filedesc);forward;
  99. procedure putc(c:character);forward;
  100. procedure putdec(n,w:integer);forward;
  101. function itoc(n:integer;var s:xstring;i:integer):integer;forward;
  102. function getarg(n:integer;var s:xstring;
  103.   maxsize:integer):boolean;forward;
  104. procedure scopy(var src:xstring;i:integer;var dest:xstring;j:integer);forward;
  105. procedure endcmd;forward;
  106. procedure xclose(fd:filedesc);forward;
  107. function mustcreate(var name:xstring;mode:integer):
  108. filedesc;forward;
  109. function create(var name:xstring;mode:integer):filedesc;forward;
  110. function xlength(var s:xstring):integer;forward;
  111. procedure strname(var str:string80;var xstr:xstring);forward;
  112. procedure error(str:string80);forward;
  113. function max(x,y:integer):integer;forward;
  114. procedure remove(name:xstring);forward;
  115. function getline(var str:xstring;fd:filedesc;
  116.   size:integer):boolean;forward;
  117. function open(var name:xstring;mode:integer):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):character;forward;
  131. procedure fcopy(fin,fout:filedesc);forward;
  132. function ctoi(var s:xstring;var i:integer):integer;forward;
  133. function isdigit(c:character):boolean;forward;
  134. function islower(c:character):boolean;forward;
  135. function isletter(c:character):boolean;forward;
  136.  
  137. function isdigit;
  138. begin
  139.   isdigit:=c in [ord('0')..ord('9')]
  140. end;
  141.  
  142. function islower;
  143. begin
  144.   islower:=c in [97..122]
  145. end;
  146.  
  147. function isletter;
  148. begin
  149.   isletter:=c in [65..90]+[97..122]
  150. end;
  151.  
  152. function ctoi;
  153. var n,sign:integer;
  154. begin
  155.   while (s[i]=blank) or (s[i]=tab)do
  156.     i:=i+1;
  157.   if(s[i]=minus) then
  158.     sign:=-1
  159.   else
  160.     sign:=1;
  161.   if(s[i]=plus)or(s[i]=minus)then
  162.     i:=i+1;
  163.   n:=0;
  164.   while(isdigit(s[i])) do begin
  165.     n:=10*n+s[i]-ord('0');
  166.     i:=i+1
  167.   end;
  168.   ctoi:=sign*n
  169. end;
  170.  
  171. procedure fcopy;
  172. var
  173.   c:character;
  174. begin
  175.   while(getcf(c,fin)<>endfile) do
  176.     putcf(c,fout)
  177. end;
  178.  
  179.  
  180.    
  181.  
  182. function index;
  183. var i:integer;
  184. begin
  185.   i:=1;
  186.   while(s[i]<>c) and (s[i]<>endstr)do
  187.     i:=i+1;
  188.   if (s[i]=endstr) then
  189.     index:=0
  190.   else
  191.     index:=i
  192. end;
  193.  
  194. function esc;
  195. begin
  196.   if(s[i]<>atsign) then
  197.     esc:=s[i]
  198.   else if(s[i+1]=endstr) then (*@ not special at end*)
  199.     esc:=atsign
  200.   else begin
  201.     i:=i+1;
  202.     if(s[i]=ord('n'))then esc:=newline
  203.     else if (s[i]=ord('t')) then
  204.       esc:=tab
  205.     else
  206.       esc:=s[i]
  207.   end
  208. end;
  209.  
  210. function isalphanum;
  211. begin
  212.   isalphanum:=c in
  213.     [ord('a')..ord('z'),ord('0')..ord('9'),
  214.     97..122]
  215. end;
  216.  
  217. function max;
  218. begin
  219.   if(x>y)then
  220.     max:=x
  221.   else
  222.     max:=y
  223. end;
  224.  
  225.  
  226. function min;
  227. begin
  228.   if x<y then
  229.     min:=x
  230.   else
  231.     min:=y
  232. end;
  233.  
  234.  
  235. function isupper;
  236.   begin
  237.     isupper:=c in [ord('a')..ord('z')]
  238.   end;
  239.  
  240.  
  241. function xlength;
  242. var
  243.   n:integer;
  244. begin
  245.   n:=1;
  246.   while(s[n]<>endstr)do
  247.     n:=n+1;
  248.   xlength:=n-1
  249. end;
  250.  
  251. function getarg;
  252. begin
  253.   if((n<1)or(cmdargs<n))then
  254.     getarg:=false
  255.   else begin
  256.     scopy(cmdlin,cmdidx[n],s,1);
  257.     getarg:=true
  258.   end
  259. end;(*getarg*)
  260.  
  261.  
  262.   procedure scopy;
  263.   begin
  264.     while(src[i]<>endstr)do begin
  265.       dest[j]:=src[i];
  266.       i:=i+1;
  267.       j:=j+1
  268.     end;
  269.     dest[j]:=endstr;
  270.   end;
  271.   
  272.   
  273.   
  274. (*$I-*)
  275. function create;
  276. var
  277.   fd:filedesc;
  278.   snm:string80;
  279. begin
  280.   fd:=fdalloc;
  281.   if(fd<>ioerror)then begin
  282.   strname(snm,name);
  283.   case (cmdfil[fd])of
  284.   fil1:
  285.     begin assign(file1,snm);rewrite(file1) end;
  286.   fil2:begin assign(file2,snm);rewrite(file2) end;
  287.   fil3:begin assign(file3,snm);rewrite(file3) end;
  288.   fil4:begin assign(file4,snm);rewrite(file4) end
  289.   end;
  290.   if(ioresult<>0)then begin
  291.     xclose(fd);
  292.     fd:=ioerror
  293.   end
  294. end;
  295. create:=fd;
  296. end;
  297. (*$I+*)
  298.  
  299. procedure strname;
  300. var i:integer;
  301. begin
  302.   str:='.pas';
  303.   i:=1;
  304.   while(xstr[i]<>endstr)do begin
  305.     insert('x',str,i);
  306.     str[i]:=chr(xstr[i]);
  307.     i:=i+1
  308.   end
  309. end;
  310. procedure error;
  311. begin
  312.   writeln(str);
  313.   halt
  314. end;
  315.  
  316. function mustcreate;
  317. var
  318.   fd:filedesc;
  319. begin
  320.   fd:=create(name,mode);
  321.   if(fd=ioerror)then begin
  322.     putstr(name,stderr);
  323.     error('  :can''t create file')
  324.   end;
  325.   mustcreate:=fd
  326. end;
  327.  
  328. function nargs;
  329. begin
  330.   nargs:=cmdargs
  331. end;
  332.  
  333. procedure remove;
  334. var
  335.   fd:filedesc;
  336. begin
  337.   fd:=open(name,ioread);
  338.   if(fd=ioerror)then
  339.   writeln('can''t remove file')
  340.   else begin
  341.     case (cmdfil[fd]) of
  342.     fil1:close(file1);
  343.     fil2:close(file2);
  344.     fil3:close(file3);
  345.     fil4:close(file4);
  346.     end
  347.   end;
  348.   cmdfil[fd]:=closed
  349. end;
  350.  
  351. function getline;
  352. var i,ii:integer;
  353.     done:boolean;
  354.     ch:character;
  355. begin
  356.  i:=0;
  357.  repeat
  358.    done:=true;
  359.    ch:=getcf(ch,fd);
  360.    if(ch=endfile) then
  361.      i:=0
  362.    else if (ch=newline) then begin
  363.      i:=i+1;
  364.      str[i]:=newline
  365.    end
  366.    else if (size-2<=i) then begin
  367.      writeln('line too long');
  368.      i:=i+1;
  369.      str[i]:=newline
  370.    end
  371.    else begin
  372.      done:=false;
  373.      i:=i+1;
  374.      str[i]:=ch;
  375.    end
  376.  until(done);
  377.  str[i+1]:=endstr;
  378. getline:=(0<i)
  379. end;(*getline*)
  380.  
  381. (*$I-*)
  382. function open;
  383. var fd:filedesc;
  384. snm:string80;
  385. begin
  386.   fd:=fdalloc;
  387.   if(fd<>ioerror) then begin
  388.     strname(snm,name);
  389.     case (cmdfil[fd]) of
  390.     fil1:begin assign(file1,snm);reset(file1) end;
  391.     fil2:begin assign(file2,snm);reset(file2) end;
  392.     fil3:begin assign(file3,snm);reset(file3) end;
  393.     fil4:begin assign(file4,snm);reset(file4) end
  394.     end;
  395.     if(ioresult<>0) then begin
  396.       xclose(fd);
  397.       fd:=ioerror
  398.     end
  399.   end;
  400.   open:=fd
  401. end;
  402. (*$I+*)
  403.  
  404. function ftalloc;
  405. var done:boolean;
  406.    ft:filtyp;
  407. begin
  408.   ft:=fil1;
  409.   repeat
  410.     done:=(not cmdopen[ft] or (ft=fil4));
  411.     if(not done) then
  412.       ft:=succ(ft)
  413.   until (done);
  414.   if(cmdopen[ft]) then
  415.     ftalloc:=closed
  416.   else
  417.     ftalloc:=ft
  418. end;
  419.  
  420. function fdalloc;
  421. var done:boolean;
  422. fd:filedesc;
  423. begin
  424.   fd:=stdin;
  425.   done:=false;
  426.   while(not done) do
  427.     if((cmdfil[fd]=closed) or (fd=maxopen))then
  428.       done:=true
  429.     else fd:=succ(fd);
  430.   if(cmdfil[fd]<>closed) then
  431.     fdalloc:=ioerror
  432.   else begin
  433.     cmdfil[fd]:=ftalloc;
  434.     if(cmdfil[fd]=closed) then
  435.       fdalloc:=ioerror
  436.     else begin
  437.       cmdopen[cmdfil[fd]]:=true;
  438.       fdalloc:=fd
  439.     end
  440.   end
  441. end;(*fdalloc*)
  442.  
  443.     procedure endcmd;
  444. var fd:filedesc;
  445. begin
  446.   for fd:=stdin to maxopen do
  447.     xclose(fd)
  448. end;
  449.  
  450. procedure xclose;
  451. begin
  452.   case (cmdfil[fd])of
  453.   closed,stdio:;
  454.   fil1:close(file1);
  455.   fil2:close(file2);
  456.   fil3:close(file3);
  457.   fil4:close(file4)
  458.   end;
  459.   cmdopen[cmdfil[fd]]:=false;
  460.   cmdfil[fd]:=closed
  461. end;
  462.  
  463. function addstr;
  464. begin
  465.   if(j>maxset)then
  466.     addstr:=false
  467.   else begin
  468.     outset[j]:=c;
  469.     j:=j+1;
  470.     addstr:=true
  471.   end
  472. end;
  473.  
  474. procedure putstr;
  475. var i:integer;
  476. begin
  477.   i:=1;
  478.   while(str[i]<>endstr) do begin
  479.     putcf(str[i],fd);
  480.     i:=i+1
  481.   end
  482. end;
  483. function mustopen;
  484. var fd:filedesc;
  485. begin
  486.   fd:=open(name,mode);
  487.   if(fd=ioerror)then begin
  488.     putstr(name,stderr);
  489.     writeln(':  can''t open file')
  490.   end;
  491.   mustopen:=fd
  492. end;
  493.  
  494. function getkbd;
  495.  
  496. var
  497.     done:boolean;
  498.     i:integer;
  499.     ch:char;
  500.  
  501. begin
  502. if (kbdn<=0)
  503. then
  504.     begin
  505.     kbdnext:=1;
  506.     done:=false;
  507.     if (kbdn=-2)
  508.     then
  509.         begin
  510.         readln;
  511.         kbdn:=0
  512.         end
  513.     else if (kbdn<0)
  514.     then
  515.         done:=true;
  516.     while(not done)
  517.     do
  518.         begin
  519.         kbdn:=kbdn+1;
  520.         done:=true;
  521.         if (eof(trm))
  522.         then
  523.             kbdn:=-1
  524.         else if eoln(trm)
  525.         then
  526.             begin
  527.             kbdline[kbdn]:=newline;
  528.             readln(trm);
  529.             end
  530.         else if (maxstr-1<=kbdn)
  531.         then
  532.             begin
  533.             writeln('line too long');
  534.             kbdline[kbdn]:=newline
  535.             end
  536.         else
  537.             begin
  538.             read(trm,ch);
  539.             kbdline[kbdn]:=ord(ch);
  540.             if (ord(ch)in [0..7,9..12,14..31])
  541.             then
  542.                 write('^',chr(ord(ch)+64))
  543.             else if (kbdline[kbdn]<>backspace)
  544.             then
  545.                 {do nothing}
  546.             else
  547.                 begin
  548.                 write(ch,' ',ch);
  549.                 if (1<kbdn)
  550.                 then
  551.                     begin
  552.                     kbdn:=kbdn-2;
  553.                     if kbdline[kbdn+1]in[0..31]
  554.                     then
  555.                         write(ch,' ',ch)
  556.                     end
  557.                 else
  558.                     kbdn:=kbdn-1
  559.                 end;
  560.             done:=false
  561.             end;
  562.         end
  563.     end;
  564. reset(trm);
  565. if(kbdn<=0)
  566. then
  567.     c:=endfile
  568. else
  569.     begin
  570.     c:=kbdline[kbdnext];
  571.     kbdnext:=kbdnext+1;
  572.     if (c=newline)
  573.     then
  574.         begin
  575.         reset(trm);
  576.         kbdn:=-2;
  577.         end
  578.     else
  579.         kbdn:=kbdn-1
  580.     end;
  581.     getkbd:=c
  582. end;
  583.  
  584.  function fgetcf;
  585.  var ch:char;
  586.  begin
  587.    if(eof(fil))then
  588.       fgetcf:=endfile
  589.    else if(eoln(fil)) then begin
  590.       readln(fil);
  591.       fgetcf:=newline
  592.    end
  593.    else begin
  594.      read(fil,ch);
  595.      fgetcf:=ord(ch);
  596.    end;
  597.  end;
  598.  
  599.  function getcf;
  600.  begin
  601.    case(cmdfil[fd])of
  602.    stdio:c:=getkbd(c);
  603.    fil1:c:=fgetcf(file1);
  604.    fil2:c:=fgetcf(file2);
  605.    fil3:c:=fgetcf(file3);
  606.    fil4:c:=fgetcf(file4);
  607.    end;
  608.  
  609.    getcf:=c
  610.  end;
  611.  
  612. function getc;
  613. begin
  614.   getc:=getcf(c,stdin)
  615. end;
  616.  
  617.  procedure fputcf;
  618.  begin
  619.   if(c=newline)then
  620.     writeln(fil)
  621.   else
  622.     write(fil,chr(c))
  623. end;
  624.  
  625. procedure putcf;
  626. begin
  627.   case (cmdfil[fd]) of
  628.   stdio:fputcf(c,con);
  629.   fil1:fputcf(c,file1);
  630.   fil2:fputcf(c,file2);
  631.   fil3:fputcf(c,file3);
  632.   fil4:fputcf(c,file4)
  633.   end
  634. end;
  635.  
  636.  
  637. procedure putc;
  638. begin
  639.   putcf(c,stdout);
  640. end;
  641.  
  642. function itoc;
  643. begin
  644.   if(n<0)then begin
  645.     s[i]:=ord('-');
  646.     itoc:=itoc(-n,s,i+1);
  647.   end
  648.   else begin
  649.     if (n>=10)then
  650.       i:=itoc(n div 10,s, i);
  651.     s[i]:=n mod 10 + ord('0');
  652.     s[i+1]:=endstr;
  653.     itoc:=i+1;
  654.   end
  655. end;
  656.  
  657. procedure putdec;
  658. var i,nd:integer;
  659.   s:xstring;
  660. begin
  661.   nd:=itoc(n,s,1);
  662.   for i:=nd to w do
  663.     putc(blank);
  664.   for i:=1 to nd-1 do
  665.     putc(s[i])
  666. end;
  667.   
  668. function equal;
  669. var
  670.   i:integer;
  671. begin
  672.   i:=1;
  673.   while(str1[i]=str2[i])and(str1[i]<>endstr) do
  674.     i:=i+1;
  675.   equal:=(str1[i]=str2[i])
  676. end;
  677.