text.inc 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1999-2000 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. EOF_CTRLZ Is Ctrl-Z (#26) a EOF mark for textfiles
  14. SHORT_LINEBREAK Use short Linebreaks #10 instead of #10#13
  15. SHORT_LINEBREAK is defined in the Linux system unit (syslinux.pp)
  16. }
  17. {****************************************************************************
  18. subroutines For TextFile handling
  19. ****************************************************************************}
  20. Procedure FileCloseFunc(Var t:TextRec);
  21. Begin
  22. Do_Close(t.Handle);
  23. t.Handle:=UnusedHandle;
  24. End;
  25. Procedure FileReadFunc(var t:TextRec);
  26. Begin
  27. t.BufEnd:=Do_Read(t.Handle,Longint(t.Bufptr),t.BufSize);
  28. t.BufPos:=0;
  29. End;
  30. Procedure FileWriteFunc(var t:TextRec);
  31. var
  32. i : longint;
  33. Begin
  34. i:=Do_Write(t.Handle,Longint(t.Bufptr),t.BufPos);
  35. if i<>t.BufPos then
  36. InOutRes:=101;
  37. t.BufPos:=0;
  38. End;
  39. Procedure FileOpenFunc(var t:TextRec);
  40. var
  41. Flags : Longint;
  42. Begin
  43. Case t.mode Of
  44. fmInput : Flags:=$10000;
  45. fmOutput : Flags:=$11001;
  46. fmAppend : Flags:=$10101;
  47. else
  48. begin
  49. InOutRes:=102;
  50. exit;
  51. end;
  52. End;
  53. Do_Open(t,PChar(@t.Name),Flags);
  54. t.CloseFunc:=@FileCloseFunc;
  55. t.FlushFunc:=nil;
  56. if t.Mode=fmInput then
  57. t.InOutFunc:=@FileReadFunc
  58. else
  59. begin
  60. t.InOutFunc:=@FileWriteFunc;
  61. { Only install flushing if its a NOT a file, and only check if there
  62. was no error opening the file, becuase else we always get a bad
  63. file handle error 6 (PFV) }
  64. if (InOutRes=0) and
  65. Do_Isdevice(t.Handle) then
  66. t.FlushFunc:=@FileWriteFunc;
  67. end;
  68. End;
  69. Procedure assign(var t:Text;const s:String);
  70. Begin
  71. FillChar(t,SizEof(TextRec),0);
  72. { only set things that are not zero }
  73. TextRec(t).Handle:=UnusedHandle;
  74. TextRec(t).mode:=fmClosed;
  75. TextRec(t).BufSize:=TextRecBufSize;
  76. TextRec(t).Bufptr:=@TextRec(t).Buffer;
  77. TextRec(t).OpenFunc:=@FileOpenFunc;
  78. Move(s[1],TextRec(t).Name,Length(s));
  79. End;
  80. Procedure assign(var t:Text;p:pchar);
  81. begin
  82. Assign(t,StrPas(p));
  83. end;
  84. Procedure assign(var t:Text;c:char);
  85. begin
  86. Assign(t,string(c));
  87. end;
  88. Procedure Close(var t : Text);[IOCheck];
  89. Begin
  90. if InOutRes<>0 then
  91. Exit;
  92. case TextRec(t).mode of
  93. fmInput,fmOutPut,fmAppend:
  94. Begin
  95. { Write pending buffer }
  96. If Textrec(t).Mode=fmoutput then
  97. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  98. { Only close functions not connected to stdout.}
  99. If ((TextRec(t).Handle<>StdInputHandle) and
  100. (TextRec(t).Handle<>StdOutputHandle) and
  101. (TextRec(t).Handle<>StdErrorHandle)) Then
  102. FileFunc(TextRec(t).CloseFunc)(TextRec(t));
  103. TextRec(t).mode := fmClosed;
  104. { Reset buffer for safety }
  105. TextRec(t).BufPos:=0;
  106. TextRec(t).BufEnd:=0;
  107. End
  108. else inOutRes := 103;
  109. End;
  110. End;
  111. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  112. Begin
  113. Case TextRec(t).mode Of {This gives the fastest code}
  114. fmInput,fmOutput,fmInOut : Close(t);
  115. fmClosed : ;
  116. else
  117. Begin
  118. InOutRes:=102;
  119. exit;
  120. End;
  121. End;
  122. TextRec(t).mode:=mode;
  123. TextRec(t).bufpos:=0;
  124. TextRec(t).bufend:=0;
  125. FileFunc(TextRec(t).OpenFunc)(TextRec(t));
  126. { reset the mode to closed when an error has occured }
  127. if InOutRes<>0 then
  128. TextRec(t).mode:=fmClosed;
  129. End;
  130. Procedure Rewrite(var t : Text);[IOCheck];
  131. Begin
  132. If InOutRes<>0 then
  133. exit;
  134. OpenText(t,fmOutput,1);
  135. End;
  136. Procedure Reset(var t : Text);[IOCheck];
  137. Begin
  138. If InOutRes<>0 then
  139. exit;
  140. OpenText(t,fmInput,0);
  141. End;
  142. Procedure Append(var t : Text);[IOCheck];
  143. Begin
  144. If InOutRes<>0 then
  145. exit;
  146. OpenText(t,fmAppend,1);
  147. End;
  148. Procedure Flush(var t : Text);[IOCheck];
  149. Begin
  150. If InOutRes<>0 then
  151. exit;
  152. if TextRec(t).mode<>fmOutput then
  153. begin
  154. if TextRec(t).mode=fmInput then
  155. InOutRes:=105
  156. else
  157. InOutRes:=103;
  158. exit;
  159. end;
  160. { Not the flushfunc but the inoutfunc should be used, becuase that
  161. writes the data, flushfunc doesn't need to be assigned }
  162. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  163. End;
  164. Procedure Erase(var t:Text);[IOCheck];
  165. Begin
  166. If InOutRes <> 0 then
  167. exit;
  168. If TextRec(t).mode=fmClosed Then
  169. Do_Erase(PChar(@TextRec(t).Name));
  170. End;
  171. Procedure Rename(var t : text;p:pchar);[IOCheck];
  172. Begin
  173. If InOutRes <> 0 then
  174. exit;
  175. If TextRec(t).mode=fmClosed Then
  176. Begin
  177. Do_Rename(PChar(@TextRec(t).Name),p);
  178. { check error code of do_rename }
  179. If InOutRes = 0 then
  180. Move(p^,TextRec(t).Name,StrLen(p)+1);
  181. End;
  182. End;
  183. Procedure Rename(var t : Text;const s : string);[IOCheck];
  184. var
  185. p : array[0..255] Of Char;
  186. Begin
  187. If InOutRes <> 0 then
  188. exit;
  189. Move(s[1],p,Length(s));
  190. p[Length(s)]:=#0;
  191. Rename(t,Pchar(@p));
  192. End;
  193. Procedure Rename(var t : Text;c : char);[IOCheck];
  194. var
  195. p : array[0..1] Of Char;
  196. Begin
  197. If InOutRes <> 0 then
  198. exit;
  199. p[0]:=c;
  200. p[1]:=#0;
  201. Rename(t,Pchar(@p));
  202. End;
  203. Function Eof(Var t: Text): Boolean;[IOCheck];
  204. Begin
  205. If (InOutRes<>0) then
  206. exit(true);
  207. if (TextRec(t).mode<>fmInput) Then
  208. begin
  209. if TextRec(t).mode=fmOutput then
  210. InOutRes:=104
  211. else
  212. InOutRes:=103;
  213. exit(true);
  214. end;
  215. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  216. begin
  217. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  218. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  219. exit(true);
  220. end;
  221. {$ifdef EOF_CTRLZ}
  222. Eof:=(TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
  223. {$else}
  224. Eof:=false;
  225. {$endif EOL_CTRLZ}
  226. end;
  227. Function Eof:Boolean;
  228. Begin
  229. Eof:=Eof(Input);
  230. End;
  231. Function SeekEof (Var t : Text) : Boolean;
  232. Begin
  233. If (InOutRes<>0) then
  234. exit(true);
  235. if (TextRec(t).mode<>fmInput) Then
  236. begin
  237. if TextRec(t).mode=fmOutPut then
  238. InOutRes:=104
  239. else
  240. InOutRes:=103;
  241. exit(true);
  242. end;
  243. repeat
  244. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  245. begin
  246. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  247. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  248. exit(true);
  249. end;
  250. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  251. #26 : exit(true);
  252. #10,#13,
  253. #9,' ' : ;
  254. else
  255. exit(false);
  256. end;
  257. inc(TextRec(t).BufPos);
  258. until false;
  259. End;
  260. Function SeekEof : Boolean;
  261. Begin
  262. SeekEof:=SeekEof(Input);
  263. End;
  264. Function Eoln(var t:Text) : Boolean;
  265. Begin
  266. If (InOutRes<>0) then
  267. exit(true);
  268. if (TextRec(t).mode<>fmInput) Then
  269. begin
  270. if TextRec(t).mode=fmOutPut then
  271. InOutRes:=104
  272. else
  273. InOutRes:=103;
  274. exit(true);
  275. end;
  276. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  277. begin
  278. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  279. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  280. exit(true);
  281. end;
  282. Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
  283. End;
  284. Function Eoln : Boolean;
  285. Begin
  286. Eoln:=Eoln(Input);
  287. End;
  288. Function SeekEoln (Var t : Text) : Boolean;
  289. Begin
  290. If (InOutRes<>0) then
  291. exit(true);
  292. if (TextRec(t).mode<>fmInput) Then
  293. begin
  294. if TextRec(t).mode=fmOutput then
  295. InOutRes:=104
  296. else
  297. InOutRes:=103;
  298. exit(true);
  299. end;
  300. repeat
  301. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  302. begin
  303. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  304. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  305. exit(true);
  306. end;
  307. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  308. #26,
  309. #10,#13 : exit(true);
  310. #9,' ' : ;
  311. else
  312. exit(false);
  313. end;
  314. inc(TextRec(t).BufPos);
  315. until false;
  316. End;
  317. Function SeekEoln : Boolean;
  318. Begin
  319. SeekEoln:=SeekEoln(Input);
  320. End;
  321. Procedure SetTextBuf(Var F : Text; Var Buf);[INTERNPROC: In_settextbuf_file_x];
  322. Procedure SetTextBuf(Var F : Text; Var Buf; Size : Longint);
  323. Begin
  324. TextRec(f).BufPtr:=@Buf;
  325. TextRec(f).BufSize:=Size;
  326. TextRec(f).BufPos:=0;
  327. TextRec(f).BufEnd:=0;
  328. End;
  329. {*****************************************************************************
  330. Write(Ln)
  331. *****************************************************************************}
  332. Procedure WriteBuffer(var f:Text;const b;len:longint);
  333. var
  334. p : pchar;
  335. left,
  336. idx : longint;
  337. begin
  338. p:=pchar(@b);
  339. idx:=0;
  340. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  341. while len>left do
  342. begin
  343. move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],left);
  344. dec(len,left);
  345. inc(idx,left);
  346. inc(TextRec(f).BufPos,left);
  347. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  348. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  349. end;
  350. move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],len);
  351. inc(TextRec(f).BufPos,len);
  352. end;
  353. Procedure WriteBlanks(var f:Text;len:longint);
  354. var
  355. left : longint;
  356. begin
  357. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  358. while len>left do
  359. begin
  360. FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],left,' ');
  361. dec(len,left);
  362. inc(TextRec(f).BufPos,left);
  363. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  364. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  365. end;
  366. FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],len,' ');
  367. inc(TextRec(f).BufPos,len);
  368. end;
  369. Procedure fpc_Write_End(var f:Text);[Public,Alias:'FPC_WRITE_END']; iocheck; {$ifdef hascompilerproc} compilerproc; {$endif}
  370. begin
  371. if TextRec(f).FlushFunc<>nil then
  372. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  373. end;
  374. Procedure fpc_Writeln_End(var f:Text);[Public,Alias:'FPC_WRITELN_END']; iocheck; {$ifdef hascompilerproc} compilerproc; {$endif}
  375. const
  376. {$IFDEF SHORT_LINEBREAK}
  377. eollen=1;
  378. eol : array[0..0] of char=(#10);
  379. {$ELSE SHORT_LINEBREAK}
  380. {$ifdef MAC_LINEBREAK}
  381. eollen=1;
  382. eol : array[0..0] of char=(#13);
  383. {$else MAC_LINEBREAK}
  384. eollen=2;
  385. eol : array[0..1] of char=(#13,#10);
  386. {$endif MAC_LINEBREAK}
  387. {$ENDIF SHORT_LINEBREAK}
  388. begin
  389. If InOutRes <> 0 then exit;
  390. case TextRec(f).mode of
  391. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  392. begin
  393. { Write EOL }
  394. WriteBuffer(f,(@sLineBreak+1)^,length(sLineBreak));
  395. { Flush }
  396. if TextRec(f).FlushFunc<>nil then
  397. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  398. end;
  399. fmInput: InOutRes:=105
  400. else InOutRes:=103;
  401. end;
  402. end;
  403. Procedure fpc_Write_Text_ShortStr(Len : Longint;var f : Text;const s : String); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  404. Begin
  405. If (InOutRes<>0) then
  406. exit;
  407. case TextRec(f).mode of
  408. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  409. begin
  410. If Len>Length(s) Then
  411. WriteBlanks(f,Len-Length(s));
  412. WriteBuffer(f,s[1],Length(s));
  413. end;
  414. fmInput: InOutRes:=105
  415. else InOutRes:=103;
  416. end;
  417. End;
  418. { provide local access to write_str }
  419. procedure Write_Str(Len : Longint;var f : Text;const s : String); iocheck; [external name 'FPC_WRITE_TEXT_SHORTSTR'];
  420. Procedure fpc_Write_Text_Pchar_as_Array(Len : Longint;var f : Text;const s : array of char); iocheck; [Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_ARRAY']; {$ifdef hascompilerproc} compilerproc; {$endif}
  421. var
  422. ArrayLen : longint;
  423. p : pchar;
  424. Begin
  425. If (InOutRes<>0) then
  426. exit;
  427. case TextRec(f).mode of
  428. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  429. begin
  430. p:=pchar(@s);
  431. { can't use StrLen, since that one could try to read past the end }
  432. { of the heap (JM) }
  433. ArrayLen:=IndexByte(p^,high(s)+1,0);
  434. { IndexByte returns -1 if not found (JM) }
  435. if ArrayLen = -1 then
  436. ArrayLen := high(s)+1;
  437. If Len>ArrayLen Then
  438. WriteBlanks(f,Len-ArrayLen);
  439. WriteBuffer(f,p^,ArrayLen);
  440. end;
  441. fmInput: InOutRes:=105
  442. else InOutRes:=103;
  443. end;
  444. End;
  445. Procedure fpc_Write_Text_PChar_As_Pointer(Len : Longint;var f : Text;p : PChar); iocheck; [Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_POINTER']; {$ifdef hascompilerproc} compilerproc; {$endif}
  446. var
  447. PCharLen : longint;
  448. Begin
  449. If (p=nil) or (InOutRes<>0) then
  450. exit;
  451. case TextRec(f).mode of
  452. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  453. begin
  454. PCharLen:=StrLen(p);
  455. If Len>PCharLen Then
  456. WriteBlanks(f,Len-PCharLen);
  457. WriteBuffer(f,p^,PCharLen);
  458. end;
  459. fmInput: InOutRes:=105
  460. else InOutRes:=103;
  461. end;
  462. End;
  463. Procedure fpc_Write_Text_AnsiStr (Len : Longint; Var f : Text; S : AnsiString); iocheck; [Public,alias:'FPC_WRITE_TEXT_ANSISTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  464. {
  465. Writes a AnsiString to the Text file T
  466. }
  467. var
  468. SLen : longint;
  469. begin
  470. If (pointer(S)=nil) or (InOutRes<>0) then
  471. exit;
  472. case TextRec(f).mode of
  473. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  474. begin
  475. SLen:=Length(s);
  476. If Len>SLen Then
  477. WriteBlanks(f,Len-SLen);
  478. WriteBuffer(f,PChar(S)^,SLen);
  479. end;
  480. fmInput: InOutRes:=105
  481. else InOutRes:=103;
  482. end;
  483. end;
  484. {$ifdef HASWIDESTRING}
  485. Procedure fpc_Write_Text_WideStr (Len : Longint; Var f : Text; S : WideString); iocheck; [Public,alias:'FPC_WRITE_TEXT_WIDESTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  486. {
  487. Writes a WideString to the Text file T
  488. }
  489. var
  490. SLen : longint;
  491. begin
  492. If (pointer(S)=nil) or (InOutRes<>0) then
  493. exit;
  494. case TextRec(f).mode of
  495. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  496. begin
  497. SLen:=Length(s);
  498. If Len>SLen Then
  499. WriteBlanks(f,Len-SLen);
  500. WriteBuffer(f,PChar(AnsiString(S))^,SLen);
  501. end;
  502. fmInput: InOutRes:=105
  503. else InOutRes:=103;
  504. end;
  505. end;
  506. {$endif HASWIDESTRING}
  507. Procedure fpc_Write_Text_SInt(Len : Longint;var t : Text;l : ValSInt); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  508. var
  509. s : String;
  510. Begin
  511. If (InOutRes<>0) then
  512. exit;
  513. Str(l,s);
  514. Write_Str(Len,t,s);
  515. End;
  516. Procedure fpc_Write_Text_UInt(Len : Longint;var t : Text;l : ValUInt); iocheck; [Public,Alias:'FPC_WRITE_TEXT_UINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  517. var
  518. s : String;
  519. Begin
  520. If (InOutRes<>0) then
  521. exit;
  522. Str(L,s);
  523. Write_Str(Len,t,s);
  524. End;
  525. procedure fpc_write_text_qword(len : longint;var t : text;q : qword); iocheck; [public,alias:'FPC_WRITE_TEXT_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  526. var
  527. s : string;
  528. begin
  529. if (InOutRes<>0) then
  530. exit;
  531. qword_str(q,s);
  532. write_str(len,t,s);
  533. end;
  534. procedure fpc_write_text_int64(len : longint;var t : text;i : int64); iocheck; [public,alias:'FPC_WRITE_TEXT_INT64']; {$ifdef hascompilerproc} compilerproc; {$endif}
  535. var
  536. s : string;
  537. begin
  538. if (InOutRes<>0) then
  539. exit;
  540. int64_str(i,s);
  541. write_str(len,t,s);
  542. end;
  543. Procedure fpc_Write_Text_Float(rt,fixkomma,Len : Longint;var t : Text;r : ValReal); iocheck; [Public,Alias:'FPC_WRITE_TEXT_FLOAT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  544. var
  545. s : String;
  546. Begin
  547. If (InOutRes<>0) then
  548. exit;
  549. Str_real(Len,fixkomma,r,treal_type(rt),s);
  550. Write_Str(Len,t,s);
  551. End;
  552. Procedure fpc_Write_Text_Boolean(Len : Longint;var t : Text;b : Boolean); iocheck; [Public,Alias:'FPC_WRITE_TEXT_BOOLEAN']; {$ifdef hascompilerproc} compilerproc; {$endif}
  553. Begin
  554. If (InOutRes<>0) then
  555. exit;
  556. { Can't use array[boolean] because b can be >0 ! }
  557. if b then
  558. Write_Str(Len,t,'TRUE')
  559. else
  560. Write_Str(Len,t,'FALSE');
  561. End;
  562. Procedure fpc_Write_Text_Char(Len : Longint;var t : Text;c : Char); iocheck; [Public,Alias:'FPC_WRITE_TEXT_CHAR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  563. Begin
  564. If (InOutRes<>0) then
  565. exit;
  566. if (TextRec(t).mode<>fmOutput) Then
  567. begin
  568. if TextRec(t).mode=fmClosed then
  569. InOutRes:=103
  570. else
  571. InOutRes:=105;
  572. exit;
  573. end;
  574. If Len>1 Then
  575. WriteBlanks(t,Len-1);
  576. If TextRec(t).BufPos+1>=TextRec(t).BufSize Then
  577. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  578. TextRec(t).Bufptr^[TextRec(t).BufPos]:=c;
  579. Inc(TextRec(t).BufPos);
  580. End;
  581. {$ifdef HASWIDECHAR}
  582. Procedure fpc_Write_Text_WideChar(Len : Longint;var t : Text;c : WideChar); iocheck; [Public,Alias:'FPC_WRITE_TEXT_WIDECHAR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  583. var
  584. ch : char;
  585. Begin
  586. If (InOutRes<>0) then
  587. exit;
  588. if (TextRec(t).mode<>fmOutput) Then
  589. begin
  590. if TextRec(t).mode=fmClosed then
  591. InOutRes:=103
  592. else
  593. InOutRes:=105;
  594. exit;
  595. end;
  596. If Len>1 Then
  597. WriteBlanks(t,Len-1);
  598. If TextRec(t).BufPos+1>=TextRec(t).BufSize Then
  599. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  600. ch:=c;
  601. TextRec(t).Bufptr^[TextRec(t).BufPos]:=ch;
  602. Inc(TextRec(t).BufPos);
  603. End;
  604. {$endif HASWIDECHAR}
  605. {*****************************************************************************
  606. Read(Ln)
  607. *****************************************************************************}
  608. Function NextChar(var f:Text;var s:string):Boolean;
  609. begin
  610. if TextRec(f).BufPos<TextRec(f).BufEnd then
  611. begin
  612. if length(s)<high(s) then
  613. begin
  614. inc(s[0]);
  615. s[length(s)]:=TextRec(f).BufPtr^[TextRec(f).BufPos];
  616. end;
  617. Inc(TextRec(f).BufPos);
  618. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  619. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  620. NextChar:=true;
  621. end
  622. else
  623. NextChar:=false;
  624. end;
  625. Function IgnoreSpaces(var f:Text):Boolean;
  626. {
  627. Removes all leading spaces,tab,eols from the input buffer, returns true if
  628. the buffer is empty
  629. }
  630. var
  631. s : string;
  632. begin
  633. s:='';
  634. IgnoreSpaces:=false;
  635. while TextRec(f).Bufptr^[TextRec(f).BufPos] in [#9,#10,#13,' '] do
  636. if not NextChar(f,s) then
  637. exit;
  638. IgnoreSpaces:=true;
  639. end;
  640. procedure ReadNumeric(var f:Text;var s:string);
  641. {
  642. Read numeric input, if buffer is empty then return True
  643. }
  644. begin
  645. repeat
  646. if not NextChar(f,s) then
  647. exit;
  648. until (length(s)=high(s)) or (TextRec(f).BufPtr^[TextRec(f).BufPos] in [#9,#10,#13,' ']);
  649. end;
  650. Procedure fpc_Read_End(var f:Text);[Public,Alias:'FPC_READ_END']; iocheck; {$ifdef hascompilerproc} compilerproc; {$endif}
  651. begin
  652. if TextRec(f).FlushFunc<>nil then
  653. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  654. end;
  655. Procedure fpc_ReadLn_End(var f : Text);[Public,Alias:'FPC_READLN_END']; iocheck; {$ifdef hascompilerproc} compilerproc; {$endif}
  656. var prev: char;
  657. Begin
  658. { Check error and if file is open and load buf if empty }
  659. If (InOutRes<>0) then
  660. exit;
  661. if (TextRec(f).mode<>fmInput) Then
  662. begin
  663. case TextRec(f).mode of
  664. fmOutPut,fmAppend:
  665. InOutRes:=104
  666. else
  667. InOutRes:=103;
  668. end;
  669. exit;
  670. end;
  671. if TextRec(f).BufPos>=TextRec(f).BufEnd Then
  672. begin
  673. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  674. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  675. { Flush if set }
  676. begin
  677. if (TextRec(f).FlushFunc<>nil) then
  678. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  679. exit;
  680. end;
  681. end;
  682. repeat
  683. prev := TextRec(f).BufPtr^[TextRec(f).BufPos];
  684. inc(TextRec(f).BufPos);
  685. { no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, }
  686. { #13#10 = Dos), so if we've got #10, we can safely exit }
  687. if prev = #10 then
  688. exit;
  689. if TextRec(f).BufPos>=TextRec(f).BufEnd Then
  690. begin
  691. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  692. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  693. { Flush if set }
  694. begin
  695. if (TextRec(f).FlushFunc<>nil) then
  696. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  697. exit;
  698. end;
  699. end;
  700. if (prev=#13) then
  701. { is there also a #10 after it? }
  702. begin
  703. if (TextRec(f).BufPtr^[TextRec(f).BufPos]=#10) then
  704. { yes, skip that one as well }
  705. inc(TextRec(f).BufPos);
  706. exit;
  707. end;
  708. until false;
  709. End;
  710. Function ReadPCharLen(var f:Text;s:pchar;maxlen:longint):longint;
  711. var
  712. sPos,len : Longint;
  713. p,startp,maxp : pchar;
  714. Begin
  715. ReadPCharLen:=0;
  716. { Check error and if file is open }
  717. If (InOutRes<>0) then
  718. exit;
  719. if (TextRec(f).mode<>fmInput) Then
  720. begin
  721. case TextRec(f).mode of
  722. fmOutPut,fmAppend:
  723. InOutRes:=104
  724. else
  725. InOutRes:=103;
  726. end;
  727. exit;
  728. end;
  729. { Read maximal until Maxlen is reached }
  730. sPos:=0;
  731. repeat
  732. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  733. begin
  734. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  735. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  736. break;
  737. end;
  738. p:=@TextRec(f).Bufptr^[TextRec(f).BufPos];
  739. if SPos+TextRec(f).BufEnd-TextRec(f).BufPos>MaxLen then
  740. maxp:=@TextRec(f).BufPtr^[TextRec(f).BufPos+MaxLen-SPos]
  741. else
  742. maxp:=@TextRec(f).Bufptr^[TextRec(f).BufEnd];
  743. startp:=p;
  744. { search linefeed }
  745. while (p<maxp) and not(P^ in [#10,#13]) do
  746. inc(p);
  747. { calculate read bytes }
  748. len:=p-startp;
  749. inc(TextRec(f).BufPos,Len);
  750. Move(startp^,s[sPos],Len);
  751. inc(sPos,Len);
  752. { was it a LF or CR? then leave }
  753. if (spos=MaxLen) or
  754. ((p<maxp) and (p^ in [#10,#13])) then
  755. break;
  756. until false;
  757. ReadPCharLen:=spos;
  758. End;
  759. Procedure fpc_Read_Text_ShortStr(var f : Text;var s : String); iocheck; [Public,Alias:'FPC_READ_TEXT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  760. Begin
  761. s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
  762. End;
  763. Procedure fpc_Read_Text_PChar_As_Pointer(var f : Text;var s : PChar); iocheck; [Public,Alias:'FPC_READ_TEXT_PCHAR_AS_POINTER']; {$ifdef hascompilerproc} compilerproc; {$endif}
  764. Begin
  765. pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
  766. End;
  767. Procedure fpc_Read_Text_PChar_As_Array(var f : Text;var s : array of char); iocheck; [Public,Alias:'FPC_READ_TEXT_PCHAR_AS_ARRAY']; {$ifdef hascompilerproc} compilerproc; {$endif}
  768. var
  769. len: longint;
  770. Begin
  771. len := ReadPCharLen(f,pchar(@s),high(s)+1);
  772. if len < high(s)+1 then
  773. s[len] := #0;
  774. End;
  775. Procedure fpc_Read_Text_AnsiStr(var f : Text;var s : AnsiString); iocheck; [Public,Alias:'FPC_READ_TEXT_ANSISTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  776. var
  777. slen,len : longint;
  778. Begin
  779. slen:=0;
  780. Repeat
  781. // SetLength will reallocate the length.
  782. SetLength(S,slen+255);
  783. len:=ReadPCharLen(f,pchar(Pointer(S)+slen),255);
  784. inc(slen,len);
  785. Until len<255;
  786. // Set actual length
  787. SetLength(S,Slen);
  788. End;
  789. {$ifdef hascompilerproc}
  790. procedure fpc_Read_Text_Char(var f : Text; var c: char); iocheck; [Public,Alias:'FPC_READ_TEXT_CHAR'];compilerproc;
  791. {$else hascompilerproc}
  792. Function fpc_Read_Text_Char(var f : Text):char;[Public,Alias:'FPC_READ_TEXT_CHAR'];
  793. {$endif hascompilerproc}
  794. Begin
  795. {$ifdef hascompilerproc}
  796. c:=#0;
  797. {$else hascompilerproc}
  798. fpc_Read_Text_Char:=#0;
  799. {$endif hascompilerproc}
  800. { Check error and if file is open }
  801. If (InOutRes<>0) then
  802. exit;
  803. if (TextRec(f).mode<>fmInput) Then
  804. begin
  805. case TextRec(f).mode of
  806. fmOutPut,fmAppend:
  807. InOutRes:=104
  808. else
  809. InOutRes:=103;
  810. end;
  811. exit;
  812. end;
  813. { Read next char or EOF }
  814. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  815. begin
  816. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  817. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  818. {$ifdef hascompilerproc}
  819. begin
  820. c := #26;
  821. exit;
  822. end;
  823. {$else hascompilerproc}
  824. exit(#26);
  825. {$endif hascompilerproc}
  826. end;
  827. {$ifdef hascompilerproc}
  828. c:=TextRec(f).Bufptr^[TextRec(f).BufPos];
  829. {$else hascompilerproc}
  830. fpc_Read_Text_Char:=TextRec(f).Bufptr^[TextRec(f).BufPos];
  831. {$endif hascompilerproc}
  832. inc(TextRec(f).BufPos);
  833. end;
  834. {$ifdef hascompilerproc}
  835. Procedure fpc_Read_Text_SInt(var f : Text; var l : ValSInt); iocheck; [Public,Alias:'FPC_READ_TEXT_SINT']; compilerproc;
  836. {$else hascompilerproc}
  837. Function fpc_Read_Text_SInt(var f : Text):ValSInt;[Public,Alias:'FPC_READ_TEXT_SINT'];
  838. {$endif hascompilerproc}
  839. var
  840. hs : String;
  841. code : Longint;
  842. Begin
  843. {$ifdef hascompilerproc}
  844. l:=0;
  845. {$else hascompilerproc}
  846. fpc_Read_Text_SInt:=0;
  847. {$endif hascompilerproc}
  848. { Leave if error or not open file, else check for empty buf }
  849. If (InOutRes<>0) then
  850. exit;
  851. if (TextRec(f).mode<>fmInput) Then
  852. begin
  853. case TextRec(f).mode of
  854. fmOutPut,fmAppend:
  855. InOutRes:=104
  856. else
  857. InOutRes:=103;
  858. end;
  859. exit;
  860. end;
  861. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  862. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  863. hs:='';
  864. if IgnoreSpaces(f) then
  865. ReadNumeric(f,hs);
  866. {$ifdef hascompilerproc}
  867. Val(hs,l,code);
  868. {$else hascompilerproc}
  869. Val(hs,fpc_Read_Text_SInt,code);
  870. {$endif hascompilerproc}
  871. If code<>0 Then
  872. InOutRes:=106;
  873. End;
  874. {$ifdef hascompilerproc}
  875. Procedure fpc_Read_Text_UInt(var f : Text; var u : ValUInt); iocheck; [Public,Alias:'FPC_READ_TEXT_UINT']; compilerproc;
  876. {$else hascompilerproc}
  877. Function fpc_Read_Text_UInt(var f : Text):ValUInt;[Public,Alias:'FPC_READ_TEXT_UINT'];
  878. {$endif hascompilerproc}
  879. var
  880. hs : String;
  881. code : longint;
  882. Begin
  883. {$ifdef hascompilerproc}
  884. u:=0;
  885. {$else hascompilerproc}
  886. fpc_Read_Text_UInt:=0;
  887. {$endif hascompilerproc}
  888. { Leave if error or not open file, else check for empty buf }
  889. If (InOutRes<>0) then
  890. exit;
  891. if (TextRec(f).mode<>fmInput) Then
  892. begin
  893. case TextRec(f).mode of
  894. fmOutPut,fmAppend:
  895. InOutRes:=104
  896. else
  897. InOutRes:=103;
  898. end;
  899. exit;
  900. end;
  901. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  902. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  903. hs:='';
  904. if IgnoreSpaces(f) then
  905. ReadNumeric(f,hs);
  906. {$ifdef hascompilerproc}
  907. val(hs,u,code);
  908. {$else hascompilerproc}
  909. val(hs,fpc_Read_Text_UInt,code);
  910. {$endif hascompilerproc}
  911. If code<>0 Then
  912. InOutRes:=106;
  913. End;
  914. {$ifdef hascompilerproc}
  915. procedure fpc_Read_Text_Float(var f : Text; var v : ValReal); iocheck; [Public,Alias:'FPC_READ_TEXT_FLOAT']; compilerproc;
  916. {$else hascompilerproc}
  917. Function fpc_Read_Text_Float(var f : Text):ValReal;[Public,Alias:'FPC_READ_TEXT_FLOAT'];
  918. {$endif hascompilerproc}
  919. var
  920. hs : string;
  921. code : Word;
  922. begin
  923. {$ifdef hascompilerproc}
  924. v:=0.0;
  925. {$else hascompilerproc}
  926. fpc_Read_Text_Float:=0.0;
  927. {$endif hascompilerproc}
  928. { Leave if error or not open file, else check for empty buf }
  929. If (InOutRes<>0) then
  930. exit;
  931. if (TextRec(f).mode<>fmInput) Then
  932. begin
  933. case TextRec(f).mode of
  934. fmOutPut,fmAppend:
  935. InOutRes:=104
  936. else
  937. InOutRes:=103;
  938. end;
  939. exit;
  940. end;
  941. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  942. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  943. hs:='';
  944. if IgnoreSpaces(f) then
  945. ReadNumeric(f,hs);
  946. {$ifdef hascompilerproc}
  947. val(hs,v,code);
  948. {$else hascompilerproc}
  949. val(hs,fpc_Read_Text_Float,code);
  950. {$endif hascompilerproc}
  951. If code<>0 Then
  952. InOutRes:=106;
  953. end;
  954. {$ifdef hascompilerproc}
  955. procedure fpc_Read_Text_QWord(var f : text; var q : qword); iocheck; [public,alias:'FPC_READ_TEXT_QWORD']; compilerproc;
  956. {$else hascompilerproc}
  957. function fpc_Read_Text_QWord(var f : text) : qword;[public,alias:'FPC_READ_TEXT_QWORD'];
  958. {$endif hascompilerproc}
  959. var
  960. hs : String;
  961. code : longint;
  962. Begin
  963. {$ifdef hascompilerproc}
  964. q:=0;
  965. {$else hascompilerproc}
  966. fpc_Read_Text_QWord:=0;
  967. {$endif hascompilerproc}
  968. { Leave if error or not open file, else check for empty buf }
  969. If (InOutRes<>0) then
  970. exit;
  971. if (TextRec(f).mode<>fmInput) Then
  972. begin
  973. case TextRec(f).mode of
  974. fmOutPut,fmAppend:
  975. InOutRes:=104
  976. else
  977. InOutRes:=103;
  978. end;
  979. exit;
  980. end;
  981. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  982. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  983. hs:='';
  984. if IgnoreSpaces(f) then
  985. ReadNumeric(f,hs);
  986. {$ifdef hascompilerproc}
  987. val(hs,q,code);
  988. {$else hascompilerproc}
  989. val(hs,fpc_Read_Text_QWord,code);
  990. {$endif hascompilerproc}
  991. If code<>0 Then
  992. InOutRes:=106;
  993. End;
  994. {$ifdef hascompilerproc}
  995. procedure fpc_Read_Text_Int64(var f : text; var i : int64); iocheck; [public,alias:'FPC_READ_TEXT_INT64']; compilerproc;
  996. {$else hascompilerproc}
  997. function fpc_Read_Text_Int64(var f : text) : int64;[public,alias:'FPC_READ_TEXT_INT64']; {$ifdef hascompilerproc} compilerproc; {$endif}
  998. {$endif hascompilerproc}
  999. var
  1000. hs : String;
  1001. code : Longint;
  1002. Begin
  1003. {$ifdef hascompilerproc}
  1004. i:=0;
  1005. {$else hascompilerproc}
  1006. fpc_Read_Text_Int64:=0;
  1007. {$endif hascompilerproc}
  1008. { Leave if error or not open file, else check for empty buf }
  1009. If (InOutRes<>0) then
  1010. exit;
  1011. if (TextRec(f).mode<>fmInput) Then
  1012. begin
  1013. case TextRec(f).mode of
  1014. fmOutPut,fmAppend:
  1015. InOutRes:=104
  1016. else
  1017. InOutRes:=103;
  1018. end;
  1019. exit;
  1020. end;
  1021. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1022. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  1023. hs:='';
  1024. if IgnoreSpaces(f) then
  1025. ReadNumeric(f,hs);
  1026. {$ifdef hascompilerproc}
  1027. Val(hs,i,code);
  1028. {$else hascompilerproc}
  1029. Val(hs,fpc_Read_Text_Int64,code);
  1030. {$endif hascompilerproc}
  1031. If code<>0 Then
  1032. InOutRes:=106;
  1033. End;
  1034. {*****************************************************************************
  1035. Initializing
  1036. *****************************************************************************}
  1037. procedure OpenStdIO(var f:text;mode,hdl:longint);
  1038. begin
  1039. Assign(f,'');
  1040. TextRec(f).Handle:=hdl;
  1041. TextRec(f).Mode:=mode;
  1042. TextRec(f).Closefunc:=@FileCloseFunc;
  1043. case mode of
  1044. fmInput :
  1045. TextRec(f).InOutFunc:=@FileReadFunc;
  1046. fmOutput :
  1047. begin
  1048. TextRec(f).InOutFunc:=@FileWriteFunc;
  1049. TextRec(f).FlushFunc:=@FileWriteFunc;
  1050. end;
  1051. else
  1052. HandleError(102);
  1053. end;
  1054. end;
  1055. {
  1056. $Log$
  1057. Revision 1.14 2001-08-23 14:28:36 jonas
  1058. + tempcreate/ref/delete nodes (allows the use of temps in the
  1059. resulttype and first pass)
  1060. * made handling of read(ln)/write(ln) processor independent
  1061. * moved processor independent handling for str and reset/rewrite-typed
  1062. from firstpass to resulttype pass
  1063. * changed names of helpers in text.inc to be generic for use as
  1064. compilerprocs + added "iocheck" directive for most of them
  1065. * reading of ordinals is done by procedures instead of functions
  1066. because otherwise FPC_IOCHECK overwrote the result before it could
  1067. be stored elsewhere (range checking still works)
  1068. * compilerprocs can now be used in the system unit before they are
  1069. implemented
  1070. * added note to errore.msg that booleans can't be read using read/readln
  1071. Revision 1.13 2001/08/22 20:49:18 peter
  1072. * regenerated
  1073. Revision 1.12 2001/08/19 11:23:10 peter
  1074. * read_array fix merged
  1075. Revision 1.11 2001/07/21 15:53:28 jonas
  1076. * really fixed write_array this time :/ (merged)
  1077. Revision 1.10 2001/07/16 13:53:21 jonas
  1078. * correctly fixed potential buffer overrun in write_array
  1079. Revision 1.9 2001/07/08 21:00:18 peter
  1080. * various widestring updates, it works now mostly without charset
  1081. mapping supported
  1082. Revision 1.8 2001/06/27 21:37:38 peter
  1083. * v10 merges
  1084. Revision 1.7 2001/06/04 11:43:51 peter
  1085. * Formal const to var fixes
  1086. * Hexstr(int64) added
  1087. Revision 1.6 2001/04/08 13:21:30 jonas
  1088. * fixed potential buffer overflow in FPC_WRITE_TEXT_PCHAR_AS_ARRAY (merged)
  1089. Revision 1.5 2001/03/21 23:29:40 florian
  1090. + sLineBreak and misc. stuff for Kylix compatiblity
  1091. Revision 1.4 2000/11/23 13:14:02 jonas
  1092. * fix for web bug 1210 from Peter (merged)
  1093. Revision 1.3 2000/07/14 10:33:10 michael
  1094. + Conditionals fixed
  1095. Revision 1.2 2000/07/13 11:33:46 michael
  1096. + removed logs
  1097. }