text.inc 28 KB

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