home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pasos2b.zip / lib / iolib.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-03  |  29KB  |  939 lines

  1. (*
  2.  * FileName:   iolib.pas
  3.  * $Source: E:/usr/src/c-code/pascal/RCS/LIB/iolib.pas,v $
  4.  * $Author: wjw $
  5.  * $Date: 1993/11/03 15:55:00 $
  6.  * $Locker: wjw $
  7.  * $State: Exp $
  8.  * $Revision: 1.1 $
  9.  * Description:
  10. D*      Part of the runtime library which comes with PASCAL for OS/2
  11. D*      
  12.  *
  13.  * History:
  14.  *      First created by Willem Jan Withagen ( wjw@eb.ele.tue.nl ),
  15.  *                    on Mon July 26 23:30:03 MET 1993
  16.  * Copyright:
  17.  *      Copyright (c) 1993 by Willem Jan Withagen and 
  18.  *                      Digital Information Systems group, TUE
  19.  *      For copying and distribution information see the file COPYRIGHT.
  20.  *
  21.  *)
  22.  
  23. program iolib;
  24. (* MODULE paslib; *)
  25.  
  26. (* Once this all will be transformed into the PASCAL runtime lib.
  27. (* Currently it is included in every file being translated.
  28. (* And it s being run through the preprocessor first, which does not know
  29. (* about pascal comments. So be carefull with ''s.
  30. (*
  31. (* Notes/limitations:
  32. (*   OS/2:
  33. (*      Maybe I should know beter, but I''m using native OS/2 calls. (wjw)
  34. (*
  35. (*   File I/O:
  36. (*      Although the compiler knows about files, currently the only files 
  37. (*      known are output for writes, input for read. And these are hard coded
  38. (*      into the routines
  39. (*      The runtime lib itself can use file handle 2 as 'stderr'.
  40. (*       
  41. (*      Upon input we assume that input lines are less than 256 chars.
  42. (*      Otherwise routines will break.
  43. (*
  44. (*   Standard routines:
  45. (*      The standard routines are Currently generated by the backend with TWO
  46. (*      leading $''s in the name. This means that here we should only use ONE,
  47. (*      the second one gets added by the compiler.
  48. (*
  49. (*   Local Routines:
  50. (*      Routines to be used only in this module have a '_' prepended to their
  51. (*      name. 
  52. (*
  53. (*   Coding:
  54. (*   1) I''m trying to code this a simple as possible. The reason for this is 
  55. (*      that is library is also used to run the compiler testfiles. And if 
  56. (*      things are hairy in the lib, then it is hard to figure out where the 
  57. (*      real errors are. (And currently WITH-stat are not implemented, so 
  58. (*      complex records do not serve any purpose.)
  59. (*   2) Also is the alignment of local data done manually, since there is
  60. (*      still a bug(read not implemented) in the local allocation.
  61. (*   3) Sets are neither implemented
  62. (*   4) So are CASE-statements.
  63.  *)
  64. #include "os2.inc"
  65.  
  66. const
  67.     _stdin              = 0;
  68.         _in                 = 0;
  69.     _stdout             = 1;
  70.         _out                = 1;
  71.     _stderr             = 2;
  72.         _error              = 2;
  73.     _Boolean_Write_Size = 5;
  74.         _MAX_BUF            = 256;
  75.     _MinInt             = -2147483648;
  76.         _InitMagic          = 168101130;   (* 0xa55a5aa5 *)
  77.  
  78. #ifndef DEBUG_IOLIB
  79.     _fill_char          = ' ';
  80. #else
  81.     _fill_char          = '.';
  82. #endif    
  83.  
  84. type
  85.     intp = ^integer;
  86.     _filebuf   = array[1.._Max_buf] of char;
  87.         _bigbuf    = array[1.._Max_buf] of char;
  88.     _filedescr = record
  89.             bufpoint    :_word;     (* By making this a pointer to the first 
  90.                                     (* available item, file^ is still usuable 
  91.                                      *)
  92.             handle      :_word;
  93.             fname       :_filename; (* The name of the file when opened.*)
  94.             namelen     :_word;
  95.             bufstart    :_word;
  96.             bufend      :_word;
  97.             elemsize    :_word;
  98.             fileopen    :Boolean;
  99.             fileinp     :Boolean;
  100.             filetxt     :Boolean;
  101.             bufempty    :Boolean;
  102.             bufeoln     :Boolean;
  103.             bufeof      :Boolean;
  104.             IsTTY       :Boolean;
  105.             Initialised :_word;     (* contains magic if it was already inited *)
  106.             (* Initialised means that there is a valid name in the descriptor *)
  107.             
  108.             (* The buffer is always at the end that way is it possibe to
  109.             (* vary its size with the type it wants to write
  110.              *)
  111.             buffer   :_filebuf;
  112.         end;
  113. var 
  114.     (* Files to operate on *)
  115.         _in_descr  :_filedescr;
  116.         _out_descr :_filedescr;
  117.         _err_descr :_filedescr;
  118.     
  119. procedure _Int2Str(i: integer; Var buf :_bigbuf; Var size: _word); forward;
  120.  
  121. procedure ErrorLib(VAR s :_str; i :_word);
  122. var
  123.     _rc    :_word;
  124.     rcnt   :_word;
  125.     buffer :_bigbuf;
  126. begin
  127.      with _err_descr
  128.      do
  129.        begin
  130.           _rc := Dos32Write( handle, s, i, rcnt)
  131.          ;Buffer[1] := CR
  132.          ;Buffer[2] := LF
  133.          ;_rc := Dos32Write( handle, Buffer, 2, rcnt)
  134.        end
  135. end;
  136.  
  137. procedure ErrorLibCode(VAR s :_str; i :_word; code: _word);
  138. var
  139.     _rc    :_word;
  140.     rcnt   :_word;
  141.     size   :integer;
  142. begin
  143.      with _err_descr
  144.      do
  145.        begin
  146.          ;_rc := Dos32Write( handle, s, i, rcnt)
  147.          ;_Int2Str(code, Buffer, size)
  148.          ;_rc := Dos32Write( handle, Buffer, size, rcnt)
  149.          ;Buffer[1] := CR
  150.          ;Buffer[2] := LF
  151.          ;_rc := Dos32Write( handle, Buffer, 2, rcnt)
  152.        end
  153. end;
  154.  
  155. (* I/O *)
  156. procedure $DumpHandle(VAR lfile :Text; f :_filedescr);
  157. (*  Dump the status of the file in 'f' on the list file 'lf'
  158.  *)
  159. var
  160.    length :_word;
  161. begin
  162.   with f
  163.   do
  164.     begin
  165.       (* bufpoint :_word;     (* By making this a pointer to the first 
  166.                            (* available item, file^ is still usuable 
  167.                             *)
  168.       ;writeln( 'handle =    ', handle)
  169.       ;writeln( 'fname =     ', fname:namelen)
  170.       ;writeln( 'buffer =   |', buffer:bufend, '|')
  171.       ;writeln( 'bufstart =  ', bufstart)
  172.       ;writeln( 'bufend   =  ', bufend  )
  173.       ;writeln( 'elemsize =  ', elemsize)
  174.       ;writeln( 'fileopen =  ', fileopen)
  175.       ;writeln( 'fileinp  =  ', fileinp )
  176.       ;writeln( 'filetxt  =  ', filetxt )
  177.       ;writeln( 'bufempty =  ', bufempty)
  178.       ;writeln( 'bufeoln  =  ', bufeoln )
  179.       ;writeln( 'bufeof   =  ', bufeof  )
  180.       ;writeln( 'IsTTY    =  ', IsTTY   )
  181.     end
  182. end;
  183.  
  184. procedure _FlushWriteBuffer(VAR f :_filedescr);
  185. (* Some thing might be in the buffer which still has to be written.
  186.  *)
  187. var
  188.     _rc
  189.    ,rcnt     :_word;
  190. begin
  191.   with f
  192.   do 
  193.     begin
  194.       if (Bufstart < BufEnd)
  195.       then
  196.         begin
  197.            _rc := Dos32Write( handle, Buffer, Bufend-BufStart, rcnt)
  198.           ;if _rc <> 0
  199.            then ErrorLibCode('Error in _FlushWriteBuffer    ', 30, _rc)
  200.           ;Bufstart := 1
  201.           ;Bufend   := Bufstart
  202.           ;Bufpoint := $StrAddr(Buffer)
  203.           ;Bufempty := True
  204.         end
  205.     end
  206. end;
  207.  
  208. procedure $StdPut(VAR f :_filedescr);
  209. var
  210.     _rc, rcnt :_word;
  211. begin
  212.   with f
  213.   do 
  214.    if filetxt
  215.    then
  216.      begin
  217.        if (Bufend < _MAX_BUF)
  218.        then
  219.          begin
  220.            Bufend   := Bufend+1
  221.           ;Bufpoint := BufPoint+1
  222.           ;Bufempty := False
  223.         end
  224.      end
  225.    else
  226.      begin
  227.        (* Its a binary file *)
  228.        _rc := Dos32Write(handle, buffer, elemsize, rcnt)
  229.      end
  230. end;
  231.  
  232. procedure $StdWriteBin(Var f :_filedescr; Var from :_str);
  233. begin
  234.     (* First copy the current contents *)
  235.     $memcopy(from, f.buffer, f.elemsize)
  236.     (* Then put new data *)
  237.    ;$StdPut(f)
  238. end;  (* $StdWriteBin *)
  239.  
  240. procedure $StdWriteln(Var f :_filedescr);
  241. var
  242.     _rc  :_word;              (* the result of the latest OS operation *)
  243.     rcnt :_word;
  244. begin
  245.   _FlushWriteBuffer(f)
  246.  ;with f
  247.   do 
  248.     begin
  249.        Buffer[1] := CR
  250.       ;Buffer[2] := LF
  251.       ;_rc := Dos32Write( f.handle, Buffer, 2, rcnt)
  252.       ;if _rc <> 0
  253.        then ErrorLib('Error in StdWriteln           ', 30)
  254.     end
  255. end;
  256.  
  257. procedure _WriteSpace(Var f:_filedescr; SpaceSize: integer);
  258. (*  Write the requested number of spaces.
  259. (*  It could be done a little more efficient.
  260. (*  Note that it requires the buffer to be flushed first.
  261. (*  This is not done here.
  262. (*  It uses it''s own private buffer, since the file buffer 
  263. (*  could be holding somethiing
  264.  *)
  265. var 
  266.     _rc    : _word;              (* the result of the latest OS operation *)
  267.     rcnt   :_word;
  268.     count  :integer;
  269.     locbuf :_bigbuf;
  270. begin
  271.   with f
  272.   do 
  273.     begin
  274.       ;for count := 1 to SpaceSize
  275.        do  locbuf[count] := ' '
  276.       ;_rc := Dos32Write( handle, locBuf, SpaceSize, rcnt)
  277.       ;if _rc <> 0
  278.        then ErrorLib('Error in _WriteSpace          ', 30)
  279.     end
  280. end;
  281.  
  282. procedure $StdWriteChar(Var f:_filedescr; c: char; WrtSize: integer);
  283. (*  Print the specified CHAR c on F. 
  284. (*  It has to be printed in a WrtSize area.
  285. (*  [6.9.3.2] specifies that spaces should be added to the front of the written
  286. (*            character.
  287.  *)
  288. var
  289.     _rc  : _word;              (* the result of the latest OS operation *)
  290.     rcnt :_word;
  291. begin
  292.    _FlushWriteBuffer(f)
  293.   ;if WrtSize <> 1
  294.      then
  295.         begin  (* add spaces *)
  296.            ;_WriteSpace(f,WrtSize-1)
  297.         end
  298.     ;with f
  299.      do 
  300.        begin
  301.           Buffer[1] := c
  302.          ;_rc := Dos32Write( handle, Buffer, 1, rcnt)
  303.          ;if _rc <> 0
  304.           then ErrorLib('Error in $StdWriteChar        ', 30)
  305.        end
  306. end;
  307.  
  308. procedure $StdWriteString(Var f:_filedescr; Var s: _str; StrSize, WrtSize: integer);
  309. (*  Print the specified string on F. The allocated size of the string is
  310. (*  StrSize. 
  311. (*  It has to be printed in a WrtSize area.
  312. (*  [6.9.3.6] specifies that spaces should be added to the end of the written
  313. (*            string.
  314.  *)
  315. var
  316.     _rc  : _word;              (* the result of the latest OS operation *)
  317.     rcnt :_word;
  318. begin
  319.    _FlushWriteBuffer(f)
  320.   ;if WrtSize <= StrSize
  321.       then
  322.         begin  (* Use WrtSize since this is at most the actual string length *)
  323.            _rc := Dos32Write( f.handle, s, WrtSize, rcnt)
  324.           ;if _rc <> 0
  325.            then ErrorLib('Error in $StdWriteString      ', 30)
  326.         end
  327.       else
  328.         begin  (* Give the full string, and add spaces *)
  329.             _rc := Dos32Write( f.handle, s, StrSize, rcnt)
  330.            ;if _rc <> 0
  331.             then ErrorLib('Error in $StdWriteString      ', 30)
  332.            ;_WriteSpace(f,WrtSize-StrSize)
  333.         end
  334. end;
  335.  
  336. procedure $StdWriteBoolean(Var f:_filedescr; b: boolean; WrtSize: integer);
  337. (*  Print the Boolean b c on F. 
  338. (*  It has to be printed in a WrtSize area.
  339. (*  [6.9.3.5] specifies that spaces should be added to the front of the written
  340. (*            character.
  341.  *)
  342. var
  343.     rcnt :_word;
  344. begin
  345.    _FlushWriteBuffer(f)
  346.   ;if WrtSize > _Boolean_Write_Size
  347.      then
  348.          begin  (* add spaces *)
  349.             _WriteSpace(f,WrtSize-_Boolean_Write_Size)
  350.          end
  351.      (* Now write the string *)   
  352.     ;if b then $StdWriteString(f, 'True',  4 ,WrtSize)
  353.           else $StdWriteString(f, 'False', 5 ,WrtSize)
  354. end; (* $StdWriteBoolean *)
  355.  
  356. procedure _Int2Str(i: integer; Var buf :_bigbuf; Var size: _word);
  357. const
  358.     base = 10;
  359. var
  360.     index                   (* point to where the next char has to be stored *)
  361.    ,j         : Integer;
  362.     Negative  : Boolean;
  363. begin
  364.    (* first, store backwards the character representation of Abs(I) in Buf *)
  365.    (* MinInt is a number value which can only be represented when it is 
  366.         * negative. As such it is not possibe to use the algorithm below *)
  367.    size := 0
  368.   ;if I = _MinInt
  369.      then
  370.        begin 
  371.           Buf := '-2147483648'
  372.          ;size := 11
  373.        end
  374.      else
  375.        begin
  376.          if I = 0 
  377.            then
  378.              begin 
  379.                 index := _Max_buf-1
  380.                ;Buf[_Max_buf] := '0' 
  381.              end
  382.            else
  383.              begin
  384.                 Negative := (I < 0)
  385.                ;if Negative 
  386.                 then I := -I              (* This doesn''t work if I is MinInt *)
  387.                ;index := _Max_buf           (* Start at the end of the buffer *)
  388.                ;while I > 0 do
  389.                   begin
  390.                      Buf[index] := Chr (I MOD Base + Ord('0')) 
  391.                     ;index := index - 1 
  392.                     ;I := I DIV Base 
  393.                   end
  394.                ;if Negative 
  395.                 then
  396.                    (* Insert a leading minus *)
  397.                    begin 
  398.                       Buf[index] := '-' 
  399.                      ;index := index - 1
  400.                    end
  401.             end
  402.          (* now, write it out 
  403.          (* The first character is at Buf[index+1] uptil Buf[_Max_buf]
  404.           *)
  405.         ;size := _Max_buf - index
  406.         ;for j := 1 to size    
  407.          do  Buf[j] := Buf[index+j]
  408.      end
  409. end; (* _Int2Str *)
  410.  
  411. procedure $StdWriteInt(Var f:_filedescr; i: integer; WrtSize: integer);
  412. const
  413.     base = 10;
  414. var 
  415.     _rc       : _word;              (* the result of the latest OS operation *)
  416.     size      : Integer;
  417.     rcnt      : _word;
  418. begin
  419.    _FlushWriteBuffer(f)
  420.   ;_Int2Str(i, f.buffer, size)
  421.   ;if size < WrtSize
  422.    then _WriteSpace(f,WrtSize-size)
  423.   ;_rc := Dos32Write( f.handle, f.Buffer, size, rcnt)
  424.   ;if _rc <> 0
  425.    then ErrorLibCode('Error in $StdWriteInteger     ', 30, _rc)
  426.  
  427. end; (* $StdWriteInt *)
  428.  
  429. procedure _CheckBufEOLN(VAR f:_Filedescr); forward;
  430.  
  431. procedure _FillReadBuf(VAR f :_filedescr);
  432. (*  Read a line at the time into Buffer, but only when the last item is
  433. (*  consumed:
  434. (*    Bufempty OR (Bufstart = Bufend+1)
  435. (*  Do not care for CR/LF combinations. If they occur they should be truncated 
  436. (*  to just CR.
  437.  *)
  438. var
  439.     _rc  : _word;              (* the result of the latest OS operation *)
  440.     rcnt : _word;
  441. begin
  442.   with f do
  443.     begin
  444.       if bufeof 
  445.       then 
  446.         begin
  447.           ErrorLib('File already at EOF           ', 30)
  448.          ;_rc := Dos32Exit(1,-1)
  449.         end
  450.      ;if bufstart > bufend
  451.       then 
  452.         begin
  453.           ErrorLib('File pointers are corrupt.    ', 30)
  454.          ;_rc := Dos32Exit(1,-1)
  455.         end
  456.      ;if Bufempty OR (Bufstart = Bufend)
  457.       then
  458.         (* Need to read new data into buffer *)
  459.         begin
  460.            _rc := Dos32Read(handle, Buffer, _Max_buf, rcnt)
  461.           ;if _rc <> 0
  462.            then ErrorLibCode('Error in _FillReadBuf         ', 30, _rc)
  463.           ;bufeof   := rcnt = 0
  464.           ;bufempty := rcnt = 0
  465.           ;BufPoint := $StrAddr(Buffer)
  466.           ;Bufstart := 1
  467.           ;Bufend   := Bufstart+rcnt
  468.           ;_CheckBufEOLN(f)
  469.         end
  470.     end
  471. end; (* _FillReadBuf(VAR f :_filedescr); *)
  472.  
  473. procedure _CheckBufEOLN(VAR f:_Filedescr);
  474. (*  Fix the current buffer contents.
  475. (*  If there is a CR/LF combination in the buffer make shure that the
  476. (*  f^ returns a ' '. and that eoln is set.
  477.  *)
  478. begin
  479.     with f
  480.     do
  481.       begin
  482.         ;bufeoln  := (Buffer[Bufstart] = CR) OR (Buffer[Bufstart] = LF)
  483.         ;if (bufeoln)
  484.          then
  485.            begin
  486.               BufStart := bufstart +1
  487.              ;Bufpoint := bufpoint +1
  488.              ;_FillReadBuf(f)         (* Make shure there''s enough *)
  489.              ;Buffer[Bufstart] := ' ' (* Kill the LF *)
  490.            end
  491.       end     
  492. end;
  493.            
  494. procedure $StdGet(VAR f :_filedescr);
  495. (*  Advance the pointer for the _filedescr.
  496. (*  Currently only implemented for Text files. (or files with byte size 
  497. (*  elements.)
  498. (*  Note that $StdGet() will skip eoln''s without hesitation.
  499.  *)
  500. var
  501.     _rc, rcnt :_word;
  502.  
  503. begin
  504.  ;with f do
  505.     if filetxt
  506.     then
  507.       begin
  508.         Bufstart := Bufstart+1
  509.        ;BufPoint := BufPoint+1
  510.        ;_FillReadBuf(f)
  511.        ;_CheckBufEOLN(f)
  512.       end
  513.     else
  514.       begin
  515.         (* Get from a binary file *)
  516.         _rc := Dos32Read(handle, buffer, elemsize, rcnt)
  517.        ;if _rc <> 0
  518.         then ErrorLibCode('Error in StdGet for bin file. ', 30, _rc)
  519.        ;bufeof := rcnt = 0
  520.       end
  521. end; (* $StdGet(f :_filedescr); *)
  522.  
  523. procedure $StdReadBin(Var f :_filedescr; VAR dest :_str);
  524. begin
  525.     (* First copy the current contents *)
  526.     $memcopy(f.buffer, dest, f.elemsize)
  527.     (* Then get new data *)
  528.    ;$StdGet(f)
  529. end;  (* $StdReadBin *)
  530.  
  531. procedure $StdReadln(Var f :_filedescr);
  532. (* Flush anything on the current line 
  533. (* including the current EOLN.
  534.  *)
  535. var
  536.     rcnt :_word;
  537.     done :Boolean;
  538. begin
  539.    with f do
  540.      begin
  541.        done := bufeoln OR bufeof
  542.       ;while not done
  543.        do
  544.          begin
  545.            $StdGet(f)
  546.           ;done := bufeoln OR bufeof
  547.          end
  548.       ;if bufeoln
  549.        then
  550.          begin
  551.            (* Only need to go to the next character 
  552.            (* That is sort of hard since the buffering requires the
  553.            (* next line to be entered as well. Maybe a diffentiation on
  554.            (* terminal input should be done. Especially if we''re going to 
  555.            (* implement something as TURBO''s keypressed.
  556.             *)
  557.            $StdGet(f)
  558.          end
  559.      end
  560. end;
  561.  
  562. function $StdEoln(Var f:_filedescr):Boolean;
  563. begin
  564.     if not (f.bufeof or f.bufeoln)
  565.     then _FillReadBuf(f)
  566.    ;$StdEoln := f.bufeoln;
  567. end; (* $StdEoln *)
  568.  
  569. function $Stdeof(Var f:_filedescr):Boolean;
  570. (* Check if it is really at end of file *)
  571. begin
  572.     if f.filetxt AND not f.bufeof
  573.     then _FillReadBuf(f)
  574.    ;$Stdeof := f.bufeof
  575. end; (* $StdEoln *)
  576.  
  577. procedure $StdReadChar(Var f:_filedescr; Var c: char);
  578. (*  Read a character from 'f' into 'c'.
  579. (*  The end of line character gets treated like a ' '
  580.  *)
  581. begin
  582.    (* Now copy the data into the request string *)
  583.    _FillReadBuf(f)
  584.   ;c := f.buffer[f.bufstart]
  585.   ;$StdGet(f)
  586. end;  (* $StdReadChar *)
  587.  
  588. procedure $StdReadString(Var f:_filedescr; Var s: _str; ReadSize: integer);
  589. (*  Read text from 'f' into 's'.
  590. (*  The maximum number to read is ReadSize characters.
  591. (*  If less than ReadSize characters are recieved, 
  592. (*     OR the input buffer has EOLN
  593. (*  then the remainder of the buffer is filled with spaces
  594.  *)
  595. var
  596.     count : integer;
  597. begin
  598.   count := 1
  599.  ;with f do
  600.   begin
  601.      _FillReadBuf(f)
  602.      (* Now copy the data into the request string *)
  603.     ;while (count < ReadSize) 
  604.            and not $Stdeoln(f) 
  605.            and not $Stdeof(f)
  606.      do
  607.        begin
  608.          s[count] := buffer[bufstart]
  609.         ;count := count+1
  610.         ;$StdGet(f)
  611.        end
  612.      (* Fill the remainder with chr(0) chars *)
  613.     ;while (count < Readsize)   
  614.      do
  615.        begin
  616.          s[count] := chr(0)
  617.         ;count    := count+1
  618.        end
  619.   end           
  620. end;      (* $StdReadString *)
  621.  
  622. procedure $StdReadInt(Var f:_filedescr; Var i: integer);
  623. (*  Read integer from 'f' into 'i'.
  624. (*  Characters are read from Buffer until it is exhausted or it is
  625. (*  not a digit any longer.
  626. (*  [6.9.1.c]  if V is a variable-access possessing the interger-type (or 
  627. (*     subrange thereof), read(f,v) shall cause the reading from f of a 
  628. (*     sequence of charaters, Preceding spaces and end-of-lines shall be 
  629. (*      skipped. It shall be an error if the rest of the sequence does not 
  630. (*      form a signed-integer according to the the syntax of 6.5.1. Reading 
  631. (*      shall cease as soon as the buffer-variable f^ does not have attributed 
  632. (*      to it a character contained by the signed-integer. The value of the 
  633. (*      signed-integer thus read shall be assignment-compatible with the type 
  634. (*      possessed by V, and shall be attributed to v.
  635. (*  NB: In no circumstances is ReadInt allowed to skip EOLN or EOF after it 
  636. (*      has found an initial part of the integer.
  637. (*      
  638.  *)
  639. var
  640.     _rc      : _word;              (* the result of the latest OS operation *)
  641.     j        : integer;
  642.     c        : char;
  643.     Sign     : integer;
  644. begin
  645.      _FillReadBuf(f)
  646.      (* Set the default return value *)
  647.     ;i    := 0
  648.     ;Sign := 1
  649.      (* Is there anything in the buffer? *)
  650.     ;with f do
  651.       begin
  652.         ;If NOT bufeof
  653.          then
  654.            begin
  655.              (* First skip white space *)
  656.              while (Buffer[BufStart] = ' ')
  657. (*                   AND NOT bufeof *)
  658.              do
  659.                begin
  660.                  $StdGet(f)
  661.                end
  662.              (* determine the sign *)
  663.             ;if (Buffer[BufStart] = '-')
  664.              then Sign := -1
  665.             ;if (Sign = -1) OR (Buffer[BufStart] = '+')
  666.              then 
  667.                begin
  668.                  $StdGet(f)
  669.                end
  670.              (* Now get the number *)
  671.             ;if ('0' <= Buffer[BufStart]) AND (Buffer[BufStart] <= '9')
  672.              then
  673.                begin
  674.                  (* Go get all numbers *)
  675.                  i := (ord(Buffer[BufStart])-ord('0'))
  676.                 ;$StdGet(f)
  677.                 ;while ('0' <= Buffer[BufStart]) AND (Buffer[BufStart] <= '9')
  678.                  do
  679.                    begin
  680.                       (* We ignore overflow *)
  681.                       i := i*10 + (ord(Buffer[BufStart])-ord('0'))
  682.                      ;$StdGet(f)
  683.                    end
  684.                end
  685.              else
  686.                begin
  687.                  writeln('Buffer = |',Buffer[BufStart],'|')
  688.                 ;ErrorLib('No integer found              ', 30     )
  689.                end
  690.              (* Now apply the sign *) 
  691.             ;i := i * Sign
  692.            end
  693.          else
  694.            ErrorLib('No integer found(EOF)         ', 30     )
  695.       end 
  696. end;
  697.  
  698. procedure $StdAssign(Var f: _filedescr; name :_filename; maxstr :_word);
  699. (* The PASCAL file 'f' has to be linked to the OS-file called 'name'
  700. (* The maximumsize of the string is maxstr. But the name coudl either
  701. (* be terminated by a ' ' or a '\0'
  702. (* Only the file is not opened yet, since we don''t know what is going on
  703. (* for reading or writting.
  704.  *)
  705. var
  706.     _rc   :_word;
  707.     i     :integer;
  708.     ended :boolean;
  709. begin
  710.      i:=1
  711.     ;ended := false
  712.     ;with f 
  713.      do
  714.        while( NOT ended)
  715.        do
  716.          begin
  717.             fname[i] := name[i]
  718.            ;ended := (name[i] = ' ') or (name[i] = chr(0)) or (i >= maxstr)
  719.            ;I := I+1
  720.          end
  721.      (* Just terminate for OS/2 *)
  722.     ;f.fname[i]    := chr(0)
  723.     ;f.namelen     := i
  724.     ;f.initialised := _InitMagic
  725.     ;f.handle      := -1
  726. end;
  727.  
  728. procedure $StdReset(Var f: _filedescr;
  729.                       name :_str; namesize :_word;
  730.                       textfile :Boolean; size :_word
  731.                       );
  732. (*  Open the file with the descriptor for reading, and start at the beginning 
  733. (*  of the file.
  734.  *)
  735. var
  736.     _rc     :_word;
  737.     result  :_word;
  738.     hdltype, dummy :_word;
  739. begin
  740.   with f
  741.   do
  742.     begin
  743.        if (Initialised <> _InitMagic)
  744.           OR (    (handle <> _stdin)
  745.               AND (handle <> _stdout)
  746.               AND (handle <> _stderr))
  747.        then
  748.          begin
  749.            if initialised <> _InitMagic
  750.            then
  751.              begin
  752.                 $memcopy(name,fname,namesize)
  753.                ;namelen := namesize
  754.              end
  755.            else
  756.              begin
  757.                 (* Make shure the file was closed, then open it.
  758.                 (* but only if it was not one of the standard files
  759.                  *)
  760.                 if handle <> -1
  761.                 then _rc := Dos32Close(handle)
  762.               end
  763.            ;_rc := Dos32Open(fname,handle,result,0,FILE_NORMAL
  764.                             ,OPEN_ACTION_FAIL_IF_NEW+OPEN_ACTION_OPEN_IF_EXISTS
  765.                             ,OPEN_ACCESS_READONLY+OPEN_SHARE_DENYNONE
  766.                              +OPEN_FLAGS_NOINHERIT+OPEN_FLAGS_SEQUENTIAL
  767.                             ,OPEN_NO_EA_BUF
  768.                             )
  769.            ;if(_rc <> 0) 
  770.             then
  771.               writeln('StdReset(',__LINE__:1,'): Error in Dos32Open: rc = ', _rc)
  772.             else
  773.               begin
  774.                  if initialised <> _InitMagic
  775.                  then
  776.                    begin
  777.                       $memcopy(name,fname,namesize)
  778.                      ;namelen := namesize
  779.                    end
  780.                 ;bufstart := 1
  781.                 ;bufpoint := $StrAddr(buffer)
  782.                 ;Bufend   := bufstart 
  783.                 ;Bufempty := True
  784.                 ;elemsize := size
  785.                 ;Fileopen := True
  786.                 ;FileTxt := textfile
  787.                 ;Bufeoln  := False
  788.                 ;Bufeof   := False
  789.                 ;_rc := Dos32QueryHType(handle,hdltype,dummy)
  790.                 ;isTTY    := textfile AND 
  791.                       (HANDLE_TYPE_CHAR_DEV = $AndWord(hdltype,HANDLE_TYPE_DEV_MASK))
  792.                  (* Is it allowed to prefetch the buffer ? *)     
  793.                 ;if not isTTY
  794.                  then
  795.                      $StdGet(f)
  796.                 ;Initialised := _InitMagic
  797.               end
  798.           end
  799.      end
  800. end;
  801.  
  802. procedure $StdRewrite(Var f: _filedescr; 
  803.                       name :_str; namesize :_word;
  804.                       textfile :Boolean; size :_word
  805.                       );
  806. (*  Open the file with the descriptor for writing, and start at the beginning 
  807. (*  of the file.
  808.  *)
  809. var
  810.     _rc    :_word;
  811.     result :_word;
  812.     hdltype, dummy :_word;
  813. begin
  814.   with f
  815.   do
  816.     begin
  817.       ;if (Initialised <> _InitMagic)
  818.           OR (    (handle <> _stdin)
  819.               AND (handle <> _stdout)
  820.               AND (handle <> _stderr))
  821.        then
  822.          begin
  823.            if initialised <> _InitMagic
  824.            then
  825.              begin
  826.                 $memcopy(name,fname,namesize)
  827.                ;namelen := namesize
  828.              end
  829.            else
  830.              begin
  831.                 (* Make shure the file was closed, then open it.
  832.                 (* but only if it was not one of the standard files
  833.                  *)
  834.                 if handle <> -1
  835.                 then _rc := Dos32Close(handle)
  836.               end
  837.            ;_rc := Dos32open(fname,handle,result,0,FILE_NORMAL
  838.                             ,OPEN_ACTION_CREATE_IF_NEW+OPEN_ACTION_REPLACE_IF_EXISTS
  839.                             ,OPEN_ACCESS_WRITEONLY+OPEN_SHARE_DENYNONE
  840.                              +OPEN_FLAGS_NOINHERIT+OPEN_FLAGS_SEQUENTIAL
  841.                             ,OPEN_NO_EA_BUF
  842.                             )
  843.            ;if(_rc <> 0) 
  844.             then
  845.               writeln('StdReset(',__LINE__:1,'): Error in Dos32Open: rc = ', _rc)
  846.             else
  847.               with f
  848.               do
  849.                 begin
  850.                   ;bufstart := 1
  851.                   ;bufpoint := $StrAddr(buffer)
  852.                   ;Bufend   := bufstart 
  853.                   ;Bufempty := True
  854.                   ;elemsize := size
  855.                   ;Fileopen := True
  856.                   ;Fileinp  := False
  857.                   ;Filetxt  := textfile
  858.                   ;Bufeoln  := False
  859.                   ;Bufeof   := False
  860.                   ;_rc := Dos32QueryHType(handle,hdltype,dummy)
  861.                   ;isTTY    := textfile AND 
  862.                         (HANDLE_TYPE_CHAR_DEV = $AndWord(hdltype,HANDLE_TYPE_DEV_MASK))
  863.                 end
  864.          end
  865.     end                
  866. end; (* StdRewrite *)
  867.  
  868. procedure _TextInit(VAR f :_filedescr; hdl :_word; 
  869.                     name :_str; namesize :_word;
  870.                     forinput, opened :Boolean
  871.                      );
  872. (* Initialise the descriptor with handle 'hdl' as being a Text mode descriptor
  873. (* Either for in/output as described by the second parameter
  874. (* It could also be a file already opened by the system.
  875.  *)
  876. var
  877.    _rc, hdltype, dummy :_word;
  878. begin
  879.      with f do
  880.      begin
  881.          $memcopy(name,fname,namesize)
  882.         ;namelen   := namesize
  883.         ;handle    := hdl
  884.         ;bufstart  := 1
  885.         ;Bufend    := bufstart
  886.         ;BufPoint  := $StrAddr(buffer)
  887.         ;elemsize  := 1
  888.         ;Bufempty  := True
  889.         ;Fileopen  := opened
  890.         ;fileinp   := forinput
  891.         ;filetxt   := True
  892.         ;Bufeoln   := False
  893.         ;Bufeof    := False
  894.          (* This assumes that these handles are opened already *)
  895.         ;_rc       := Dos32QueryHType(hdl,hdltype,dummy)
  896.         ;isTTY     := HANDLE_TYPE_CHAR_DEV =
  897.                            $AndWord(hdltype,HANDLE_TYPE_DEV_MASK)
  898.         ;Initialised := _InitMagic
  899.      end
  900. end;
  901.  
  902. (* Startup and Exit code *)
  903.  
  904. procedure $IOInit;
  905. (*  Initialise all kind of things which are in the STD-library.
  906.  *)
  907. var
  908.     _rc       : _word;              (* the result of the latest OS operation *)
  909. begin
  910.      (* No Errors yet *)
  911.      _rc := 0
  912.      (* _input.buf initialisation *)
  913.     ;_TextInit(_in_descr, _stdin, 'input', 6, True, True )
  914.     (* Output initialisation *)
  915.     ;_TextInit(_out_descr, _stdout, 'output', 7, False, True )
  916.     (* Error out initialisation *)
  917.     ;_TextInit(_err_descr, _stderr, 'error', 6, False, True )
  918. end;
  919.  
  920. procedure $IOExit;
  921. (*  Called when the User part of the program is done.
  922.  *)
  923. var
  924.     _rc       : _word;              (* the result of the latest OS operation *)
  925. begin
  926. end;
  927.  
  928. begin
  929. end.
  930. (*
  931.  * $Log: iolib.pas,v $
  932.  * Revision 1.1  1993/11/03  15:55:00  wjw
  933.  * Started adminstration for the RUNTIME LIB
  934.  *
  935.  *
  936.  *      First created by Willem Jan Withagen ( wjw@eb.ele.tue.nl ),
  937.  *                    on Mon July 26 23:30:03 MET 1993
  938.  *)
  939.