text.inc 28 KB

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