text.inc 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910
  1. {
  2. This file is part of the Free Pascal Run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {****************************************************************************
  11. subroutines For TextFile handling
  12. ****************************************************************************}
  13. Procedure FileCloseFunc(Var t:TextRec);
  14. Begin
  15. Do_Close(t.Handle);
  16. t.Handle:=UnusedHandle;
  17. End;
  18. Procedure FileReadFunc(var t:TextRec);
  19. Begin
  20. t.BufEnd:=Do_Read(t.Handle,t.Bufptr,t.BufSize);
  21. t.BufPos:=0;
  22. End;
  23. Procedure FileWriteFunc(var t:TextRec);
  24. var
  25. i : longint;
  26. Begin
  27. { prevent unecessary system call }
  28. if t.BufPos=0 then
  29. exit;
  30. i:=Do_Write(t.Handle,t.Bufptr,t.BufPos);
  31. if i<>t.BufPos then
  32. InOutRes:=101;
  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:=$10000;
  41. fmOutput : Flags:=$11001;
  42. fmAppend : Flags:=$10101;
  43. else
  44. begin
  45. InOutRes:=102;
  46. exit;
  47. end;
  48. End;
  49. Do_Open(t,PChar(@t.Name),Flags);
  50. t.CloseFunc:=@FileCloseFunc;
  51. t.FlushFunc:=nil;
  52. if t.Mode=fmInput then
  53. t.InOutFunc:=@FileReadFunc
  54. else
  55. begin
  56. t.InOutFunc:=@FileWriteFunc;
  57. { Only install flushing if its a NOT a file, and only check if there
  58. was no error opening the file, because else we always get a bad
  59. file handle error 6 (PFV) }
  60. if (InOutRes=0) and
  61. Do_Isdevice(t.Handle) then
  62. t.FlushFunc:=@FileWriteFunc;
  63. end;
  64. End;
  65. Procedure Assign(out t:Text;const s:String);
  66. Begin
  67. FillChar(t,SizeOf(TextRec),0);
  68. { only set things that are not zero }
  69. TextRec(t).Handle:=UnusedHandle;
  70. TextRec(t).mode:=fmClosed;
  71. TextRec(t).BufSize:=TextRecBufSize;
  72. TextRec(t).Bufptr:=@TextRec(t).Buffer;
  73. TextRec(t).OpenFunc:=@FileOpenFunc;
  74. Case DefaultTextLineBreakStyle Of
  75. tlbsLF: TextRec(t).LineEnd := #10;
  76. tlbsCRLF: TextRec(t).LineEnd := #13#10;
  77. tlbsCR: TextRec(t).LineEnd := #13;
  78. End;
  79. Move(s[1],TextRec(t).Name,Length(s));
  80. End;
  81. Procedure Assign(out t:Text;p:pchar);
  82. begin
  83. Assign(t,StrPas(p));
  84. end;
  85. Procedure Assign(out t:Text;c:char);
  86. begin
  87. Assign(t,string(c));
  88. end;
  89. Procedure Close(var t : Text);[IOCheck];
  90. Begin
  91. if InOutRes<>0 then
  92. Exit;
  93. case TextRec(t).mode of
  94. fmInput,fmOutput,fmAppend:
  95. Begin
  96. { Write pending buffer }
  97. If Textrec(t).Mode=fmoutput then
  98. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  99. {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
  100. { Only close functions not connected to stdout.}
  101. If ((TextRec(t).Handle<>StdInputHandle) and
  102. (TextRec(t).Handle<>StdOutputHandle) and
  103. (TextRec(t).Handle<>StdErrorHandle)) Then
  104. {$endif FPC_HAS_FEATURE_CONSOLEIO}
  105. FileFunc(TextRec(t).CloseFunc)(TextRec(t));
  106. TextRec(t).mode := fmClosed;
  107. { Reset buffer for safety }
  108. TextRec(t).BufPos:=0;
  109. TextRec(t).BufEnd:=0;
  110. End
  111. else inOutRes := 103;
  112. End;
  113. End;
  114. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  115. Begin
  116. Case TextRec(t).mode Of {This gives the fastest code}
  117. fmInput,fmOutput,fmInOut : Close(t);
  118. fmClosed : ;
  119. else
  120. Begin
  121. InOutRes:=102;
  122. exit;
  123. End;
  124. End;
  125. TextRec(t).mode:=mode;
  126. TextRec(t).bufpos:=0;
  127. TextRec(t).bufend:=0;
  128. FileFunc(TextRec(t).OpenFunc)(TextRec(t));
  129. { reset the mode to closed when an error has occured }
  130. if InOutRes<>0 then
  131. TextRec(t).mode:=fmClosed;
  132. End;
  133. Procedure Rewrite(var t : Text);[IOCheck];
  134. Begin
  135. If InOutRes<>0 then
  136. exit;
  137. OpenText(t,fmOutput,1);
  138. End;
  139. Procedure Reset(var t : Text);[IOCheck];
  140. Begin
  141. If InOutRes<>0 then
  142. exit;
  143. OpenText(t,fmInput,0);
  144. End;
  145. Procedure Append(var t : Text);[IOCheck];
  146. Begin
  147. If InOutRes<>0 then
  148. exit;
  149. OpenText(t,fmAppend,1);
  150. End;
  151. Procedure Flush(var t : Text);[IOCheck];
  152. Begin
  153. If InOutRes<>0 then
  154. exit;
  155. if TextRec(t).mode<>fmOutput then
  156. begin
  157. if TextRec(t).mode=fmInput then
  158. InOutRes:=105
  159. else
  160. InOutRes:=103;
  161. exit;
  162. end;
  163. { Not the flushfunc but the inoutfunc should be used, because that
  164. writes the data, flushfunc doesn't need to be assigned }
  165. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  166. End;
  167. Procedure Erase(var t:Text);[IOCheck];
  168. Begin
  169. If InOutRes <> 0 then
  170. exit;
  171. If TextRec(t).mode=fmClosed Then
  172. Do_Erase(PChar(@TextRec(t).Name));
  173. End;
  174. Procedure Rename(var t : text;p:pchar);[IOCheck];
  175. Begin
  176. If InOutRes <> 0 then
  177. exit;
  178. If TextRec(t).mode=fmClosed Then
  179. Begin
  180. Do_Rename(PChar(@TextRec(t).Name),p);
  181. { check error code of do_rename }
  182. If InOutRes = 0 then
  183. Move(p^,TextRec(t).Name,StrLen(p)+1);
  184. End;
  185. End;
  186. Procedure Rename(var t : Text;const s : string);[IOCheck];
  187. var
  188. p : array[0..255] Of Char;
  189. Begin
  190. If InOutRes <> 0 then
  191. exit;
  192. Move(s[1],p,Length(s));
  193. p[Length(s)]:=#0;
  194. Rename(t,Pchar(@p));
  195. End;
  196. Procedure Rename(var t : Text;c : char);[IOCheck];
  197. var
  198. p : array[0..1] Of Char;
  199. Begin
  200. If InOutRes <> 0 then
  201. exit;
  202. p[0]:=c;
  203. p[1]:=#0;
  204. Rename(t,Pchar(@p));
  205. End;
  206. Function Eof(Var t: Text): Boolean;[IOCheck];
  207. Begin
  208. If (InOutRes<>0) then
  209. exit(true);
  210. if (TextRec(t).mode<>fmInput) Then
  211. begin
  212. if TextRec(t).mode=fmOutput then
  213. InOutRes:=104
  214. else
  215. InOutRes:=103;
  216. exit(true);
  217. end;
  218. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  219. begin
  220. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  221. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  222. exit(true);
  223. end;
  224. Eof:=CtrlZMarksEOF and (TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
  225. end;
  226. Function Eof:Boolean;
  227. Begin
  228. Eof:=Eof(Input);
  229. End;
  230. Function SeekEof (Var t : Text) : Boolean;
  231. var
  232. oldfilepos : Int64;
  233. oldbufpos, oldbufend : SizeInt;
  234. reads: longint;
  235. isdevice: boolean;
  236. Begin
  237. If (InOutRes<>0) then
  238. exit(true);
  239. if (TextRec(t).mode<>fmInput) Then
  240. begin
  241. if TextRec(t).mode=fmOutPut then
  242. InOutRes:=104
  243. else
  244. InOutRes:=103;
  245. exit(true);
  246. end;
  247. { try to save the current position in the file, seekeof() should not move }
  248. { the current file position (JM) }
  249. oldbufpos := TextRec(t).BufPos;
  250. oldbufend := TextRec(t).BufEnd;
  251. reads := 0;
  252. oldfilepos := -1;
  253. isdevice := Do_IsDevice(TextRec(t).handle);
  254. repeat
  255. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  256. begin
  257. { signal that the we will have to do a seek }
  258. inc(reads);
  259. if not isdevice and
  260. (reads = 1) then
  261. begin
  262. oldfilepos := Do_FilePos(TextRec(t).handle) - TextRec(t).BufEnd;
  263. InOutRes:=0;
  264. end;
  265. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  266. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  267. begin
  268. { if we only did a read in which we didn't read anything, the }
  269. { old buffer is still valid and we can simply restore the }
  270. { pointers (JM) }
  271. dec(reads);
  272. SeekEof := true;
  273. break;
  274. end;
  275. end;
  276. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  277. #26 :
  278. if CtrlZMarksEOF then
  279. begin
  280. SeekEof := true;
  281. break;
  282. end;
  283. #10,#13,#9,' ' :
  284. ;
  285. else
  286. begin
  287. SeekEof := false;
  288. break;
  289. end;
  290. end;
  291. inc(TextRec(t).BufPos);
  292. until false;
  293. { restore file position if not working with a device }
  294. if not isdevice then
  295. { if we didn't modify the buffer, simply restore the BufPos and BufEnd }
  296. { (the latter because it's now probably set to zero because nothing was }
  297. { was read anymore) }
  298. if (reads = 0) then
  299. begin
  300. TextRec(t).BufPos:=oldbufpos;
  301. TextRec(t).BufEnd:=oldbufend;
  302. end
  303. { otherwise return to the old filepos and reset the buffer }
  304. else
  305. begin
  306. do_seek(TextRec(t).handle,oldfilepos);
  307. InOutRes:=0;
  308. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  309. TextRec(t).BufPos:=oldbufpos;
  310. end;
  311. End;
  312. Function SeekEof : Boolean;
  313. Begin
  314. SeekEof:=SeekEof(Input);
  315. End;
  316. Function Eoln(var t:Text) : Boolean;
  317. Begin
  318. If (InOutRes<>0) then
  319. exit(true);
  320. if (TextRec(t).mode<>fmInput) Then
  321. begin
  322. if TextRec(t).mode=fmOutPut then
  323. InOutRes:=104
  324. else
  325. InOutRes:=103;
  326. exit(true);
  327. end;
  328. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  329. begin
  330. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  331. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  332. exit(true);
  333. end;
  334. if CtrlZMarksEOF and (TextRec (T).BufPtr^[TextRec (T).BufPos] = #26) then
  335. exit (true);
  336. Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
  337. End;
  338. Function Eoln : Boolean;
  339. Begin
  340. Eoln:=Eoln(Input);
  341. End;
  342. Function SeekEoln (Var t : Text) : Boolean;
  343. Begin
  344. If (InOutRes<>0) then
  345. exit(true);
  346. if (TextRec(t).mode<>fmInput) Then
  347. begin
  348. if TextRec(t).mode=fmOutput then
  349. InOutRes:=104
  350. else
  351. InOutRes:=103;
  352. exit(true);
  353. end;
  354. repeat
  355. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  356. begin
  357. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  358. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  359. exit(true);
  360. end;
  361. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  362. #26: if CtrlZMarksEOF then
  363. exit (true);
  364. #10,#13 : exit(true);
  365. #9,' ' : ;
  366. else
  367. exit(false);
  368. end;
  369. inc(TextRec(t).BufPos);
  370. until false;
  371. End;
  372. Function SeekEoln : Boolean;
  373. Begin
  374. SeekEoln:=SeekEoln(Input);
  375. End;
  376. Procedure SetTextBuf(Var F : Text; Var Buf; Size : SizeInt);
  377. Begin
  378. TextRec(f).BufPtr:=@Buf;
  379. TextRec(f).BufSize:=Size;
  380. TextRec(f).BufPos:=0;
  381. TextRec(f).BufEnd:=0;
  382. End;
  383. Procedure SetTextLineEnding(Var f:Text; Ending:string);
  384. Begin
  385. TextRec(F).LineEnd:=Ending;
  386. End;
  387. Function fpc_get_input:PText;compilerproc;
  388. begin
  389. fpc_get_input:=@Input;
  390. end;
  391. Function fpc_get_output:PText;compilerproc;
  392. begin
  393. fpc_get_output:=@Output;
  394. end;
  395. {*****************************************************************************
  396. Write(Ln)
  397. *****************************************************************************}
  398. Procedure fpc_WriteBuffer(var f:Text;const b;len:SizeInt);
  399. var
  400. p : pchar;
  401. left,
  402. idx : SizeInt;
  403. begin
  404. p:=pchar(@b);
  405. idx:=0;
  406. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  407. while len>left do
  408. begin
  409. move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],left);
  410. dec(len,left);
  411. inc(idx,left);
  412. inc(TextRec(f).BufPos,left);
  413. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  414. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  415. end;
  416. move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],len);
  417. inc(TextRec(f).BufPos,len);
  418. end;
  419. Procedure fpc_WriteBlanks(var f:Text;len:longint);
  420. var
  421. left : longint;
  422. begin
  423. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  424. while len>left do
  425. begin
  426. FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],left,' ');
  427. dec(len,left);
  428. inc(TextRec(f).BufPos,left);
  429. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  430. left:=TextRec(f).BufSize-TextRec(f).BufPos;
  431. end;
  432. FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],len,' ');
  433. inc(TextRec(f).BufPos,len);
  434. end;
  435. Procedure fpc_Write_End(var f:Text); iocheck; compilerproc;
  436. begin
  437. if TextRec(f).FlushFunc<>nil then
  438. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  439. end;
  440. Procedure fpc_Writeln_End(var f:Text); iocheck; compilerproc;
  441. begin
  442. If InOutRes <> 0 then exit;
  443. case TextRec(f).mode of
  444. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  445. begin
  446. { Write EOL }
  447. fpc_WriteBuffer(f,TextRec(f).LineEnd[1],length(TextRec(f).LineEnd));
  448. { Flush }
  449. if TextRec(f).FlushFunc<>nil then
  450. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  451. end;
  452. fmInput: InOutRes:=105
  453. else InOutRes:=103;
  454. end;
  455. end;
  456. Procedure fpc_Write_Text_ShortStr(Len : Longint;var f : Text;const s : String); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SHORTSTR']; compilerproc;
  457. Begin
  458. If (InOutRes<>0) then
  459. exit;
  460. case TextRec(f).mode of
  461. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  462. begin
  463. If Len>Length(s) Then
  464. fpc_WriteBlanks(f,Len-Length(s));
  465. fpc_WriteBuffer(f,s[1],Length(s));
  466. end;
  467. fmInput: InOutRes:=105
  468. else InOutRes:=103;
  469. end;
  470. End;
  471. Procedure fpc_Write_Text_ShortStr_Iso(Len : Longint;var f : Text;const s : String); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SHORTSTR_ISO']; compilerproc;
  472. Begin
  473. If (InOutRes<>0) then
  474. exit;
  475. case TextRec(f).mode of
  476. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  477. begin
  478. { default value? }
  479. If Len=-1 then
  480. Len:=length(s);
  481. If Len>Length(s) Then
  482. begin
  483. fpc_WriteBlanks(f,Len-Length(s));
  484. fpc_WriteBuffer(f,s[1],Length(s));
  485. end
  486. else
  487. fpc_WriteBuffer(f,s[1],Len);
  488. end;
  489. fmInput: InOutRes:=105
  490. else InOutRes:=103;
  491. end;
  492. End;
  493. { provide local access to write_str }
  494. procedure Write_Str(Len : Longint;var f : Text;const s : String); iocheck; [external name 'FPC_WRITE_TEXT_SHORTSTR'];
  495. { provide local access to write_str_iso }
  496. procedure Write_Str_Iso(Len : Longint;var f : Text;const s : String); iocheck; [external name 'FPC_WRITE_TEXT_SHORTSTR_ISO'];
  497. Procedure fpc_Write_Text_Pchar_as_Array(Len : Longint;var f : Text;const s : array of char; zerobased: boolean = true); iocheck; compilerproc;
  498. var
  499. ArrayLen : longint;
  500. p : pchar;
  501. Begin
  502. If (InOutRes<>0) then
  503. exit;
  504. case TextRec(f).mode of
  505. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  506. begin
  507. p:=pchar(@s);
  508. if zerobased then
  509. begin
  510. { can't use StrLen, since that one could try to read past the end }
  511. { of the heap (JM) }
  512. ArrayLen:=IndexByte(p^,high(s)+1,0);
  513. { IndexByte returns -1 if not found (JM) }
  514. if ArrayLen = -1 then
  515. ArrayLen := high(s)+1;
  516. end
  517. else
  518. ArrayLen := high(s)+1;
  519. If Len>ArrayLen Then
  520. fpc_WriteBlanks(f,Len-ArrayLen);
  521. fpc_WriteBuffer(f,p^,ArrayLen);
  522. end;
  523. fmInput: InOutRes:=105
  524. else InOutRes:=103;
  525. end;
  526. End;
  527. Procedure fpc_Write_Text_Pchar_as_Array_Iso(Len : Longint;var f : Text;const s : array of char; zerobased: boolean = true); iocheck; compilerproc;
  528. var
  529. ArrayLen : longint;
  530. p : pchar;
  531. Begin
  532. If (InOutRes<>0) then
  533. exit;
  534. case TextRec(f).mode of
  535. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  536. begin
  537. p:=pchar(@s);
  538. if zerobased then
  539. begin
  540. { can't use StrLen, since that one could try to read past the end }
  541. { of the heap (JM) }
  542. ArrayLen:=IndexByte(p^,high(s)+1,0);
  543. { IndexByte returns -1 if not found (JM) }
  544. if ArrayLen = -1 then
  545. ArrayLen := high(s)+1;
  546. end
  547. else
  548. ArrayLen := high(s)+1;
  549. { default value? }
  550. If Len=-1 then
  551. Len:=ArrayLen;
  552. If Len>ArrayLen Then
  553. begin
  554. fpc_WriteBlanks(f,Len-ArrayLen);
  555. fpc_WriteBuffer(f,p^,ArrayLen);
  556. end
  557. else
  558. fpc_WriteBuffer(f,p^,Len);
  559. end;
  560. fmInput: InOutRes:=105
  561. else InOutRes:=103;
  562. end;
  563. End;
  564. Procedure fpc_Write_Text_PChar_As_Pointer(Len : Longint;var f : Text;p : PChar); iocheck; compilerproc;
  565. var
  566. PCharLen : longint;
  567. Begin
  568. If (p=nil) or (InOutRes<>0) then
  569. exit;
  570. case TextRec(f).mode of
  571. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  572. begin
  573. PCharLen:=StrLen(p);
  574. If Len>PCharLen Then
  575. fpc_WriteBlanks(f,Len-PCharLen);
  576. fpc_WriteBuffer(f,p^,PCharLen);
  577. end;
  578. fmInput: InOutRes:=105
  579. else InOutRes:=103;
  580. end;
  581. End;
  582. Procedure fpc_Write_Text_AnsiStr (Len : Longint; Var f : Text; const S : RawByteString); iocheck; [Public,alias:'FPC_WRITE_TEXT_ANSISTR']; compilerproc;
  583. {
  584. Writes a AnsiString to the Text file T
  585. }
  586. var
  587. SLen : longint;
  588. begin
  589. If (InOutRes<>0) then
  590. exit;
  591. case TextRec(f).mode of
  592. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  593. begin
  594. SLen:=Length(s);
  595. If Len>SLen Then
  596. fpc_WriteBlanks(f,Len-SLen);
  597. if slen > 0 then
  598. fpc_WriteBuffer(f,PChar(S)^,SLen);
  599. end;
  600. fmInput: InOutRes:=105
  601. else InOutRes:=103;
  602. end;
  603. end;
  604. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  605. Procedure fpc_Write_Text_UnicodeStr (Len : Longint; Var f : Text; const S : UnicodeString); iocheck; compilerproc;
  606. {
  607. Writes a UnicodeString to the Text file T
  608. }
  609. var
  610. SLen : longint;
  611. a: ansistring;
  612. begin
  613. If (pointer(S)=nil) or (InOutRes<>0) then
  614. exit;
  615. case TextRec(f).mode of
  616. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  617. begin
  618. SLen:=Length(s);
  619. If Len>SLen Then
  620. fpc_WriteBlanks(f,Len-SLen);
  621. a:=s;
  622. { length(a) can be > slen, e.g. after utf-16 -> utf-8 }
  623. fpc_WriteBuffer(f,pchar(a)^,length(a));
  624. end;
  625. fmInput: InOutRes:=105
  626. else InOutRes:=103;
  627. end;
  628. end;
  629. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  630. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  631. Procedure fpc_Write_Text_WideStr (Len : Longint; Var f : Text; const S : WideString); iocheck; compilerproc;
  632. {
  633. Writes a WideString to the Text file T
  634. }
  635. var
  636. SLen : longint;
  637. a: ansistring;
  638. begin
  639. If (pointer(S)=nil) or (InOutRes<>0) then
  640. exit;
  641. case TextRec(f).mode of
  642. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  643. begin
  644. SLen:=Length(s);
  645. If Len>SLen Then
  646. fpc_WriteBlanks(f,Len-SLen);
  647. a:=s;
  648. { length(a) can be > slen, e.g. after utf-16 -> utf-8 }
  649. fpc_WriteBuffer(f,pchar(a)^,length(a));
  650. end;
  651. fmInput: InOutRes:=105
  652. else InOutRes:=103;
  653. end;
  654. end;
  655. {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
  656. Procedure fpc_Write_Text_SInt(Len : Longint;var t : Text;l : ValSInt); iocheck; compilerproc;
  657. var
  658. s : String;
  659. Begin
  660. If (InOutRes<>0) then
  661. exit;
  662. Str(l,s);
  663. Write_Str(Len,t,s);
  664. End;
  665. Procedure fpc_Write_Text_UInt(Len : Longint;var t : Text;l : ValUInt); iocheck; compilerproc;
  666. var
  667. s : String;
  668. Begin
  669. If (InOutRes<>0) then
  670. exit;
  671. Str(L,s);
  672. Write_Str(Len,t,s);
  673. End;
  674. Procedure fpc_Write_Text_SInt_Iso(Len : Longint;var t : Text;l : ValSInt); iocheck; compilerproc;
  675. var
  676. s : String;
  677. Begin
  678. If (InOutRes<>0) then
  679. exit;
  680. Str(l,s);
  681. { default value? }
  682. if len=-1 then
  683. len:=11
  684. else if len<length(s) then
  685. len:=length(s);
  686. Write_Str_Iso(Len,t,s);
  687. End;
  688. Procedure fpc_Write_Text_UInt_Iso(Len : Longint;var t : Text;l : ValUInt); iocheck; compilerproc;
  689. var
  690. s : String;
  691. Begin
  692. If (InOutRes<>0) then
  693. exit;
  694. Str(L,s);
  695. { default value? }
  696. if len=-1 then
  697. len:=11
  698. else if len<length(s) then
  699. len:=length(s);
  700. Write_Str_Iso(Len,t,s);
  701. End;
  702. {$ifndef CPU64}
  703. procedure fpc_write_text_qword(len : longint;var t : text;q : qword); iocheck; compilerproc;
  704. var
  705. s : string;
  706. begin
  707. if (InOutRes<>0) then
  708. exit;
  709. str(q,s);
  710. write_str(len,t,s);
  711. end;
  712. procedure fpc_write_text_int64(len : longint;var t : text;i : int64); iocheck; compilerproc;
  713. var
  714. s : string;
  715. begin
  716. if (InOutRes<>0) then
  717. exit;
  718. str(i,s);
  719. write_str(len,t,s);
  720. end;
  721. procedure fpc_write_text_qword_iso(len : longint;var t : text;q : qword); iocheck; compilerproc;
  722. var
  723. s : string;
  724. begin
  725. if (InOutRes<>0) then
  726. exit;
  727. str(q,s);
  728. { default value? }
  729. if len=-1 then
  730. len:=20
  731. else if len<length(s) then
  732. len:=length(s);
  733. write_str_iso(len,t,s);
  734. end;
  735. procedure fpc_write_text_int64_iso(len : longint;var t : text;i : int64); iocheck; compilerproc;
  736. var
  737. s : string;
  738. begin
  739. if (InOutRes<>0) then
  740. exit;
  741. str(i,s);
  742. { default value? }
  743. if len=-1 then
  744. len:=20
  745. else if len<length(s) then
  746. len:=length(s);
  747. write_str_iso(len,t,s);
  748. end;
  749. {$endif CPU64}
  750. {$ifndef FPUNONE}
  751. Procedure fpc_Write_Text_Float(rt,fixkomma,Len : Longint;var t : Text;r : ValReal); iocheck; compilerproc;
  752. var
  753. s : String;
  754. Begin
  755. If (InOutRes<>0) then
  756. exit;
  757. Str_real(Len,fixkomma,r,treal_type(rt),s);
  758. Write_Str(Len,t,s);
  759. End;
  760. Procedure fpc_Write_Text_Float_iso(rt,fixkomma,Len : Longint;var t : Text;r : ValReal); iocheck; compilerproc;
  761. var
  762. s : String;
  763. Begin
  764. If (InOutRes<>0) then
  765. exit;
  766. Str_real_iso(Len,fixkomma,r,treal_type(rt),s);
  767. Write_Str(Len,t,s);
  768. End;
  769. {$endif}
  770. procedure fpc_write_text_enum(typinfo,ord2strindex:pointer;len:sizeint;var t:text;ordinal:longint); iocheck; compilerproc;
  771. var
  772. s:string;
  773. begin
  774. if textrec(t).mode<>fmoutput then
  775. begin
  776. if textrec(t).mode=fminput then
  777. inoutres:=105
  778. else
  779. inoutres:=103;
  780. exit;
  781. end;
  782. inoutres := fpc_shortstr_enum_intern(ordinal, len, typinfo, ord2strindex, s);
  783. if (inoutres <> 0) then
  784. exit;
  785. fpc_writeBuffer(t,s[1],length(s));
  786. end;
  787. {$ifdef FPC_HAS_STR_CURRENCY}
  788. Procedure fpc_Write_Text_Currency(fixkomma,Len : Longint;var t : Text;c : Currency); iocheck; compilerproc;
  789. var
  790. s : String;
  791. Begin
  792. If (InOutRes<>0) then
  793. exit;
  794. str(c:Len:fixkomma,s);
  795. Write_Str(Len,t,s);
  796. End;
  797. {$endif FPC_HAS_STR_CURRENCY}
  798. Procedure fpc_Write_Text_Boolean(Len : Longint;var t : Text;b : Boolean); iocheck; compilerproc;
  799. Begin
  800. If (InOutRes<>0) then
  801. exit;
  802. { Can't use array[boolean] because b can be >0 ! }
  803. if b then
  804. Write_Str(Len,t,'TRUE')
  805. else
  806. Write_Str(Len,t,'FALSE');
  807. End;
  808. Procedure fpc_Write_Text_Boolean_Iso(Len : Longint;var t : Text;b : Boolean); iocheck; compilerproc;
  809. Begin
  810. If (InOutRes<>0) then
  811. exit;
  812. { Can't use array[boolean] because b can be >0 ! }
  813. { default value? }
  814. If Len=-1 then
  815. Len:=5;
  816. if b then
  817. Write_Str_Iso(Len,t,'true')
  818. else
  819. Write_Str_Iso(Len,t,'false');
  820. End;
  821. Procedure fpc_Write_Text_Char(Len : Longint;var t : Text;c : Char); iocheck; compilerproc;
  822. Begin
  823. If (InOutRes<>0) then
  824. exit;
  825. if (TextRec(t).mode<>fmOutput) Then
  826. begin
  827. if TextRec(t).mode=fmClosed then
  828. InOutRes:=103
  829. else
  830. InOutRes:=105;
  831. exit;
  832. end;
  833. If Len>1 Then
  834. fpc_WriteBlanks(t,Len-1);
  835. If TextRec(t).BufPos>=TextRec(t).BufSize Then
  836. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  837. TextRec(t).Bufptr^[TextRec(t).BufPos]:=c;
  838. Inc(TextRec(t).BufPos);
  839. End;
  840. Procedure fpc_Write_Text_Char_Iso(Len : Longint;var t : Text;c : Char); iocheck; compilerproc;
  841. Begin
  842. If (InOutRes<>0) then
  843. exit;
  844. if (TextRec(t).mode<>fmOutput) Then
  845. begin
  846. if TextRec(t).mode=fmClosed then
  847. InOutRes:=103
  848. else
  849. InOutRes:=105;
  850. exit;
  851. end;
  852. { default value? }
  853. If Len=-1 then
  854. Len:=1;
  855. If Len>1 Then
  856. fpc_WriteBlanks(t,Len-1)
  857. else If Len<1 Then
  858. exit;
  859. If TextRec(t).BufPos>=TextRec(t).BufSize Then
  860. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  861. TextRec(t).Bufptr^[TextRec(t).BufPos]:=c;
  862. Inc(TextRec(t).BufPos);
  863. End;
  864. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  865. Procedure fpc_Write_Text_WideChar(Len : Longint;var t : Text;c : WideChar); iocheck; compilerproc;
  866. var
  867. a : ansistring;
  868. Begin
  869. If (InOutRes<>0) then
  870. exit;
  871. if (TextRec(t).mode<>fmOutput) Then
  872. begin
  873. if TextRec(t).mode=fmClosed then
  874. InOutRes:=103
  875. else
  876. InOutRes:=105;
  877. exit;
  878. end;
  879. If Len>1 Then
  880. fpc_WriteBlanks(t,Len-1);
  881. If TextRec(t).BufPos>=TextRec(t).BufSize Then
  882. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  883. { a widechar can be translated into more than a single ansichar }
  884. a:=c;
  885. fpc_WriteBuffer(t,pchar(a)^,length(a));
  886. End;
  887. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  888. {*****************************************************************************
  889. Read(Ln)
  890. *****************************************************************************}
  891. Function NextChar(var f:Text;var s:string):Boolean;
  892. begin
  893. NextChar:=false;
  894. if (TextRec(f).BufPos<TextRec(f).BufEnd) then
  895. if not (CtrlZMarksEOF) or (TextRec(f).Bufptr^[TextRec(f).BufPos]<>#26) then
  896. begin
  897. if length(s)<high(s) then
  898. begin
  899. inc(s[0]);
  900. s[length(s)]:=TextRec(f).BufPtr^[TextRec(f).BufPos];
  901. end;
  902. Inc(TextRec(f).BufPos);
  903. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  904. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  905. NextChar:=true;
  906. end;
  907. end;
  908. Function IgnoreSpaces(var f:Text):Boolean;
  909. {
  910. Removes all leading spaces,tab,eols from the input buffer, returns true if
  911. the buffer is empty
  912. }
  913. var
  914. s : string;
  915. begin
  916. s:='';
  917. IgnoreSpaces:=false;
  918. { Return false when already at EOF }
  919. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  920. exit;
  921. (* Check performed separately to avoid accessing memory outside buffer *)
  922. if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
  923. exit;
  924. while (TextRec(f).Bufptr^[TextRec(f).BufPos] <= ' ') do
  925. begin
  926. if not NextChar(f,s) then
  927. exit;
  928. { EOF? }
  929. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  930. break;
  931. if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
  932. break;
  933. end;
  934. IgnoreSpaces:=true;
  935. end;
  936. procedure ReadNumeric(var f:Text;var s:string);
  937. {
  938. Read numeric input, if buffer is empty then return True
  939. }
  940. begin
  941. repeat
  942. if not NextChar(f,s) then
  943. exit;
  944. until (length(s)=high(s)) or (TextRec(f).BufPtr^[TextRec(f).BufPos] <= ' ');
  945. end;
  946. function CheckRead(var f:Text):Boolean;
  947. begin
  948. CheckRead:=False;
  949. { Check error and if file is open and load buf if empty }
  950. If (InOutRes<>0) then
  951. exit;
  952. if (TextRec(f).mode<>fmInput) Then
  953. begin
  954. case TextRec(f).mode of
  955. fmOutPut,fmAppend:
  956. InOutRes:=104;
  957. else
  958. InOutRes:=103;
  959. end;
  960. exit;
  961. end;
  962. if TextRec(f).BufPos>=TextRec(f).BufEnd Then
  963. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  964. CheckRead:=True;
  965. end;
  966. Procedure fpc_Read_End(var f:Text);[Public,Alias:'FPC_READ_END']; iocheck; compilerproc;
  967. begin
  968. if TextRec(f).FlushFunc<>nil then
  969. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  970. end;
  971. Procedure fpc_ReadLn_End(var f : Text);[Public,Alias:'FPC_READLN_END']; iocheck; compilerproc;
  972. var prev: char;
  973. Begin
  974. If not CheckRead(f) then
  975. exit;
  976. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  977. { Flush if set }
  978. begin
  979. if (TextRec(f).FlushFunc<>nil) then
  980. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  981. exit;
  982. end;
  983. if CtrlZMarksEOF and (TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26) then
  984. Exit;
  985. repeat
  986. prev := TextRec(f).BufPtr^[TextRec(f).BufPos];
  987. inc(TextRec(f).BufPos);
  988. { no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, }
  989. { #13#10 = Dos), so if we've got #10, we can safely exit }
  990. if prev = #10 then
  991. exit;
  992. {$ifdef MACOS}
  993. if prev = #13 then
  994. {StdInput on macos never have dos line ending, so this is safe.}
  995. if TextRec(f).Handle = StdInputHandle then
  996. exit;
  997. {$endif MACOS}
  998. if TextRec(f).BufPos>=TextRec(f).BufEnd Then
  999. begin
  1000. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  1001. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1002. { Flush if set }
  1003. begin
  1004. if (TextRec(f).FlushFunc<>nil) then
  1005. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  1006. exit;
  1007. end;
  1008. end;
  1009. if CtrlZMarksEOF and (TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26) then
  1010. Exit;
  1011. if (prev=#13) then
  1012. { is there also a #10 after it? }
  1013. begin
  1014. if (TextRec(f).BufPtr^[TextRec(f).BufPos]=#10) then
  1015. { yes, skip that one as well }
  1016. inc(TextRec(f).BufPos);
  1017. exit;
  1018. end;
  1019. until false;
  1020. End;
  1021. Procedure fpc_ReadLn_End_Iso(var f : Text);[Public,Alias:'FPC_READLN_END_ISO']; iocheck; compilerproc;
  1022. var prev: char;
  1023. Begin
  1024. If not CheckRead(f) then
  1025. exit;
  1026. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1027. { Flush if set }
  1028. begin
  1029. if (TextRec(f).FlushFunc<>nil) then
  1030. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  1031. exit;
  1032. end;
  1033. if TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26 then
  1034. begin
  1035. inc(TextRec(f).BufPos);
  1036. Exit;
  1037. end;
  1038. repeat
  1039. prev := TextRec(f).BufPtr^[TextRec(f).BufPos];
  1040. inc(TextRec(f).BufPos);
  1041. { no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, }
  1042. { #13#10 = Dos), so if we've got #10, we can safely exit }
  1043. if prev = #10 then
  1044. exit;
  1045. {$ifdef MACOS}
  1046. if prev = #13 then
  1047. {StdInput on macos never have dos line ending, so this is safe.}
  1048. if TextRec(f).Handle = StdInputHandle then
  1049. exit;
  1050. {$endif MACOS}
  1051. if TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1052. begin
  1053. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  1054. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1055. { Flush if set }
  1056. begin
  1057. if (TextRec(f).FlushFunc<>nil) then
  1058. FileFunc(TextRec(f).FlushFunc)(TextRec(f));
  1059. exit;
  1060. end;
  1061. end;
  1062. if TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26 then
  1063. begin
  1064. inc(TextRec(f).BufPos);
  1065. Exit;
  1066. end;
  1067. if (prev=#13) then
  1068. { is there also a #10 after it? }
  1069. begin
  1070. if (TextRec(f).BufPtr^[TextRec(f).BufPos]=#10) then
  1071. { yes, skip that one as well }
  1072. inc(TextRec(f).BufPos);
  1073. exit;
  1074. end;
  1075. until false;
  1076. End;
  1077. Function ReadPCharLen(var f:Text;s:pchar;maxlen:longint):longint;
  1078. var
  1079. sPos,len : Longint;
  1080. p,startp,maxp : pchar;
  1081. end_of_string:boolean;
  1082. Begin
  1083. ReadPCharLen:=0;
  1084. If not CheckRead(f) then
  1085. exit;
  1086. { Read maximal until Maxlen is reached }
  1087. sPos:=0;
  1088. end_of_string:=false;
  1089. repeat
  1090. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1091. begin
  1092. FileFunc(TextRec(f).InOutFunc)(TextRec(f));
  1093. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1094. break;
  1095. end;
  1096. p:=@TextRec(f).Bufptr^[TextRec(f).BufPos];
  1097. if SPos+TextRec(f).BufEnd-TextRec(f).BufPos>MaxLen then
  1098. maxp:=@TextRec(f).BufPtr^[TextRec(f).BufPos+MaxLen-SPos]
  1099. else
  1100. maxp:=@TextRec(f).Bufptr^[TextRec(f).BufEnd];
  1101. startp:=p;
  1102. { find stop character }
  1103. while p<maxp do
  1104. begin
  1105. { Optimization: Do a quick check for a control character first }
  1106. if (p^<' ') then
  1107. begin
  1108. if (p^ in [#10,#13]) or
  1109. (ctrlZmarkseof and (p^=#26)) then
  1110. begin
  1111. end_of_string:=true;
  1112. break;
  1113. end;
  1114. end;
  1115. inc(p);
  1116. end;
  1117. { calculate read bytes }
  1118. len:=p-startp;
  1119. inc(TextRec(f).BufPos,Len);
  1120. Move(startp^,s[sPos],Len);
  1121. inc(sPos,Len);
  1122. until (spos=MaxLen) or end_of_string;
  1123. ReadPCharLen:=spos;
  1124. End;
  1125. Procedure fpc_Read_Text_ShortStr(var f : Text;out s : String); iocheck; compilerproc;
  1126. Begin
  1127. s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
  1128. End;
  1129. Procedure fpc_Read_Text_PChar_As_Pointer(var f : Text; const s : PChar); iocheck; compilerproc;
  1130. Begin
  1131. pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
  1132. End;
  1133. Procedure fpc_Read_Text_PChar_As_Array(var f : Text;out s : array of char; zerobased: boolean = false); iocheck; compilerproc;
  1134. var
  1135. len: longint;
  1136. Begin
  1137. len := ReadPCharLen(f,pchar(@s),high(s)+1);
  1138. if zerobased and
  1139. (len > high(s)) then
  1140. len := high(s);
  1141. if (len <= high(s)) then
  1142. s[len] := #0;
  1143. End;
  1144. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  1145. Procedure fpc_Read_Text_AnsiStr(var f : Text;out s : RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); [public, alias: 'FPC_READ_TEXT_ANSISTR']; iocheck; compilerproc;
  1146. var
  1147. slen,len : SizeInt;
  1148. Begin
  1149. slen:=0;
  1150. Repeat
  1151. // SetLength will reallocate the length.
  1152. SetLength(s,slen+255);
  1153. len:=ReadPCharLen(f,pchar(Pointer(s)+slen),255);
  1154. inc(slen,len);
  1155. Until len<255;
  1156. // Set actual length
  1157. SetLength(s,Slen);
  1158. {$ifdef FPC_HAS_CPSTRING}
  1159. SetCodePage(s,cp,false);
  1160. {$endif FPC_HAS_CPSTRING}
  1161. End;
  1162. Procedure fpc_Read_Text_AnsiStr_Intern(var f : Text;out s : RawByteString{$ifdef FPC_HAS_CPSTRING};cp : TSystemCodePage{$endif FPC_HAS_CPSTRING}); [external name 'FPC_READ_TEXT_ANSISTR'];
  1163. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  1164. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  1165. Procedure fpc_Read_Text_UnicodeStr(var f : Text;out us : UnicodeString); iocheck; compilerproc;
  1166. var
  1167. s: AnsiString;
  1168. Begin
  1169. // all standard input is assumed to be ansi-encoded
  1170. fpc_Read_Text_AnsiStr_Intern(f,RawByteString(s){$ifdef FPC_HAS_CPSTRING},DefaultSystemCodePage{$endif FPC_HAS_CPSTRING});
  1171. // Convert to unicodestring
  1172. us:=s;
  1173. End;
  1174. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  1175. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1176. Procedure fpc_Read_Text_WideStr(var f : Text;out ws : WideString); iocheck; compilerproc;
  1177. var
  1178. s: AnsiString;
  1179. Begin
  1180. // all standard input is assumed to be ansi-encoded
  1181. fpc_Read_Text_AnsiStr_Intern(f,RawByteString(s){$ifdef FPC_HAS_CPSTRING},DefaultSystemCodePage{$endif FPC_HAS_CPSTRING});
  1182. // Convert to widestring
  1183. ws:=s;
  1184. End;
  1185. {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1186. procedure fpc_Read_Text_Char(var f : Text; out c: char); [public, alias: 'FPC_READ_TEXT_CHAR']; iocheck;compilerproc;
  1187. Begin
  1188. c:=#0;
  1189. If not CheckRead(f) then
  1190. exit;
  1191. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1192. begin
  1193. c := #26;
  1194. exit;
  1195. end;
  1196. c:=TextRec(f).Bufptr^[TextRec(f).BufPos];
  1197. inc(TextRec(f).BufPos);
  1198. end;
  1199. procedure fpc_Read_Text_Char_intern(var f : Text; out c: char); iocheck; [external name 'FPC_READ_TEXT_CHAR'];
  1200. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  1201. procedure fpc_Read_Text_WideChar(var f : Text; out wc: widechar); iocheck;compilerproc;
  1202. var
  1203. ws: widestring;
  1204. i: longint;
  1205. { maximum code point length is 6 characters (with UTF-8) }
  1206. str: array[0..5] of char;
  1207. Begin
  1208. fillchar(str[0],sizeof(str),0);
  1209. for i:=low(str) to high(str) do
  1210. begin
  1211. fpc_Read_Text_Char_intern(f,str[i]);
  1212. case widestringmanager.CodePointLengthProc(@str[0],i+1) of
  1213. -1: { possibly incomplete code point, try with an extra character }
  1214. ;
  1215. 0: { null character }
  1216. begin
  1217. wc:=#0;
  1218. exit;
  1219. end;
  1220. else
  1221. begin
  1222. { valid code point -> convert to widestring}
  1223. widestringmanager.Ansi2WideMoveProc(@str[0],DefaultSystemCodePage,ws,i+1);
  1224. { has to be exactly one widechar }
  1225. if length(ws)=1 then
  1226. begin
  1227. wc:=ws[1];
  1228. exit
  1229. end
  1230. else
  1231. break;
  1232. end;
  1233. end;
  1234. end;
  1235. { invalid widechar input }
  1236. inoutres:=106;
  1237. end;
  1238. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  1239. procedure fpc_Read_Text_Char_Iso(var f : Text; out c: char); iocheck;compilerproc;
  1240. Begin
  1241. c:=' ';
  1242. If not CheckRead(f) then
  1243. exit;
  1244. If TextRec(f).BufPos>=TextRec(f).BufEnd Then
  1245. begin
  1246. c:=' ';
  1247. exit;
  1248. end;
  1249. c:=TextRec(f).Bufptr^[TextRec(f).BufPos];
  1250. inc(TextRec(f).BufPos);
  1251. if c=#13 then
  1252. begin
  1253. c:=' ';
  1254. If not CheckRead(f) or
  1255. (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1256. exit;
  1257. If TextRec(f).Bufptr^[TextRec(f).BufPos]=#10 then
  1258. inc(TextRec(f).BufPos);
  1259. { ignore #26 following a new line }
  1260. If not CheckRead(f) or
  1261. (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1262. exit;
  1263. If TextRec(f).Bufptr^[TextRec(f).BufPos]=#26 then
  1264. inc(TextRec(f).BufPos);
  1265. end
  1266. else if c=#10 then
  1267. begin
  1268. c:=' ';
  1269. { ignore #26 following a new line }
  1270. If not CheckRead(f) or
  1271. (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1272. exit;
  1273. If TextRec(f).Bufptr^[TextRec(f).BufPos]=#26 then
  1274. inc(TextRec(f).BufPos);
  1275. end
  1276. else if c=#26 then
  1277. c:=' ';
  1278. end;
  1279. Procedure fpc_Read_Text_SInt(var f : Text; out l : ValSInt); iocheck; compilerproc;
  1280. var
  1281. hs : String;
  1282. code : longint;
  1283. Begin
  1284. l:=0;
  1285. If not CheckRead(f) then
  1286. exit;
  1287. hs:='';
  1288. if IgnoreSpaces(f) then
  1289. begin
  1290. { When spaces were found and we are now at EOF,
  1291. then we return 0 }
  1292. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1293. exit;
  1294. if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
  1295. exit;
  1296. ReadNumeric(f,hs);
  1297. end;
  1298. if (hs = '') then
  1299. L := 0
  1300. else
  1301. begin
  1302. Val(hs,l,code);
  1303. if Code <> 0 then
  1304. InOutRes:=106;
  1305. end;
  1306. End;
  1307. Procedure fpc_Read_Text_UInt(var f : Text; out u : ValUInt); iocheck; compilerproc;
  1308. var
  1309. hs : String;
  1310. code : longint;
  1311. Begin
  1312. u:=0;
  1313. If not CheckRead(f) then
  1314. exit;
  1315. hs:='';
  1316. if IgnoreSpaces(f) then
  1317. begin
  1318. { When spaces were found and we are now at EOF,
  1319. then we return 0 }
  1320. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1321. exit;
  1322. ReadNumeric(f,hs);
  1323. end;
  1324. if (hs = '') then
  1325. u := 0
  1326. else
  1327. begin
  1328. val(hs,u,code);
  1329. If code<>0 Then
  1330. InOutRes:=106;
  1331. end;
  1332. End;
  1333. {$ifndef FPUNONE}
  1334. procedure fpc_Read_Text_Float(var f : Text; out v : ValReal); iocheck; compilerproc;
  1335. var
  1336. hs : string;
  1337. code : Word;
  1338. begin
  1339. v:=0.0;
  1340. If not CheckRead(f) then
  1341. exit;
  1342. hs:='';
  1343. if IgnoreSpaces(f) then
  1344. begin
  1345. { When spaces were found and we are now at EOF,
  1346. then we return 0 }
  1347. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1348. exit;
  1349. ReadNumeric(f,hs);
  1350. end;
  1351. val(hs,v,code);
  1352. If code<>0 Then
  1353. InOutRes:=106;
  1354. end;
  1355. {$endif}
  1356. procedure fpc_read_text_enum(str2ordindex:pointer;var t:text;out ordinal:longint); iocheck;compilerproc;
  1357. var s:string;
  1358. code:valsint;
  1359. begin
  1360. if not checkread(t) then
  1361. exit;
  1362. s:='';
  1363. if ignorespaces(t) then
  1364. begin
  1365. { When spaces were found and we are now at EOF, then we return 0 }
  1366. if (TextRec(t).BufPos>=TextRec(t).BufEnd) then
  1367. exit;
  1368. ReadNumeric(t,s);
  1369. end;
  1370. ordinal:=fpc_val_enum_shortstr(str2ordindex,s,code);
  1371. if code<>0 then
  1372. InOutRes:=106;
  1373. end;
  1374. procedure fpc_Read_Text_Currency(var f : Text; out v : Currency); iocheck; compilerproc;
  1375. var
  1376. hs : string;
  1377. code : Word;
  1378. begin
  1379. {$ifdef FPUNONE}
  1380. v:=0;
  1381. {$else}
  1382. v:=0.0;
  1383. {$endif}
  1384. If not CheckRead(f) then
  1385. exit;
  1386. hs:='';
  1387. if IgnoreSpaces(f) then
  1388. begin
  1389. { When spaces were found and we are now at EOF,
  1390. then we return 0 }
  1391. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1392. exit;
  1393. ReadNumeric(f,hs);
  1394. end;
  1395. val(hs,v,code);
  1396. If code<>0 Then
  1397. InOutRes:=106;
  1398. end;
  1399. {$ifndef cpu64}
  1400. procedure fpc_Read_Text_QWord(var f : text; out q : qword); iocheck; compilerproc;
  1401. var
  1402. hs : String;
  1403. code : longint;
  1404. Begin
  1405. q:=0;
  1406. If not CheckRead(f) then
  1407. exit;
  1408. hs:='';
  1409. if IgnoreSpaces(f) then
  1410. begin
  1411. { When spaces were found and we are now at EOF,
  1412. then we return 0 }
  1413. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1414. exit;
  1415. ReadNumeric(f,hs);
  1416. end;
  1417. val(hs,q,code);
  1418. If code<>0 Then
  1419. InOutRes:=106;
  1420. End;
  1421. procedure fpc_Read_Text_Int64(var f : text; out i : int64); iocheck; compilerproc;
  1422. var
  1423. hs : String;
  1424. code : Longint;
  1425. Begin
  1426. i:=0;
  1427. If not CheckRead(f) then
  1428. exit;
  1429. hs:='';
  1430. if IgnoreSpaces(f) then
  1431. begin
  1432. { When spaces were found and we are now at EOF,
  1433. then we return 0 }
  1434. if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
  1435. exit;
  1436. ReadNumeric(f,hs);
  1437. end;
  1438. Val(hs,i,code);
  1439. If code<>0 Then
  1440. InOutRes:=106;
  1441. End;
  1442. {$endif CPU64}
  1443. {*****************************************************************************
  1444. WriteStr/ReadStr
  1445. *****************************************************************************}
  1446. const
  1447. StrPtrIndex = 1;
  1448. { leave space for 128 bit string pointers :) (used for writestr) }
  1449. ShortStrLenIndex = 17;
  1450. { how many bytes of the string have been processed already (used for readstr) }
  1451. BytesReadIndex = 17;
  1452. threadvar
  1453. ReadWriteStrText: textrec;
  1454. procedure WriteStrShort(var t: textrec);
  1455. var
  1456. str: pshortstring;
  1457. newbytes,
  1458. oldlen: longint;
  1459. begin
  1460. if (t.bufpos=0) then
  1461. exit;
  1462. str:=pshortstring(ppointer(@t.userdata[StrPtrIndex])^);
  1463. newbytes:=t.BufPos;
  1464. oldlen:=length(str^);
  1465. if (oldlen+t.bufpos > t.userdata[ShortStrLenIndex]) then
  1466. begin
  1467. newbytes:=t.userdata[ShortStrLenIndex]-oldlen;
  1468. {$ifdef writestr_iolencheck}
  1469. // GPC only gives an io error if {$no-truncate-strings} is active
  1470. // FPC does not have this setting (it never gives errors when a
  1471. // a string expression is truncated)
  1472. { "disk full" }
  1473. inoutres:=101;
  1474. {$endif}
  1475. end;
  1476. setlength(str^,length(str^)+newbytes);
  1477. move(t.bufptr^,str^[oldlen+1],newbytes);
  1478. t.bufpos:=0;
  1479. end;
  1480. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  1481. procedure WriteStrAnsi(var t: textrec);
  1482. var
  1483. str: pansistring;
  1484. oldlen: longint;
  1485. begin
  1486. if (t.bufpos=0) then
  1487. exit;
  1488. str:=pansistring(ppointer(@t.userdata[StrPtrIndex])^);
  1489. oldlen:=length(str^);
  1490. setlength(str^,oldlen+t.bufpos);
  1491. move(t.bufptr^,str^[oldlen+1],t.bufpos);
  1492. t.bufpos:=0;
  1493. end;
  1494. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  1495. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  1496. procedure WriteStrUnicode(var t: textrec);
  1497. var
  1498. temp: ansistring;
  1499. str: punicodestring;
  1500. begin
  1501. if (t.bufpos=0) then
  1502. exit;
  1503. str:=punicodestring(ppointer(@t.userdata[StrPtrIndex])^);
  1504. setlength(temp,t.bufpos);
  1505. move(t.bufptr^,temp[1],t.bufpos);
  1506. str^:=str^+temp;
  1507. t.bufpos:=0;
  1508. end;
  1509. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  1510. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1511. procedure WriteStrWide(var t: textrec);
  1512. var
  1513. temp: ansistring;
  1514. str: pwidestring;
  1515. begin
  1516. if (t.bufpos=0) then
  1517. exit;
  1518. str:=pwidestring(ppointer(@t.userdata[StrPtrIndex])^);
  1519. setlength(temp,t.bufpos);
  1520. move(t.bufptr^,temp[1],t.bufpos);
  1521. str^:=str^+temp;
  1522. t.bufpos:=0;
  1523. end;
  1524. {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1525. procedure SetupWriteStrCommon(out t: textrec);
  1526. begin
  1527. // initialise
  1528. Assign(text(t),'');
  1529. t.mode:=fmOutput;
  1530. t.OpenFunc:=nil;
  1531. t.CloseFunc:=nil;
  1532. end;
  1533. function fpc_SetupWriteStr_Shortstr(out s: shortstring): PText; compilerproc;
  1534. begin
  1535. setupwritestrcommon(ReadWriteStrText);
  1536. PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
  1537. ReadWriteStrText.userdata[ShortStrLenIndex]:=high(s);
  1538. setlength(s,0);
  1539. ReadWriteStrText.InOutFunc:=@WriteStrShort;
  1540. ReadWriteStrText.FlushFunc:=@WriteStrShort;
  1541. result:=@ReadWriteStrText;
  1542. end;
  1543. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  1544. function fpc_SetupWriteStr_Ansistr(out s: ansistring): PText; compilerproc;
  1545. begin
  1546. setupwritestrcommon(ReadWriteStrText);
  1547. PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
  1548. // automatically done by out-semantics
  1549. // setlength(s,0);
  1550. ReadWriteStrText.InOutFunc:=@WriteStrAnsi;
  1551. ReadWriteStrText.FlushFunc:=@WriteStrAnsi;
  1552. result:=@ReadWriteStrText;
  1553. end;
  1554. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  1555. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  1556. function fpc_SetupWriteStr_Unicodestr(out s: unicodestring): PText; compilerproc;
  1557. begin
  1558. setupwritestrcommon(ReadWriteStrText);
  1559. PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
  1560. // automatically done by out-semantics
  1561. // setlength(s,0);
  1562. ReadWriteStrText.InOutFunc:=@WriteStrUnicode;
  1563. ReadWriteStrText.FlushFunc:=@WriteStrUnicode;
  1564. result:=@ReadWriteStrText;
  1565. end;
  1566. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  1567. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1568. function fpc_SetupWriteStr_Widestr(out s: widestring): PText; compilerproc;
  1569. begin
  1570. setupwritestrcommon(ReadWriteStrText);
  1571. PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
  1572. // automatically done by out-semantics
  1573. // setlength(s,0);
  1574. ReadWriteStrText.InOutFunc:=@WriteStrWide;
  1575. ReadWriteStrText.FlushFunc:=@WriteStrWide;
  1576. result:=@ReadWriteStrText;
  1577. end;
  1578. {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1579. procedure ReadAnsiStrFinal(var t: textrec);
  1580. begin
  1581. { finalise the temp ansistring }
  1582. PAnsiString(@t.userdata[StrPtrIndex])^ := '';
  1583. end;
  1584. procedure ReadStrCommon(var t: textrec; strdata: pchar; len: sizeint);
  1585. var
  1586. newbytes: sizeint;
  1587. begin
  1588. newbytes := len - PSizeInt(@t.userdata[BytesReadIndex])^;
  1589. if (t.BufSize <= newbytes) then
  1590. newbytes := t.BufSize;
  1591. if (newbytes > 0) then
  1592. begin
  1593. move(strdata[PSizeInt(@t.userdata[BytesReadIndex])^],t.BufPtr^,newbytes);
  1594. inc(PSizeInt(@t.userdata[BytesReadIndex])^,newbytes);
  1595. end;
  1596. t.BufEnd:=newbytes;
  1597. t.BufPos:=0;
  1598. end;
  1599. procedure ReadStrAnsi(var t: textrec);
  1600. var
  1601. str: pansistring;
  1602. begin
  1603. str:=pansistring(@t.userdata[StrPtrIndex]);
  1604. ReadStrCommon(t,@str^[1],length(str^));
  1605. end;
  1606. procedure SetupReadStrCommon(out t: textrec);
  1607. begin
  1608. // initialise
  1609. Assign(text(t),'');
  1610. t.mode:=fmInput;
  1611. t.OpenFunc:=nil;
  1612. t.CloseFunc:=nil;
  1613. PSizeInt(@t.userdata[BytesReadIndex])^:=0;
  1614. end;
  1615. function fpc_SetupReadStr_Ansistr(const s: ansistring): PText; [public, alias: 'FPC_SETUPREADSTR_ANSISTR']; compilerproc;
  1616. begin
  1617. setupreadstrcommon(ReadWriteStrText);
  1618. { we need a reference, because 's' may be a temporary expression }
  1619. PAnsiString(@ReadWriteStrText.userdata[StrPtrIndex])^:=s;
  1620. ReadWriteStrText.InOutFunc:=@ReadStrAnsi;
  1621. { this is called at the end, by fpc_read_end }
  1622. ReadWriteStrText.FlushFunc:=@ReadAnsiStrFinal;
  1623. result:=@ReadWriteStrText;
  1624. end;
  1625. function fpc_SetupReadStr_Ansistr_Intern(const s: ansistring): PText; [external name 'FPC_SETUPREADSTR_ANSISTR'];
  1626. function fpc_SetupReadStr_Shortstr(const s: shortstring): PText; compilerproc;
  1627. begin
  1628. { the reason we convert the short string to ansistring, is because the semantics of
  1629. readstr are defined as:
  1630. *********************
  1631. Apart from the restrictions imposed by requirements given in this clause,
  1632. the execution of readstr(e,v 1 ,...,v n ) where e denotes a
  1633. string-expression and v 1 ,...,v n denote variable-accesses possessing the
  1634. char-type (or a subrange of char-type), the integer-type (or a subrange of
  1635. integer-type), the real-type, a fixed-string-type, or a
  1636. variable-string-type, shall be equivalent to
  1637. begin
  1638. rewrite(f);
  1639. writeln(f, e);
  1640. reset(f);
  1641. read(f, v 1 ,...,v n )
  1642. end
  1643. *********************
  1644. This means that any side effects caused by the evaluation of v 1 .. v n
  1645. must not affect the value of e (= our argument s) -> we need a copy of it.
  1646. An ansistring is the easiest way to get a threadsafe copy, and allows us
  1647. to use the other ansistring readstr helpers too.
  1648. }
  1649. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  1650. result:=fpc_SetupReadStr_Ansistr_Intern(s);
  1651. {$else FPC_HAS_FEATURE_ANSISTRINGS}
  1652. runerror(217);
  1653. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  1654. end;
  1655. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  1656. function fpc_SetupReadStr_Unicodestr(const s: unicodestring): PText; compilerproc;
  1657. begin
  1658. { we use an ansistring to avoid code duplication, and let the }
  1659. { assignment convert the widestring to an equivalent ansistring }
  1660. result:=fpc_SetupReadStr_Ansistr_Intern(s);
  1661. end;
  1662. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  1663. {$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1664. function fpc_SetupReadStr_Widestr(const s: widestring): PText; compilerproc;
  1665. begin
  1666. { we use an ansistring to avoid code duplication, and let the }
  1667. { assignment convert the widestring to an equivalent ansistring }
  1668. result:=fpc_SetupReadStr_Ansistr_Intern(s);
  1669. end;
  1670. {$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
  1671. {*****************************************************************************
  1672. Initializing
  1673. *****************************************************************************}
  1674. procedure OpenStdIO(var f:text;mode:longint;hdl:thandle);
  1675. begin
  1676. Assign(f,'');
  1677. TextRec(f).Handle:=hdl;
  1678. TextRec(f).Mode:=mode;
  1679. TextRec(f).Closefunc:=@FileCloseFunc;
  1680. case mode of
  1681. fmInput :
  1682. TextRec(f).InOutFunc:=@FileReadFunc;
  1683. fmOutput :
  1684. begin
  1685. TextRec(f).InOutFunc:=@FileWriteFunc;
  1686. if Do_Isdevice(hdl) then
  1687. TextRec(f).FlushFunc:=@FileWriteFunc;
  1688. end;
  1689. else
  1690. HandleError(102);
  1691. end;
  1692. end;