text.inc 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {
  12. Possible Defines:
  13. EXTENDED_EOF Use extended EOF checking for textfile, necessary for
  14. Pipes and Sockets under Linux
  15. EOF_CTRLZ Is Ctrl-Z (#26) a EOF mark for textfiles
  16. SHORT_LINEBREAK Use short Linebreaks #10 instead of #10#13
  17. Both EXTENDED_EOF and SHORT_LINEBREAK are defined in the Linux system
  18. unit (syslinux.pp)
  19. }
  20. {****************************************************************************
  21. subroutines For TextFile handling
  22. ****************************************************************************}
  23. Procedure FileCloseFunc(Var t:TextRec);
  24. Begin
  25. Do_Close(t.Handle);
  26. t.Handle:=UnusedHandle;
  27. End;
  28. Procedure FileReadFunc(var t:TextRec);
  29. Begin
  30. t.BufEnd:=Do_Read(t.Handle,Longint(t.Bufptr),t.BufSize);
  31. t.BufPos:=0;
  32. End;
  33. Procedure FileWriteFunc(var t:TextRec);
  34. Begin
  35. Do_Write(t.Handle,Longint(t.Bufptr),t.BufPos);
  36. t.BufPos:=0;
  37. End;
  38. Procedure FileOpenFunc(var t:TextRec);
  39. var
  40. Flags : Longint;
  41. Begin
  42. Case t.mode Of
  43. fmInput : Flags:=$1000;
  44. fmOutput : Flags:=$1101;
  45. fmAppend : Flags:=$1011;
  46. else
  47. HandleError(102);
  48. End;
  49. Do_Open(t,PChar(@t.Name),Flags);
  50. t.CloseFunc:=@FileCloseFunc;
  51. t.FlushFunc:=nil;
  52. if t.Mode=fmInput then
  53. t.InOutFunc:=@FileReadFunc
  54. else
  55. begin
  56. t.InOutFunc:=@FileWriteFunc;
  57. { Only install flushing if its a NOT a file }
  58. if Do_Isdevice(t.Handle) then
  59. t.FlushFunc:=@FileWriteFunc;
  60. end;
  61. End;
  62. Procedure assign(var t:Text;const s:String);
  63. Begin
  64. FillChar(t,SizEof(TextRec),0);
  65. { only set things that are not zero }
  66. TextRec(t).Handle:=UnusedHandle;
  67. TextRec(t).mode:=fmClosed;
  68. TextRec(t).BufSize:=128;
  69. TextRec(t).Bufptr:=@TextRec(t).Buffer;
  70. TextRec(t).OpenFunc:=@FileOpenFunc;
  71. Move(s[1],TextRec(t).Name,Length(s));
  72. End;
  73. Procedure assign(var t:Text;p:pchar);
  74. begin
  75. Assign(t,StrPas(p));
  76. end;
  77. Procedure assign(var t:Text;c:char);
  78. begin
  79. Assign(t,string(c));
  80. end;
  81. Procedure Close(var t : Text);[Public,Alias: 'CLOSE_TEXT',IOCheck];
  82. Begin
  83. if InOutRes <> 0 then Exit;
  84. If (TextRec(t).mode<>fmClosed) Then
  85. Begin
  86. { Write pending buffer }
  87. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  88. TextRec(t).mode:=fmClosed;
  89. { Only close functions not connected to stdout.}
  90. If ((TextRec(t).Handle<>StdInputHandle) or
  91. (TextRec(t).Handle<>StdOutputHandle) or
  92. (TextRec(t).Handle<>StdErrorHandle)) Then
  93. FileFunc(TextRec(t).CloseFunc)(TextRec(t));
  94. End;
  95. End;
  96. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  97. Begin
  98. Case TextRec(t).mode Of {This gives the fastest code}
  99. fmInput,fmOutput,fmInOut : Close(t);
  100. fmClosed : ;
  101. else
  102. Begin
  103. InOutRes:=102;
  104. exit;
  105. End;
  106. End;
  107. TextRec(t).mode:=word(mode);
  108. FileFunc(TextRec(t).OpenFunc)(TextRec(t))
  109. End;
  110. Procedure Rewrite(var t : Text);[IOCheck];
  111. Begin
  112. If InOutRes <> 0 then exit;
  113. OpenText(t,fmOutput,1);
  114. End;
  115. Procedure Reset(var t : Text);[IOCheck];
  116. Begin
  117. If InOutRes <> 0 then exit;
  118. OpenText(t,fmInput,0);
  119. End;
  120. Procedure Append(var t : Text);[IOCheck];
  121. Begin
  122. If InOutRes <> 0 then exit;
  123. OpenText(t,fmAppend,1);
  124. End;
  125. Procedure Flush(var t : Text);[IOCheck];
  126. Begin
  127. If InOutRes <> 0 then exit;
  128. If TextRec(t).mode<>fmOutput Then
  129. exit;
  130. { Not the flushfunc but the inoutfunc should be used, becuase that
  131. writes the data, flushfunc doesn't need to be assigned }
  132. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  133. End;
  134. Procedure Erase(var t:Text);[IOCheck];
  135. Begin
  136. If InOutRes <> 0 then exit;
  137. If TextRec(t).mode=fmClosed Then
  138. Do_Erase(PChar(@TextRec(t).Name));
  139. End;
  140. Procedure Rename(var t : text;p:pchar);[IOCheck];
  141. Begin
  142. If InOutRes <> 0 then exit;
  143. If TextRec(t).mode=fmClosed Then
  144. Begin
  145. Do_Rename(PChar(@TextRec(t).Name),p);
  146. Move(p^,TextRec(t).Name,StrLen(p)+1);
  147. End;
  148. End;
  149. Procedure Rename(var t : Text;const s : string);[IOCheck];
  150. var
  151. p : array[0..255] Of Char;
  152. Begin
  153. If InOutRes <> 0 then exit;
  154. Move(s[1],p,Length(s));
  155. p[Length(s)]:=#0;
  156. Rename(t,Pchar(@p));
  157. End;
  158. Procedure Rename(var t : Text;c : char);[IOCheck];
  159. var
  160. p : array[0..1] Of Char;
  161. Begin
  162. If InOutRes <> 0 then exit;
  163. p[0]:=c;
  164. p[1]:=#0;
  165. Rename(t,Pchar(@p));
  166. End;
  167. Function Eof(Var t: Text): Boolean;[IOCheck];
  168. Begin
  169. If InOutRes <> 0 then exit;
  170. {$IFNDEF EXTENDED_EOF}
  171. {$IFDEF EOF_CTRLZ}
  172. Eof:=TextRec(t).Buffer[TextRec(t).BufPos]=#26;
  173. If Eof Then
  174. Exit;
  175. {$ENDIF EOL_CTRLZ}
  176. Eof:=(Do_FileSize(TextRec(t).Handle)<=Do_FilePos(TextRec(t).Handle));
  177. If Eof Then
  178. Eof:=TextRec(t).BufEnd <= TextRec(t).BufPos;
  179. {$ELSE EXTENDED_EOF}
  180. { The previous method will NOT work on stdin and pipes or sockets.
  181. So how to do it ?
  182. 1) Check if characters in buffer - Yes ? Eof=false;
  183. 2) Read buffer full. If 0 Chars Read : Eof !
  184. Michael.}
  185. If TextRec(T).mode=fmClosed Then { Sanity Check }
  186. Begin
  187. Eof:=True;
  188. Exit;
  189. End;
  190. If (TextRec(T).BufPos < TextRec(T).BufEnd) Then
  191. Begin
  192. Eof:=False;
  193. Exit
  194. End;
  195. TextRec(T).BufPos:=0;
  196. TextRec(T).BufEnd:=Do_Read(TextRec(T).Handle,Longint(TextRec(T).BufPtr),TextRec(T).BufSize);
  197. If TextRec(T).BufEnd<0 Then
  198. TextRec(T).BufEnd:=0;
  199. Eof:=(TextRec(T).BufEnd=0);
  200. {$ENDIF EXTENDED_EOF}
  201. End;
  202. Function Eof:Boolean;
  203. Begin
  204. Eof:=Eof(Input);
  205. End;
  206. Function SeekEof (Var F : Text) : Boolean;
  207. Var
  208. TR : ^TextRec;
  209. Temp : Longint;
  210. Begin
  211. TR:=@TextRec(f);
  212. If TR^.mode<>fmInput Then exit (true);
  213. SeekEof:=True;
  214. {No data in buffer ? Fill it }
  215. If TR^.BufPos>=TR^.BufEnd Then
  216. FileFunc(TR^.InOutFunc)(TR^);
  217. Temp:=TR^.BufPos;
  218. while (TR^.BufPos<TR^.BufEnd) Do
  219. Begin
  220. If (TR^.Bufptr^[Temp] In [#9,#10,#13,' ']) Then
  221. Inc(Temp)
  222. else
  223. Begin
  224. SeekEof:=False;
  225. TR^.BufPos:=Temp;
  226. exit;
  227. End;
  228. If Temp>=TR^.BufEnd Then
  229. Begin
  230. FileFunc(TR^.InOutFunc)(TR^);
  231. Temp:=TR^.BufPos+1;
  232. End;
  233. End;
  234. End;
  235. Function SeekEof : Boolean;
  236. Begin
  237. SeekEof:=SeekEof(Input);
  238. End;
  239. Function Eoln(var t:Text) : Boolean;
  240. Begin
  241. { maybe we need new data }
  242. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  243. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  244. Eoln:=Eof(t) or (TextRec(t).Bufptr^[TextRec(t).BufPos] In [#10,#13]);
  245. End;
  246. Function Eoln : Boolean;
  247. Begin
  248. Eoln:=Eoln(Input);
  249. End;
  250. Function SeekEoln (Var F : Text) : Boolean;
  251. Var
  252. TR : ^TextRec;
  253. Temp : Longint;
  254. Begin
  255. TR:=@TextRec(f);
  256. If TR^.mode<>fmInput Then
  257. exit (true);
  258. SeekEoln:=True;
  259. {No data in buffer ? Fill it }
  260. If TR^.BufPos>=TR^.BufEnd Then
  261. FileFunc(TR^.InOutFunc)(TR^);
  262. Temp:=TR^.BufPos;
  263. while (TR^.BufPos<TR^.BufEnd) Do
  264. Begin
  265. Case (TR^.Bufptr^[Temp]) Of
  266. #10 : Exit;
  267. #9,' ' : Inc(Temp)
  268. else
  269. Begin
  270. SeekEoln:=False;
  271. TR^.BufPos:=Temp;
  272. exit;
  273. End;
  274. End;
  275. If Temp>=TR^.BufEnd Then
  276. Begin
  277. FileFunc(TR^.InOutFunc)(TR^);
  278. Temp:=TR^.BufPos+1;
  279. End;
  280. End;
  281. End;
  282. Function SeekEoln : Boolean;
  283. Begin
  284. SeekEoln:=SeekEoln(Input);
  285. End;
  286. Procedure SetTextBuf(Var F : Text; Var Buf);[INTERNPROC: In_settextbuf_file_x];
  287. Procedure SetTextBuf(Var F : Text; Var Buf; Size : Word);
  288. Begin
  289. TextRec(f).BufPtr:=@Buf;
  290. TextRec(f).BufSize:=Size;
  291. TextRec(f).BufPos:=0;
  292. TextRec(f).BufEnd:=0;
  293. End;
  294. {*****************************************************************************
  295. Write(Ln)
  296. *****************************************************************************}
  297. Procedure WriteBuffer(var f:TextRec;var b;len:longint);
  298. var
  299. p : pchar;
  300. left,
  301. idx : longint;
  302. begin
  303. p:=pchar(@b);
  304. idx:=0;
  305. left:=f.BufSize-f.BufPos;
  306. while len>left do
  307. begin
  308. move(p[idx],f.Bufptr^[f.BufPos],left);
  309. dec(len,left);
  310. inc(idx,left);
  311. inc(f.BufPos,left);
  312. FileFunc(f.InOutFunc)(f);
  313. left:=f.BufSize-f.BufPos;
  314. end;
  315. move(p[idx],f.Bufptr^[f.BufPos],len);
  316. inc(f.BufPos,len);
  317. end;
  318. Procedure WriteBlanks(var f:TextRec;len:longint);
  319. var
  320. left : longint;
  321. begin
  322. left:=f.BufSize-f.BufPos;
  323. while len>left do
  324. begin
  325. FillChar(f.Bufptr^[f.BufPos],left,' ');
  326. dec(len,left);
  327. inc(f.BufPos,left);
  328. FileFunc(f.InOutFunc)(f);
  329. left:=f.BufSize-f.BufPos;
  330. end;
  331. FillChar(f.Bufptr^[f.BufPos],len,' ');
  332. inc(f.BufPos,len);
  333. end;
  334. Procedure Write_End(var f:TextRec);[Public,Alias:'WRITE_END'];
  335. begin
  336. if f.FlushFunc<>nil then
  337. FileFunc(f.FlushFunc)(f);
  338. end;
  339. Procedure Writeln_End(var f:TextRec);[Public,Alias:'WRITELN_END'];
  340. const
  341. {$IFDEF SHORT_LINEBREAK}
  342. eollen=1;
  343. eol : array[0..0] of char=(#10);
  344. {$ELSE SHORT_LINEBREAK}
  345. eollen=2;
  346. eol : array[0..1] of char=(#13,#10);
  347. {$ENDIF SHORT_LINEBREAK}
  348. begin
  349. If InOutRes <> 0 then exit;
  350. { Write EOL }
  351. WriteBuffer(f,eol,eollen);
  352. { Flush }
  353. if f.FlushFunc<>nil then
  354. FileFunc(f.FlushFunc)(f);
  355. end;
  356. Procedure Write_Str(Len : Longint;var f : TextRec;const s : String);[Public,Alias: 'WRITE_TEXT_STRING'];
  357. Begin
  358. If InOutRes <> 0 then exit;
  359. If f.mode<>fmOutput Then
  360. exit;
  361. If Len>Length(s) Then
  362. WriteBlanks(f,Len-Length(s));
  363. WriteBuffer(f,s[1],Length(s));
  364. End;
  365. Type
  366. array00 = array[0..0] Of Char;
  367. Procedure Write_Array(Len : Longint;var f : TextRec;const p : array00);[Public,Alias: 'WRITE_TEXT_PCHAR_AS_ARRAY'];
  368. var
  369. ArrayLen : longint;
  370. Begin
  371. If InOutRes <> 0 then exit;
  372. If f.mode<>fmOutput Then
  373. exit;
  374. ArrayLen:=StrLen(p);
  375. If Len>ArrayLen Then
  376. WriteBlanks(f,Len-ArrayLen);
  377. WriteBuffer(f,p,ArrayLen);
  378. End;
  379. Procedure Write_PChar(Len : Longint;var f : TextRec;p : PChar);[Public,Alias: 'WRITE_TEXT_PCHAR_AS_POINTER'];
  380. var
  381. PCharLen : longint;
  382. Begin
  383. If InOutRes <> 0 then exit;
  384. If f.mode<>fmOutput Then
  385. exit;
  386. PCharLen:=StrLen(p);
  387. If Len>PCharLen Then
  388. WriteBlanks(f,Len-PCharLen);
  389. WriteBuffer(f,p^,PCharLen);
  390. End;
  391. {$ifdef UseAnsiStrings}
  392. Procedure Write_Text_AnsiString (Len : Longint; Var T : TextRec; Var S : AnsiString);[Public, alias: 'WRITE_TEXT_ANSISTRING'];
  393. {
  394. Writes a AnsiString to the Text file T
  395. }
  396. Var Temp : Pointer;
  397. begin
  398. Temp:=Pointer(S);
  399. If Temp=Nil then exit;
  400. Write_pchar (Len,t,PChar(Temp));
  401. end;
  402. {$endif}
  403. Procedure Write_LongInt(Len : Longint;var t : TextRec;l : Longint);[Public,Alias: 'WRITE_TEXT_LONGINT'];
  404. var
  405. s : String;
  406. Begin
  407. If InOutRes <> 0 then exit;
  408. Str(l,s);
  409. Write_Str(Len,t,s);
  410. End;
  411. Procedure Write_Real(fixkomma,Len : Longint;var t : TextRec;r : real);[Public,Alias: 'WRITE_TEXT_REAL'];
  412. var
  413. s : String;
  414. Begin
  415. If InOutRes <> 0 then exit;
  416. {$ifdef i386}
  417. Str_real(Len,fixkomma,r,rt_s64real,s);
  418. {$else}
  419. Str_real(Len,fixkomma,r,rt_s32real,s);
  420. {$endif}
  421. Write_Str(Len,t,s);
  422. End;
  423. Procedure Write_Cardinal(Len : Longint;var t : TextRec;l : cardinal);[Public,Alias: 'WRITE_TEXT_CARDINAL'];
  424. var
  425. s : String;
  426. Begin
  427. If InOutRes <> 0 then exit;
  428. Str(L,s);
  429. Write_Str(Len,t,s);
  430. End;
  431. {$ifdef SUPPORT_SINGLE}
  432. Procedure Write_Single(fixkomma,Len : Longint;var t : TextRec;r : single);[Public,Alias: 'WRITE_TEXT_SINGLE'];
  433. var
  434. s : String;
  435. Begin
  436. If InOutRes <> 0 then exit;
  437. Str_real(Len,fixkomma,r,rt_s32real,s);
  438. Write_Str(Len,t,s);
  439. End;
  440. {$endif SUPPORT_SINGLE}
  441. {$ifdef SUPPORT_EXTENDED}
  442. Procedure Write_Extended(fixkomma,Len : Longint;var t : TextRec;r : extended);[Public,Alias: 'WRITE_TEXT_EXTENDED'];
  443. var
  444. s : String;
  445. Begin
  446. If InOutRes <> 0 then exit;
  447. Str_real(Len,fixkomma,r,rt_s80real,s);
  448. Write_Str(Len,t,s);
  449. End;
  450. {$endif SUPPORT_EXTENDED}
  451. {$ifdef SUPPORT_COMP}
  452. Procedure Write_Comp(fixkomma,Len : Longint;var t : TextRec;r : comp);[Public,Alias: 'WRITE_TEXT_COMP'];
  453. var
  454. s : String;
  455. Begin
  456. If InOutRes <> 0 then exit;
  457. Str_real(Len,fixkomma,r,rt_s64bit,s);
  458. Write_Str(Len,t,s);
  459. End;
  460. {$endif SUPPORT_COMP}
  461. {$ifdef SUPPORT_FIXED}
  462. Procedure Write_Fixed(fixkomma,Len : Longint;var t : TextRec;r : fixed);[Public,Alias: 'WRITE_TEXT_FIXED'];
  463. var
  464. s : String;
  465. Begin
  466. If InOutRes <> 0 then exit;
  467. Str_real(Len,fixkomma,r,rt_f32bit,s);
  468. Write_Str(Len,t,s);
  469. End;
  470. {$endif SUPPORT_FIXED}
  471. Procedure Write_Boolean(Len : Longint;var t : TextRec;b : Boolean);[Public,Alias: 'WRITE_TEXT_BOOLEAN'];
  472. Begin
  473. If InOutRes <> 0 then exit;
  474. { Can't use array[boolean] because b can be >0 ! }
  475. if b then
  476. Write_Str(Len,t,'TRUE')
  477. else
  478. Write_Str(Len,t,'FALSE');
  479. End;
  480. Procedure Write_Char(Len : Longint;var t : TextRec;c : Char);[Public,Alias: 'WRITE_TEXT_CHAR'];
  481. Begin
  482. If InOutRes <> 0 then exit;
  483. If t.mode<>fmOutput Then
  484. exit;
  485. If Len>1 Then
  486. WriteBlanks(t,Len-1);
  487. If t.BufPos+1>=t.BufSize Then
  488. FileFunc(t.InOutFunc)(t);
  489. t.Bufptr^[t.BufPos]:=c;
  490. Inc(t.BufPos);
  491. End;
  492. {$ifdef VER0_99_5}
  493. Procedure w(var t : TextRec);[Public,Alias: 'WRITELN_TEXT'];
  494. var
  495. hs : String;
  496. Begin
  497. If InOutRes <> 0 then exit;
  498. {$IFDEF SHORT_LINEBREAK}
  499. hs:=#10;
  500. {$ELSE}
  501. hs:=#13#10;
  502. {$ENDIF}
  503. Write_Str(0,t,hs);
  504. End;
  505. {$endif VER0_99_5}
  506. {*****************************************************************************
  507. Read(Ln)
  508. *****************************************************************************}
  509. Function OpenInput(var f:TextRec):boolean;
  510. begin
  511. If f.mode=fmInput Then
  512. begin
  513. { No characters in the buffer? Load them ! }
  514. If f.BufPos>=f.BufEnd Then
  515. FileFunc(f.InOutFunc)(f);
  516. OpenInput:=true;
  517. end
  518. else
  519. OpenInput:=false;
  520. end;
  521. Function NextChar(var f:TextRec;var s:string):Boolean;
  522. begin
  523. if f.BufPos<f.BufEnd then
  524. begin
  525. s:=s+f.BufPtr^[f.BufPos];
  526. Inc(f.BufPos);
  527. If f.BufPos>=f.BufEnd Then
  528. FileFunc(f.InOutFunc)(f);
  529. NextChar:=true;
  530. end
  531. else
  532. NextChar:=false;
  533. end;
  534. Function IgnoreSpaces(var f:TextRec):Boolean;
  535. {
  536. Removes all leading spaces,tab,eols from the input buffer, returns true if
  537. the buffer is empty
  538. }
  539. var
  540. s : string;
  541. begin
  542. s:='';
  543. IgnoreSpaces:=false;
  544. while f.Bufptr^[f.BufPos] in [#9,#10,#13,' '] do
  545. if not NextChar(f,s) then
  546. exit;
  547. IgnoreSpaces:=true;
  548. end;
  549. Function ReadSign(var f:TextRec;var s:string):Boolean;
  550. {
  551. Read + and - sign, return true if buffer is empty
  552. }
  553. begin
  554. ReadSign:=(not (f.Bufptr^[f.BufPos] in ['-','+'])) or NextChar(f,s);
  555. end;
  556. Function ReadBase(var f:TextRec;var s:string;var Base:longint):boolean;
  557. {
  558. Read the base $ For 16 and % For 2, if buffer is empty return true
  559. }
  560. begin
  561. case f.BufPtr^[f.BufPos] of
  562. '$' : Base:=16;
  563. '%' : Base:=2;
  564. else
  565. Base:=10;
  566. end;
  567. ReadBase:=(Base=10) or NextChar(f,s);
  568. end;
  569. Function ReadNumeric(var f:TextRec;var s:string;base:longint):Boolean;
  570. {
  571. Read numeric input, if buffer is empty then return True
  572. }
  573. var
  574. c : char;
  575. begin
  576. ReadNumeric:=false;
  577. c:=f.BufPtr^[f.BufPos];
  578. while ((base>=10) and (c in ['0'..'9'])) or
  579. ((base=16) and (c in ['A'..'F','a'..'f'])) or
  580. ((base=2) and (c in ['0'..'1'])) do
  581. begin
  582. if not NextChar(f,s) then
  583. exit;
  584. c:=f.BufPtr^[f.BufPos];
  585. end;
  586. ReadNumeric:=true;
  587. end;
  588. Procedure Read_End(var f:TextRec);[Public,Alias:'READ_END'];
  589. begin
  590. if f.FlushFunc<>nil then
  591. FileFunc(f.FlushFunc)(f);
  592. end;
  593. Procedure ReadLn_End(var f : TextRec);[Public,Alias: 'READLN_END'];
  594. Begin
  595. If InOutRes <> 0 then exit;
  596. if not OpenInput(f) then
  597. exit;
  598. { Read until a linebreak }
  599. while (f.BufPos<f.BufEnd) do
  600. begin
  601. inc(f.BufPos);
  602. if (f.BufPtr^[f.BufPos-1]=#10) then
  603. exit;
  604. If f.BufPos>=f.BufEnd Then
  605. FileFunc(f.InOutFunc)(f);
  606. end;
  607. { Flush if set }
  608. if f.FlushFunc<>nil then
  609. FileFunc(f.FlushFunc)(f);
  610. End;
  611. {$ifdef VER0_99_5}
  612. Procedure Read_String(var f : TextRec;var s : String);[Public,Alias: 'READ_TEXT_STRING'];
  613. var
  614. Temp,sPos : Word;
  615. Begin
  616. { Delete the string }
  617. s:='';
  618. If InOutRes <> 0 then exit;
  619. if not OpenInput(f) then
  620. exit;
  621. Temp:=f.BufPos;
  622. sPos:=1;
  623. while (f.BufPos<f.BufEnd) and (f.Bufptr^[Temp]<>#10) Do
  624. Begin
  625. { search linefeed }
  626. while (f.Bufptr^[Temp]<>#10) and (Temp<f.BufEnd) Do
  627. Inc(Temp);
  628. { copy String. Take 255 char limit in account.}
  629. If sPos+Temp-f.BufPos<=255 Then
  630. Begin
  631. Move (f.Bufptr^[f.BufPos],s[sPos],Temp-f.BufPos);
  632. sPos:=sPos+Temp-f.BufPos;
  633. { Remove #13 from a #13#10 break }
  634. If s[sPos-1]=#13 Then
  635. dec(sPos);
  636. End
  637. else
  638. Begin
  639. If (sPos<=255) Then
  640. Move(f.Bufptr^[f.BufPos],s[sPos],256-sPos);
  641. sPos:=256
  642. End;
  643. { update f.BufPos }
  644. f.BufPos:=Temp;
  645. If Temp>=f.BufEnd Then
  646. Begin
  647. FileFunc(f.InOutFunc)(f);
  648. Temp:=f.BufPos;
  649. End
  650. End;
  651. s[0]:=chr(sPos-1);
  652. End;
  653. {$else VER0_99_5}
  654. Procedure Read_String(Maxlen : Longint;var f : TextRec;var s : String);[Public,Alias:'READ_TEXT_STRING'];
  655. var
  656. Temp,sPos,nrread : Word;
  657. Begin
  658. { Delete the string }
  659. s:='';
  660. If InOutRes <> 0 then exit;
  661. if not OpenInput(f) then
  662. exit;
  663. Temp:=f.BufPos;
  664. sPos:=1;
  665. NrRead:=0;
  666. while (f.BufPos<f.BufEnd) and ((f.Bufptr^[Temp]<>#10) and (NrRead<Maxlen)) Do
  667. Begin
  668. { search linefeed or length of string }
  669. while ((f.Bufptr^[Temp]<>#10) and (NrRead<Maxlen)) and (Temp<f.BufEnd) Do
  670. begin
  671. Temp:=Temp+1;
  672. NrRead:=NrRead+1;
  673. end;
  674. { copy String. Take 255 char limit in account.}
  675. If sPos+Temp-f.BufPos<=255 Then
  676. Begin
  677. Move (f.Bufptr^[f.BufPos],s[sPos],Temp-f.BufPos);
  678. sPos:=sPos+Temp-f.BufPos;
  679. { Remove #13 from a #13#10 break }
  680. If s[sPos-1]=#13 Then
  681. dec(sPos);
  682. End
  683. else
  684. Begin
  685. If (sPos<=255) Then
  686. Move(f.Bufptr^[f.BufPos],s[sPos],256-sPos);
  687. sPos:=256
  688. End;
  689. { update f.BufPos }
  690. f.BufPos:=Temp;
  691. If Temp>=f.BufEnd Then
  692. Begin
  693. FileFunc(f.InOutFunc)(f);
  694. Temp:=f.BufPos;
  695. End
  696. End;
  697. s[0]:=chr(sPos-1);
  698. End;
  699. {$endif VER0_99_5}
  700. Procedure Read_Char(var f : TextRec;var c : Char);[Public,Alias: 'READ_TEXT_CHAR'];
  701. Begin
  702. c:=#0;
  703. If InOutRes <> 0 then exit;
  704. if not OpenInput(f) then
  705. exit;
  706. If f.BufPos>=f.BufEnd Then
  707. c:=#26
  708. else
  709. c:=f.Bufptr^[f.BufPos];
  710. Inc(f.BufPos);
  711. End;
  712. Procedure Read_PChar(var f : TextRec;var s : PChar);[Public,Alias:'READ_TEXT_PCHAR_AS_POINTER'];
  713. var
  714. p : PChar;
  715. Temp : byte;
  716. Begin
  717. { Delete the string }
  718. s^:=#0;
  719. If InOutRes <> 0 then exit;
  720. p:=s;
  721. if not OpenInput(f) then
  722. exit;
  723. Temp:=f.BufPos;
  724. while (f.BufPos<f.BufEnd) and (f.Bufptr^[Temp]<>#10) Do
  725. Begin
  726. { search linefeed }
  727. while (f.Bufptr^[Temp]<>#10) and (Temp<f.BufEnd) Do
  728. inc(Temp);
  729. { copy string. }
  730. Move (f.Bufptr^[f.BufPos],p^,Temp-f.BufPos);
  731. Inc(Longint(p),Temp-f.BufPos);
  732. If pchar(p-1)^=#13 Then
  733. dec(p);
  734. { update f.BufPos }
  735. f.BufPos:=Temp;
  736. If Temp>=f.BufEnd Then
  737. Begin
  738. FileFunc(f.InOutFunc)(f);
  739. Temp:=f.BufPos;
  740. End
  741. End;
  742. p^:=#0;
  743. End;
  744. Procedure Read_Array(var f : TextRec;var s : array00);[Public,Alias:'READ_TEXT_PCHAR_AS_ARRAY'];
  745. var
  746. p : PChar;
  747. Temp : byte;
  748. Begin
  749. { Delete the string }
  750. s[0]:=#0;
  751. If InOutRes <> 0 then exit;
  752. p:=pchar(@s);
  753. if not OpenInput(f) then
  754. exit;
  755. Temp:=f.BufPos;
  756. while (f.BufPos<f.BufEnd) and (f.Bufptr^[Temp]<>#10) Do
  757. Begin
  758. { search linefeed }
  759. while (f.Bufptr^[Temp]<>#10) and (Temp<f.BufEnd) Do
  760. inc(Temp);
  761. { copy string. }
  762. Move (f.Bufptr^[f.BufPos],p^,Temp-f.BufPos);
  763. Inc(Longint(p),Temp-f.BufPos);
  764. If pchar(p-1)^=#13 Then
  765. dec(p);
  766. { update f.BufPos }
  767. f.BufPos:=Temp;
  768. If Temp>=f.BufEnd Then
  769. Begin
  770. FileFunc(f.InOutFunc)(f);
  771. Temp:=f.BufPos;
  772. End
  773. End;
  774. p^:=#0;
  775. End;
  776. {$ifdef useansistrings}
  777. Procedure Read_String(Maxlen : Longint;var f : TextRec;var s : AnsiString);[Public,Alias: 'READ_TEXT_ANSISTRING'];
  778. var
  779. p : PChar;
  780. Temp : byte;
  781. len : Longint;
  782. Begin
  783. { Delete the string }
  784. Decr_ansi_ref (S);
  785. // We assign room for 1024 characters totally at random....
  786. Pointer(s):=Pointer(NewAnsiString(1024));
  787. If InOutRes <> 0 then exit;
  788. p:=pointer(s);
  789. if not OpenInput(f) then
  790. exit;
  791. Temp:=f.BufPos;
  792. while (f.BufPos<f.BufEnd) and (f.Bufptr^[Temp]<>#10) Do
  793. Begin
  794. { search linefeed }
  795. while (f.Bufptr^[Temp]<>#10) and (Temp<f.BufEnd) Do
  796. inc(Temp);
  797. { copy string. }
  798. Move (f.Bufptr^[f.BufPos],p^,Temp-f.BufPos);
  799. Inc(Longint(p),Temp-f.BufPos);
  800. Inc(len,Temp-f.bufpos);
  801. If pchar(p-1)^=#13 Then
  802. dec(p);
  803. { update f.BufPos }
  804. f.BufPos:=Temp;
  805. If Temp>=f.BufEnd Then
  806. Begin
  807. FileFunc(f.InOutFunc)(f);
  808. Temp:=f.BufPos;
  809. End
  810. End;
  811. p^:=#0;
  812. PAnsiRec(Pointer(S)-FirstOff)^.Len:=len
  813. End;
  814. {$endif}
  815. Procedure Read_Longint(var f : TextRec;var l : Longint);[Public,Alias: 'READ_TEXT_LONGINT'];
  816. var
  817. hs : String;
  818. code : Word;
  819. base : longint;
  820. Begin
  821. l:=0;
  822. If InOutRes <> 0 then exit;
  823. hs:='';
  824. if not OpenInput(f) then
  825. exit;
  826. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  827. ReadNumeric(f,hs,Base);
  828. Val(hs,l,code);
  829. If code<>0 Then
  830. HandleError(106);
  831. End;
  832. Procedure Read_Integer(var f : TextRec;var l : Integer);[Public,Alias: 'READ_TEXT_INTEGER'];
  833. var
  834. ll : Longint;
  835. Begin
  836. l:=0;
  837. If InOutRes <> 0 then exit;
  838. Read_Longint(f,ll);
  839. If (ll<-32768) or (ll>32767) Then
  840. HandleError(106);
  841. l:=ll;
  842. End;
  843. Procedure Read_Word(var f : TextRec;var l : Word);[Public,Alias: 'READ_TEXT_WORD'];
  844. var
  845. ll : Longint;
  846. Begin
  847. l:=0;
  848. If InOutRes <> 0 then exit;
  849. Read_Longint(f,ll);
  850. If (ll<0) or (ll>$ffff) Then
  851. HandleError(106);
  852. l:=ll;
  853. End;
  854. Procedure Read_Byte(var f : TextRec;var l : byte);[Public,Alias: 'READ_TEXT_BYTE'];
  855. var
  856. ll : Longint;
  857. Begin
  858. l:=0;
  859. If InOutRes <> 0 then exit;
  860. Read_Longint(f,ll);
  861. If (ll<0) or (ll>255) Then
  862. HandleError(106);
  863. l:=ll;
  864. End;
  865. Procedure Read_Shortint(var f : TextRec;var l : shortint);[Public,Alias: 'READ_TEXT_SHORTINT'];
  866. var
  867. ll : Longint;
  868. Begin
  869. l:=0;
  870. If InOutRes <> 0 then exit;
  871. Read_Longint(f,ll);
  872. If (ll<-128) or (ll>127) Then
  873. HandleError(106);
  874. l:=ll;
  875. End;
  876. Procedure Read_Cardinal(var f : TextRec;var l : cardinal);[Public,Alias: 'READ_TEXT_CARDINAL'];
  877. var
  878. hs : String;
  879. code : Word;
  880. base : longint;
  881. Begin
  882. l:=0;
  883. If InOutRes <> 0 then exit;
  884. hs:='';
  885. if not OpenInput(f) then
  886. exit;
  887. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  888. ReadNumeric(f,hs,Base);
  889. val(hs,l,code);
  890. If code<>0 Then
  891. HandleError(106);
  892. End;
  893. Procedure Read_Real(var f : TextRec;var d : Real);[Public,Alias: 'READ_TEXT_REAL'];
  894. var
  895. hs : String;
  896. code : Word;
  897. Begin
  898. d:=0.0;
  899. If InOutRes <> 0 then exit;
  900. hs:='';
  901. if not OpenInput(f) then
  902. exit;
  903. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  904. begin
  905. { First check for a . }
  906. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  907. begin
  908. hs:=hs+'.';
  909. Inc(f.BufPos);
  910. If f.BufPos>=f.BufEnd Then
  911. FileFunc(f.InOutFunc)(f);
  912. ReadNumeric(f,hs,10);
  913. end;
  914. { Also when a point is found check for a E }
  915. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  916. begin
  917. hs:=hs+'E';
  918. Inc(f.BufPos);
  919. If f.BufPos>=f.BufEnd Then
  920. FileFunc(f.InOutFunc)(f);
  921. if ReadSign(f,hs) then
  922. ReadNumeric(f,hs,10);
  923. end;
  924. end;
  925. val(hs,d,code);
  926. If code<>0 Then
  927. HandleError(106);
  928. End;
  929. {$ifdef SUPPORT_EXTENDED}
  930. Procedure Read_Extended(var f : TextRec;var d : extended);[Public,Alias: 'READ_TEXT_EXTENDED'];
  931. var
  932. hs : String;
  933. code : Word;
  934. Begin
  935. d:=0.0;
  936. If InOutRes <> 0 then exit;
  937. hs:='';
  938. if not OpenInput(f) then
  939. exit;
  940. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  941. begin
  942. { First check for a . }
  943. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  944. begin
  945. hs:=hs+'.';
  946. Inc(f.BufPos);
  947. If f.BufPos>=f.BufEnd Then
  948. FileFunc(f.InOutFunc)(f);
  949. ReadNumeric(f,hs,10);
  950. end;
  951. { Also when a point is found check for a E }
  952. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  953. begin
  954. hs:=hs+'E';
  955. Inc(f.BufPos);
  956. If f.BufPos>=f.BufEnd Then
  957. FileFunc(f.InOutFunc)(f);
  958. if ReadSign(f,hs) then
  959. ReadNumeric(f,hs,10);
  960. end;
  961. end;
  962. val(hs,d,code);
  963. If code<>0 Then
  964. HandleError(106);
  965. End;
  966. {$endif SUPPORT_EXTENDED}
  967. {$ifdef SUPPORT_COMP}
  968. Procedure Read_Comp(var f : TextRec;var d : comp);[Public,Alias: 'READ_TEXT_COMP'];
  969. var
  970. hs : String;
  971. code : Word;
  972. Begin
  973. d:=comp(0.0);
  974. If InOutRes <> 0 then exit;
  975. hs:='';
  976. if not OpenInput(f) then
  977. exit;
  978. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  979. begin
  980. { First check for a . }
  981. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  982. begin
  983. hs:=hs+'.';
  984. Inc(f.BufPos);
  985. If f.BufPos>=f.BufEnd Then
  986. FileFunc(f.InOutFunc)(f);
  987. ReadNumeric(f,hs,10);
  988. end;
  989. { Also when a point is found check for a E }
  990. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  991. begin
  992. hs:=hs+'E';
  993. Inc(f.BufPos);
  994. If f.BufPos>=f.BufEnd Then
  995. FileFunc(f.InOutFunc)(f);
  996. if ReadSign(f,hs) then
  997. ReadNumeric(f,hs,10);
  998. end;
  999. end;
  1000. val(hs,d,code);
  1001. If code<>0 Then
  1002. HandleError(106);
  1003. End;
  1004. {$endif SUPPORT_COMP}
  1005. {$ifdef VER0_99_5}
  1006. Procedure r(var f : TextRec);[Public,Alias: 'READLN_TEXT'];
  1007. Begin
  1008. If InOutRes <> 0 then exit;
  1009. if not OpenInput(f) then
  1010. exit;
  1011. while (f.BufPos<f.BufEnd) do
  1012. begin
  1013. inc(f.BufPos);
  1014. if (f.BufPtr^[f.BufPos-1]=#10) then
  1015. exit;
  1016. If f.BufPos>=f.BufEnd Then
  1017. FileFunc(f.InOutFunc)(f);
  1018. end;
  1019. End;
  1020. {$endif VER0_99_5}
  1021. {*****************************************************************************
  1022. Initializing
  1023. *****************************************************************************}
  1024. procedure OpenStdIO(var f:text;mode:word;hdl:longint);
  1025. begin
  1026. Assign(f,'');
  1027. TextRec(f).Handle:=hdl;
  1028. TextRec(f).Mode:=mode;
  1029. TextRec(f).Closefunc:=@FileCloseFunc;
  1030. case mode of
  1031. fmInput : TextRec(f).InOutFunc:=@FileReadFunc;
  1032. fmOutput : begin
  1033. TextRec(f).InOutFunc:=@FileWriteFunc;
  1034. TextRec(f).FlushFunc:=@FileWriteFunc;
  1035. end;
  1036. else
  1037. HandleError(102);
  1038. end;
  1039. end;
  1040. {
  1041. $Log$
  1042. Revision 1.20 1998-08-11 00:05:28 peter
  1043. * $ifdef ver0_99_5 updates
  1044. Revision 1.19 1998/07/30 13:26:16 michael
  1045. + Added support for ErrorProc variable. All internal functions are required
  1046. to call HandleError instead of runerror from now on.
  1047. This is necessary for exception support.
  1048. Revision 1.18 1998/07/29 21:44:35 michael
  1049. + Implemented reading/writing of ansistrings
  1050. Revision 1.17 1998/07/19 19:55:33 michael
  1051. + fixed rename. Changed p to p^
  1052. Revision 1.16 1998/07/10 11:02:40 peter
  1053. * support_fixed, becuase fixed is not 100% yet for the m68k
  1054. Revision 1.15 1998/07/06 15:56:43 michael
  1055. Added length checking for string reading
  1056. Revision 1.14 1998/07/02 12:14:56 carl
  1057. + Each IOCheck routine now check InOutRes before, just like TP
  1058. Revision 1.13 1998/07/01 15:30:00 peter
  1059. * better readln/writeln
  1060. Revision 1.12 1998/07/01 14:48:10 carl
  1061. * bugfix of WRITE_TEXT_BOOLEAN , was not TP compatible
  1062. + added explicit typecast in OpenText
  1063. Revision 1.11 1998/06/25 09:44:22 daniel
  1064. + RTLLITE directive to compile minimal RTL.
  1065. Revision 1.10 1998/06/04 23:46:03 peter
  1066. * comp,extended are only i386 added support_comp,support_extended
  1067. Revision 1.9 1998/06/02 16:47:56 pierre
  1068. * bug for boolean values greater than one fixed
  1069. Revision 1.8 1998/05/31 14:14:54 peter
  1070. * removed warnings using comp()
  1071. Revision 1.7 1998/05/27 00:19:21 peter
  1072. * fixed crt input
  1073. Revision 1.6 1998/05/21 19:31:01 peter
  1074. * objects compiles for linux
  1075. + assign(pchar), assign(char), rename(pchar), rename(char)
  1076. * fixed read_text_as_array
  1077. + read_text_as_pchar which was not yet in the rtl
  1078. Revision 1.5 1998/05/12 10:42:45 peter
  1079. * moved getopts to inc/, all supported OS's need argc,argv exported
  1080. + strpas, strlen are now exported in the systemunit
  1081. * removed logs
  1082. * removed $ifdef ver_above
  1083. Revision 1.4 1998/04/07 22:40:46 florian
  1084. * final fix of comp writing
  1085. }