text.inc 29 KB

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