fpc/rtl/inc/text.inc
Jonas Maebe c13ff3729b * Merged 2.3 branch changes:
+ darwin/ppc64 support
    + val/str/read(ln)/write(ln) support for enums
    + simple cse at the node tree level
    + if-node simplify support
    + simple ssa support for memory locations
    + support for optional overflow/rangecheck boolean parameters for
      operators
    * a lot of unification of the ppc32/ppc64 code generators


........
r6380 | jonas | 2007-02-08 21:25:36 +0100 (Thu, 08 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ncgld.pas
   M /branches/fpc_2_3/compiler/tgobj.pas
   A /branches/fpc_2_3/tests/webtbs/tw8283.pp

  + support for replacing the memory location of a temp (including
    local variables) with that of another temp to avoid unnecessary
    copies (mantis #8283)

........
r6381 | jonas | 2007-02-08 22:53:36 +0100 (Thu, 08 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/nflw.pas
   A /branches/fpc_2_3/tests/webtbs/tw8282.pp

  + simplify support for ifn (based on patch by Florian)

........
r6386 | peter | 2007-02-09 13:48:53 +0100 (Fri, 09 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/htypechk.pas
   M /branches/fpc_2_3/compiler/ncal.pas
   M /branches/fpc_2_3/compiler/symconst.pas

  * overflow,rangecheck optional parameters for operators, patch from 8281

........
r6391 | jonas | 2007-02-09 23:52:13 +0100 (Fri, 09 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc/agppcgas.pas
   M /branches/fpc_2_3/compiler/powerpc64/cpunode.pas
   D /branches/fpc_2_3/compiler/powerpc64/nppcinl.pas
   M /branches/fpc_2_3/compiler/ppcgen/ngppcinl.pas

  * merged fsqrt(s) support to common powerpc unit, activate for ppc32
    if -Op970 is used (still default for ppc64, since default cpu there
    is already ppc970)

........
r6394 | jonas | 2007-02-10 18:58:47 +0100 (Sat, 10 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc/cgcpu.pas
   M /branches/fpc_2_3/compiler/powerpc64/cgcpu.pas
   M /branches/fpc_2_3/compiler/ppcgen/cgppc.pas

  * adapted a_jmp_name for darwin/ppc64
  * merged g_intf_wrapper for ppc32 and ppc64, and added darwin/ppc64
    support to it

........
r6396 | jonas | 2007-02-10 20:16:06 +0100 (Sat, 10 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/cgobj.pas

  + darwin/ppc64 support for g_indirect_sym_load

........
r6397 | jonas | 2007-02-10 20:22:49 +0100 (Sat, 10 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc/cgcpu.pas
   M /branches/fpc_2_3/compiler/powerpc64/cgcpu.pas
   M /branches/fpc_2_3/compiler/ppcgen/cgppc.pas

  + darwin/ppc64 support to ppc64's fixref
  * moved ppc32 a_load_store to cgppc and use it for darwin/ppc64 as
    well (its relocatable symbols are only 32 bits large)

........
r6399 | jonas | 2007-02-10 22:02:37 +0100 (Sat, 10 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems.pas

  + system_x86_64_darwin identifier
  + set default source system for system_x86_64_darwin and
    system_powerpc64_darwin

........
r6404 | jonas | 2007-02-10 23:01:23 +0100 (Sat, 10 Feb 2007) | 5 lines
Changed paths:
   M /branches/fpc_2_3/compiler/aasmdata.pas
   M /branches/fpc_2_3/compiler/aggas.pas
   M /branches/fpc_2_3/compiler/cgobj.pas
   M /branches/fpc_2_3/compiler/cgutils.pas
   M /branches/fpc_2_3/compiler/cresstr.pas
   M /branches/fpc_2_3/compiler/dbgdwarf.pas
   M /branches/fpc_2_3/compiler/dbgstabs.pas
   M /branches/fpc_2_3/compiler/ncgutil.pas
   M /branches/fpc_2_3/compiler/ogelf.pas
   M /branches/fpc_2_3/compiler/pdecvar.pas
   M /branches/fpc_2_3/compiler/pmodules.pas
   M /branches/fpc_2_3/compiler/symdef.pas
   M /branches/fpc_2_3/compiler/systems.pas

  + system_x86_64_darwin identifier
  + systems_darwin set which collects all darwin variants
  + added support for darwin/ppc64 and darwin/x86_64 where needed in
    the generic code

........
r6406 | jonas | 2007-02-10 23:24:32 +0100 (Sat, 10 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/cgobj.pas

  * ifdef cpu64 -> ifdef cpu64bit

........
r6409 | jonas | 2007-02-11 00:34:04 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/pdecvar.pas

  * fixed ppc64 compilation

........
r6413 | jonas | 2007-02-11 12:41:27 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/bsd/system.pp
   M /branches/fpc_2_3/rtl/darwin/powerpc/sig_cpu.inc
   M /branches/fpc_2_3/rtl/darwin/signal.inc

  + darwin/ppc64 support for signal routines

........
r6415 | jonas | 2007-02-11 13:54:53 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/i_linux.pas

  * set abi of linux/ppc64 to abi_powerpc_sysv

........
r6416 | jonas | 2007-02-11 13:55:51 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/cputarg.pas
   M /branches/fpc_2_3/compiler/systems/i_bsd.pas
   M /branches/fpc_2_3/compiler/systems/t_bsd.pas

  + darwin/ppc64 source and target information

........
r6418 | jonas | 2007-02-11 14:19:55 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/powerpc64/math.inc

  * darwin/ppc64 compilation fixes

........
r6419 | jonas | 2007-02-11 14:22:22 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc/cgcpu.pas
   M /branches/fpc_2_3/compiler/powerpc64/cgcpu.pas
   M /branches/fpc_2_3/compiler/ppcgen/cgppc.pas

  * darwin/ppc64 needs the 32 bit version of a_loadaddr_ref_reg

........
r6420 | jonas | 2007-02-11 14:22:55 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/utils/fpcm/fpcmmain.pp

  + darwin/ppc64 support

........
r6426 | jonas | 2007-02-11 16:13:19 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/rappcgas.pas

  * fixed refaddr parsing for darwin/ppc64

........
r6427 | jonas | 2007-02-11 16:14:21 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc/agppcgas.pas
   M /branches/fpc_2_3/compiler/powerpc64/agppcgas.pas
   A /branches/fpc_2_3/compiler/ppcgen/agppcutl.pas

  * moved ppc32/ppc64 assembler writer helpers to a common unit

........
r6430 | jonas | 2007-02-11 17:53:23 +0100 (Sun, 11 Feb 2007) | 4 lines
Changed paths:
   D /branches/fpc_2_3/rtl/darwin/powerpc/sig_cpu.inc
   D /branches/fpc_2_3/rtl/darwin/powerpc/sighnd.inc
   A /branches/fpc_2_3/rtl/darwin/powerpc64
   A /branches/fpc_2_3/rtl/darwin/powerpc64/sig_cpu.inc
   A /branches/fpc_2_3/rtl/darwin/powerpc64/sighnd.inc
   A /branches/fpc_2_3/rtl/darwin/ppcgen
   A /branches/fpc_2_3/rtl/darwin/ppcgen/ppchnd.inc (from /branches/fpc_2_3/rtl/darwin/powerpc/sighnd.inc:6422)
   A /branches/fpc_2_3/rtl/darwin/ppcgen/sig_ppc.inc (from /branches/fpc_2_3/rtl/darwin/powerpc/sig_cpu.inc:6422)
   M /branches/fpc_2_3/rtl/darwin/signal.inc

  * fixed ppc/ppc64 signal include handling (both real files are in
    ppcgen, dummies in powerpc and powerpc64 which include those files)
    (1st step because pre-commit filter can't handle replaced files)

........
r6431 | jonas | 2007-02-11 17:53:47 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   A /branches/fpc_2_3/rtl/darwin/powerpc/sig_cpu.inc
   A /branches/fpc_2_3/rtl/darwin/powerpc/sighnd.inc

  * second step of signal include patch

........
r6432 | jonas | 2007-02-11 19:00:12 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/t_bsd.pas

  * changed darwin checks to use systems_darwin constant

........
r6433 | jonas | 2007-02-11 19:05:38 +0100 (Sun, 11 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/cgcpu.pas

  * handle non-multiple-of-4 offsets with 64 bit loads/stores for
    darwin/ppc64

........
r6434 | jonas | 2007-02-11 19:05:56 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   D /branches/fpc_2_3/compiler/powerpc/agppcgas.pas
   D /branches/fpc_2_3/compiler/powerpc64/agppcgas.pas
   A /branches/fpc_2_3/compiler/ppcgen/agppcgas.pas (from /branches/fpc_2_3/compiler/ppcgen/agppcutl.pas:6427)
   D /branches/fpc_2_3/compiler/ppcgen/agppcutl.pas

  * completely merged ppc assembler writers

........
r6435 | jonas | 2007-02-11 19:06:40 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/darwin/console.pp
   M /branches/fpc_2_3/rtl/darwin/termiosproc.inc

  * fixed 64 bit compilation

........
r6436 | jonas | 2007-02-11 19:09:28 +0100 (Sun, 11 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/packages/extra/Makefile.fpc

  * universal interfaces aren't 64 bit ready yet -> only compile for
    darwin/ppc and darwin/i386

........
r6438 | jonas | 2007-02-11 19:22:34 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   A /branches/fpc_2_3/tests/test/cg/obj/darwin/powerpc64
   A /branches/fpc_2_3/tests/test/cg/obj/darwin/powerpc64/ctest.o
   A /branches/fpc_2_3/tests/test/cg/obj/darwin/powerpc64/tcext3.o
   A /branches/fpc_2_3/tests/test/cg/obj/darwin/powerpc64/tcext4.o
   A /branches/fpc_2_3/tests/test/cg/obj/darwin/powerpc64/tcext5.o

  + compiled for darwin/ppc64

........
r6439 | jonas | 2007-02-11 20:24:42 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ppcgen/cgppc.pas

  * patch from Thomas to fix linux/ppc64

........
r6440 | jonas | 2007-02-11 20:25:15 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems.pas

  * fixed setting source OS for darwin/ppc64

........
r6444 | florian | 2007-02-11 22:24:20 +0100 (Sun, 11 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/globtype.pas
   M /branches/fpc_2_3/compiler/nopt.pas
   M /branches/fpc_2_3/compiler/nutils.pas
   M /branches/fpc_2_3/compiler/optcse.pas
   M /branches/fpc_2_3/compiler/psub.pas

+ first node cse implementation

........
r6445 | jonas | 2007-02-11 22:30:07 +0100 (Sun, 11 Feb 2007) | 6 lines
Changed paths:
   M /branches/fpc_2_3/compiler/cresstr.pas

  * hack to work around strange darwin/ppc64 linker bug: it seems to
    have problems if you put a global symbol at the end of a section
    without any data following (at least in case of the resource strings
    section) -> add dummy byte at the end for darwin/ppc64 (otherwise
    it messes up the address of the first symbol stub entry)

........
r6449 | jonas | 2007-02-11 23:23:44 +0100 (Sun, 11 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/i_bsd.pas

  * cpupowerpc is defined for both ppc32 and ppc64 ->
    changed to cpupowerpc32 to avoid defining source
    wrongly on ppc64

........
r6450 | jonas | 2007-02-11 23:26:34 +0100 (Sun, 11 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ppcgen/ngppcset.pas

  * disable jump tables for darwin/ppc64 for now, don't work
    yet for some reason

........
r6451 | florian | 2007-02-11 23:54:37 +0100 (Sun, 11 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ncal.pas
   M /branches/fpc_2_3/compiler/nutils.pas
   M /branches/fpc_2_3/compiler/optcse.pas

* improved cse
* better complexity calculation for subscript nodes with classes or interfaces

........
r6456 | jonas | 2007-02-12 19:33:22 +0100 (Mon, 12 Feb 2007) | 4 lines
Changed paths:
   M /branches/fpc_2_3/compiler/nutils.pas

  + support for notn,shln,shrn,equaln,unequaln,gtn,gten,ltn,lten in
    node_cplexity()
  * mark muln,divn,modn as more complex

........
r6469 | jonas | 2007-02-13 15:56:01 +0100 (Tue, 13 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/optcse.pas

  * fixed when cross-compiling a 64 bit compiler from a 32 bit platform

........
r6471 | jonas | 2007-02-13 16:17:16 +0100 (Tue, 13 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/cputarg.pas

  * include stabs support (can work on darwin/ppc64, but doesn't work
    yet)

........
r6473 | jonas | 2007-02-13 16:45:48 +0100 (Tue, 13 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/cgcpu.pas
   M /branches/fpc_2_3/compiler/powerpc64/cpupara.pas

  * R2 is a volatile and usable register under darwin/ppc64
  * R13 is a reserved non-volatile register under darwin/ppc64 (tls)

........
r6479 | jonas | 2007-02-13 20:40:50 +0100 (Tue, 13 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/i_bsd.pas

  * maxCrecordalign seems to have to be 8 rather 4, in spite of what
    the ABI docs say (although they are contradictory to some extent)

........
r6487 | jonas | 2007-02-14 15:57:40 +0100 (Wed, 14 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/tests/webtbs/tw8153a.pp

  * fixed for darwin/ppc64

........
r6488 | jonas | 2007-02-14 15:58:56 +0100 (Wed, 14 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/tests/webtbs/tw7851a.pp

  * fixed for darwin/ppc64

........
r6494 | jonas | 2007-02-15 19:36:55 +0100 (Thu, 15 Feb 2007) | 3 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/i_bsd.pas

  * set default debug info for darwin/ppc64 to dwarf2 since
    it works better than stabs currently

........
r6500 | jonas | 2007-02-15 21:38:16 +0100 (Thu, 15 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/version.pas

  * updated version to 2.3.0

........
r6505 | jonas | 2007-02-15 22:39:28 +0100 (Thu, 15 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/version.pas

  * changed version to 2.3.1

........
r6511 | jonas | 2007-02-16 15:17:24 +0100 (Fri, 16 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/powerpc64/itcpugas.pas

  * system_powerpc_darwin -> system_powerpc64_darwin

........
r6546 | daniel | 2007-02-18 15:48:54 +0100 (Sun, 18 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ncginl.pas
   M /branches/fpc_2_3/compiler/ncgld.pas
   M /branches/fpc_2_3/compiler/ncgrtti.pas
   M /branches/fpc_2_3/compiler/ncnv.pas
   M /branches/fpc_2_3/compiler/ninl.pas
   M /branches/fpc_2_3/compiler/nld.pas
   M /branches/fpc_2_3/compiler/nutils.pas
   M /branches/fpc_2_3/compiler/pinline.pas
   M /branches/fpc_2_3/rtl/inc/astrings.inc
   M /branches/fpc_2_3/rtl/inc/compproc.inc
   M /branches/fpc_2_3/rtl/inc/sstrings.inc
   M /branches/fpc_2_3/rtl/inc/text.inc
   M /branches/fpc_2_3/rtl/inc/wstrings.inc

  + Val/str/read/write support for enumeration types.

........
r6547 | daniel | 2007-02-18 17:01:20 +0100 (Sun, 18 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/inc/sstrings.inc

  * Fix val code that I broke.

........
r6571 | daniel | 2007-02-20 09:27:44 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/inc/astrings.inc
   M /branches/fpc_2_3/rtl/inc/sstrings.inc
   M /branches/fpc_2_3/rtl/inc/text.inc
   M /branches/fpc_2_3/rtl/inc/wstrings.inc

  * o2s -> ord2str, s2o -> str2ord

........
r6572 | daniel | 2007-02-20 09:33:30 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ncgld.pas
   M /branches/fpc_2_3/compiler/ncgrtti.pas
   M /branches/fpc_2_3/compiler/ninl.pas
   M /branches/fpc_2_3/compiler/nld.pas

  * o2s -> ord2str, s2o -> str2ord

........
r6574 | daniel | 2007-02-20 12:07:58 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/inc/compproc.inc

  * o2s -> ord2str, s2o -> str2ord

........
r6578 | daniel | 2007-02-20 22:18:49 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/rtl/inc/text.inc

  * Change longint to valsint.

........
r6579 | daniel | 2007-02-20 22:29:09 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ninl.pas

  * Handle ordinal currency types.

........
r6580 | jonas | 2007-02-20 22:29:11 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ncgrtti.pas

  * fixed compilation for cpurequiresproperalignment

........
r6581 | jonas | 2007-02-20 22:30:21 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ninl.pas

  * fixed typo

........
r6582 | daniel | 2007-02-20 22:36:19 +0100 (Tue, 20 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/ninl.pas

  * Set is_real to true.

........
r6590 | jonas | 2007-02-21 20:23:54 +0100 (Wed, 21 Feb 2007) | 2 lines
Changed paths:
   M /branches/fpc_2_3/compiler/systems/i_bsd.pas

  * set tf_dwarf_only_local_labels for darwin/ppc64

git-svn-id: trunk@6720 -
2007-03-04 20:16:57 +00:00

1316 lines
32 KiB
PHP

{
This file is part of the Free Pascal Run time library.
Copyright (c) 1999-2000 by the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{****************************************************************************
subroutines For TextFile handling
****************************************************************************}
Procedure FileCloseFunc(Var t:TextRec);
Begin
Do_Close(t.Handle);
t.Handle:=UnusedHandle;
End;
Procedure FileReadFunc(var t:TextRec);
Begin
t.BufEnd:=Do_Read(t.Handle,t.Bufptr,t.BufSize);
t.BufPos:=0;
End;
Procedure FileWriteFunc(var t:TextRec);
var
i : longint;
Begin
{ prevent unecessary system call }
if t.BufPos=0 then
exit;
i:=Do_Write(t.Handle,t.Bufptr,t.BufPos);
if i<>t.BufPos then
InOutRes:=101;
t.BufPos:=0;
End;
Procedure FileOpenFunc(var t:TextRec);
var
Flags : Longint;
Begin
Case t.mode Of
fmInput : Flags:=$10000;
fmOutput : Flags:=$11001;
fmAppend : Flags:=$10101;
else
begin
InOutRes:=102;
exit;
end;
End;
Do_Open(t,PChar(@t.Name),Flags);
t.CloseFunc:=@FileCloseFunc;
t.FlushFunc:=nil;
if t.Mode=fmInput then
t.InOutFunc:=@FileReadFunc
else
begin
t.InOutFunc:=@FileWriteFunc;
{ Only install flushing if its a NOT a file, and only check if there
was no error opening the file, becuase else we always get a bad
file handle error 6 (PFV) }
if (InOutRes=0) and
Do_Isdevice(t.Handle) then
t.FlushFunc:=@FileWriteFunc;
end;
End;
Procedure Assign({$ifdef PARAOUTFILE}out{$else}var{$endif} t:Text;const s:String);
Begin
FillChar(t,SizeOf(TextRec),0);
{ only set things that are not zero }
TextRec(t).Handle:=UnusedHandle;
TextRec(t).mode:=fmClosed;
TextRec(t).BufSize:=TextRecBufSize;
TextRec(t).Bufptr:=@TextRec(t).Buffer;
TextRec(t).OpenFunc:=@FileOpenFunc;
Case DefaultTextLineBreakStyle Of
tlbsLF: TextRec(t).LineEnd := #10;
tlbsCRLF: TextRec(t).LineEnd := #13#10;
tlbsCR: TextRec(t).LineEnd := #13;
End;
Move(s[1],TextRec(t).Name,Length(s));
End;
Procedure Assign({$ifdef PARAOUTFILE}out{$else}var{$endif} t:Text;p:pchar);
begin
Assign(t,StrPas(p));
end;
Procedure Assign({$ifdef PARAOUTFILE}out{$else}var{$endif} t:Text;c:char);
begin
Assign(t,string(c));
end;
Procedure Close(var t : Text);[IOCheck];
Begin
if InOutRes<>0 then
Exit;
case TextRec(t).mode of
fmInput,fmOutPut,fmAppend:
Begin
{ Write pending buffer }
If Textrec(t).Mode=fmoutput then
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
{ Only close functions not connected to stdout.}
If ((TextRec(t).Handle<>StdInputHandle) and
(TextRec(t).Handle<>StdOutputHandle) and
(TextRec(t).Handle<>StdErrorHandle)) Then
FileFunc(TextRec(t).CloseFunc)(TextRec(t));
TextRec(t).mode := fmClosed;
{ Reset buffer for safety }
TextRec(t).BufPos:=0;
TextRec(t).BufEnd:=0;
End
else inOutRes := 103;
End;
End;
Procedure OpenText(var t : Text;mode,defHdl:Longint);
Begin
Case TextRec(t).mode Of {This gives the fastest code}
fmInput,fmOutput,fmInOut : Close(t);
fmClosed : ;
else
Begin
InOutRes:=102;
exit;
End;
End;
TextRec(t).mode:=mode;
TextRec(t).bufpos:=0;
TextRec(t).bufend:=0;
FileFunc(TextRec(t).OpenFunc)(TextRec(t));
{ reset the mode to closed when an error has occured }
if InOutRes<>0 then
TextRec(t).mode:=fmClosed;
End;
Procedure Rewrite(var t : Text);[IOCheck];
Begin
If InOutRes<>0 then
exit;
OpenText(t,fmOutput,1);
End;
Procedure Reset(var t : Text);[IOCheck];
Begin
If InOutRes<>0 then
exit;
OpenText(t,fmInput,0);
End;
Procedure Append(var t : Text);[IOCheck];
Begin
If InOutRes<>0 then
exit;
OpenText(t,fmAppend,1);
End;
Procedure Flush(var t : Text);[IOCheck];
Begin
If InOutRes<>0 then
exit;
if TextRec(t).mode<>fmOutput then
begin
if TextRec(t).mode=fmInput then
InOutRes:=105
else
InOutRes:=103;
exit;
end;
{ Not the flushfunc but the inoutfunc should be used, becuase that
writes the data, flushfunc doesn't need to be assigned }
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
End;
Procedure Erase(var t:Text);[IOCheck];
Begin
If InOutRes <> 0 then
exit;
If TextRec(t).mode=fmClosed Then
Do_Erase(PChar(@TextRec(t).Name));
End;
Procedure Rename(var t : text;p:pchar);[IOCheck];
Begin
If InOutRes <> 0 then
exit;
If TextRec(t).mode=fmClosed Then
Begin
Do_Rename(PChar(@TextRec(t).Name),p);
{ check error code of do_rename }
If InOutRes = 0 then
Move(p^,TextRec(t).Name,StrLen(p)+1);
End;
End;
Procedure Rename(var t : Text;const s : string);[IOCheck];
var
p : array[0..255] Of Char;
Begin
If InOutRes <> 0 then
exit;
Move(s[1],p,Length(s));
p[Length(s)]:=#0;
Rename(t,Pchar(@p));
End;
Procedure Rename(var t : Text;c : char);[IOCheck];
var
p : array[0..1] Of Char;
Begin
If InOutRes <> 0 then
exit;
p[0]:=c;
p[1]:=#0;
Rename(t,Pchar(@p));
End;
Function Eof(Var t: Text): Boolean;[IOCheck];
Begin
If (InOutRes<>0) then
exit(true);
if (TextRec(t).mode<>fmInput) Then
begin
if TextRec(t).mode=fmOutput then
InOutRes:=104
else
InOutRes:=103;
exit(true);
end;
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
begin
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
exit(true);
end;
Eof:=CtrlZMarksEOF and (TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
end;
Function Eof:Boolean;
Begin
Eof:=Eof(Input);
End;
Function SeekEof (Var t : Text) : Boolean;
var
oldfilepos : Int64;
oldbufpos, oldbufend : SizeInt;
reads: longint;
isdevice: boolean;
Begin
If (InOutRes<>0) then
exit(true);
if (TextRec(t).mode<>fmInput) Then
begin
if TextRec(t).mode=fmOutPut then
InOutRes:=104
else
InOutRes:=103;
exit(true);
end;
{ try to save the current position in the file, seekeof() should not move }
{ the current file position (JM) }
oldbufpos := TextRec(t).BufPos;
oldbufend := TextRec(t).BufEnd;
reads := 0;
oldfilepos := -1;
isdevice := Do_IsDevice(TextRec(t).handle);
repeat
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
begin
{ signal that the we will have to do a seek }
inc(reads);
if not isdevice and
(reads = 1) then
begin
oldfilepos := Do_FilePos(TextRec(t).handle) - TextRec(t).BufEnd;
InOutRes:=0;
end;
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
begin
{ if we only did a read in which we didn't read anything, the }
{ old buffer is still valid and we can simply restore the }
{ pointers (JM) }
dec(reads);
SeekEof := true;
break;
end;
end;
case TextRec(t).Bufptr^[TextRec(t).BufPos] of
#26 :
if CtrlZMarksEOF then
begin
SeekEof := true;
break;
end;
#10,#13,#9,' ' :
;
else
begin
SeekEof := false;
break;
end;
end;
inc(TextRec(t).BufPos);
until false;
{ restore file position if not working with a device }
if not isdevice then
{ if we didn't modify the buffer, simply restore the BufPos and BufEnd }
{ (the latter becuase it's now probably set to zero because nothing was }
{ was read anymore) }
if (reads = 0) then
begin
TextRec(t).BufPos:=oldbufpos;
TextRec(t).BufEnd:=oldbufend;
end
{ otherwise return to the old filepos and reset the buffer }
else
begin
do_seek(TextRec(t).handle,oldfilepos);
InOutRes:=0;
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
TextRec(t).BufPos:=oldbufpos;
end;
End;
Function SeekEof : Boolean;
Begin
SeekEof:=SeekEof(Input);
End;
Function Eoln(var t:Text) : Boolean;
Begin
If (InOutRes<>0) then
exit(true);
if (TextRec(t).mode<>fmInput) Then
begin
if TextRec(t).mode=fmOutPut then
InOutRes:=104
else
InOutRes:=103;
exit(true);
end;
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
begin
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
exit(true);
end;
if CtrlZMarksEOF and (TextRec (T).BufPtr^[TextRec (T).BufPos] = #26) then
exit (true);
Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
End;
Function Eoln : Boolean;
Begin
Eoln:=Eoln(Input);
End;
Function SeekEoln (Var t : Text) : Boolean;
Begin
If (InOutRes<>0) then
exit(true);
if (TextRec(t).mode<>fmInput) Then
begin
if TextRec(t).mode=fmOutput then
InOutRes:=104
else
InOutRes:=103;
exit(true);
end;
repeat
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
begin
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
If TextRec(t).BufPos>=TextRec(t).BufEnd Then
exit(true);
end;
case TextRec(t).Bufptr^[TextRec(t).BufPos] of
#26: if CtrlZMarksEOF then
exit (true);
#10,#13 : exit(true);
#9,' ' : ;
else
exit(false);
end;
inc(TextRec(t).BufPos);
until false;
End;
Function SeekEoln : Boolean;
Begin
SeekEoln:=SeekEoln(Input);
End;
Procedure SetTextBuf(Var F : Text; Var Buf; Size : SizeInt);
Begin
TextRec(f).BufPtr:=@Buf;
TextRec(f).BufSize:=Size;
TextRec(f).BufPos:=0;
TextRec(f).BufEnd:=0;
End;
Procedure SetTextLineEnding(Var f:Text; Ending:string);
Begin
TextRec(F).LineEnd:=Ending;
End;
Function fpc_get_input:PText;compilerproc;
begin
fpc_get_input:=@Input;
end;
Function fpc_get_output:PText;compilerproc;
begin
fpc_get_output:=@Output;
end;
{*****************************************************************************
Write(Ln)
*****************************************************************************}
Procedure fpc_WriteBuffer(var f:Text;const b;len:SizeInt);[Public,Alias:'FPC_WRITEBUFFER'];
var
p : pchar;
left,
idx : SizeInt;
begin
p:=pchar(@b);
idx:=0;
left:=TextRec(f).BufSize-TextRec(f).BufPos;
while len>left do
begin
move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],left);
dec(len,left);
inc(idx,left);
inc(TextRec(f).BufPos,left);
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
left:=TextRec(f).BufSize-TextRec(f).BufPos;
end;
move(p[idx],TextRec(f).Bufptr^[TextRec(f).BufPos],len);
inc(TextRec(f).BufPos,len);
end;
Procedure fpc_WriteBlanks(var f:Text;len:longint);[Public,Alias:'FPC_WRITEBLANKS'];
var
left : longint;
begin
left:=TextRec(f).BufSize-TextRec(f).BufPos;
while len>left do
begin
FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],left,' ');
dec(len,left);
inc(TextRec(f).BufPos,left);
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
left:=TextRec(f).BufSize-TextRec(f).BufPos;
end;
FillChar(TextRec(f).Bufptr^[TextRec(f).BufPos],len,' ');
inc(TextRec(f).BufPos,len);
end;
Procedure fpc_Write_End(var f:Text);[Public,Alias:'FPC_WRITE_END']; iocheck; compilerproc;
begin
if TextRec(f).FlushFunc<>nil then
FileFunc(TextRec(f).FlushFunc)(TextRec(f));
end;
Procedure fpc_Writeln_End(var f:Text);[Public,Alias:'FPC_WRITELN_END']; iocheck; compilerproc;
begin
If InOutRes <> 0 then exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
{ Write EOL }
fpc_WriteBuffer(f,TextRec(f).LineEnd[1],length(TextRec(f).LineEnd));
{ Flush }
if TextRec(f).FlushFunc<>nil then
FileFunc(TextRec(f).FlushFunc)(TextRec(f));
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
end;
Procedure fpc_Write_Text_ShortStr(Len : Longint;var f : Text;const s : String); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SHORTSTR']; compilerproc;
Begin
If (InOutRes<>0) then
exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
If Len>Length(s) Then
fpc_WriteBlanks(f,Len-Length(s));
fpc_WriteBuffer(f,s[1],Length(s));
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
End;
{ provide local access to write_str }
procedure Write_Str(Len : Longint;var f : Text;const s : String); iocheck; [external name 'FPC_WRITE_TEXT_SHORTSTR'];
Procedure fpc_Write_Text_Pchar_as_Array(Len : Longint;var f : Text;const s : array of char; zerobased: boolean = true); iocheck; [Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_ARRAY']; compilerproc;
var
ArrayLen : longint;
p : pchar;
Begin
If (InOutRes<>0) then
exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
p:=pchar(@s);
if (zerobased) then
begin
{ can't use StrLen, since that one could try to read past the end }
{ of the heap (JM) }
ArrayLen:=IndexByte(p^,high(s)+1,0);
{ IndexByte returns -1 if not found (JM) }
if ArrayLen = -1 then
ArrayLen := high(s)+1;
end
else
ArrayLen := high(s)+1;
If Len>ArrayLen Then
fpc_WriteBlanks(f,Len-ArrayLen);
fpc_WriteBuffer(f,p^,ArrayLen);
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
End;
Procedure fpc_Write_Text_PChar_As_Pointer(Len : Longint;var f : Text;p : PChar); iocheck; [Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_POINTER']; compilerproc;
var
PCharLen : longint;
Begin
If (p=nil) or (InOutRes<>0) then
exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
PCharLen:=StrLen(p);
If Len>PCharLen Then
fpc_WriteBlanks(f,Len-PCharLen);
fpc_WriteBuffer(f,p^,PCharLen);
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
End;
Procedure fpc_Write_Text_AnsiStr (Len : Longint; Var f : Text; const S : AnsiString); iocheck; [Public,alias:'FPC_WRITE_TEXT_ANSISTR']; compilerproc;
{
Writes a AnsiString to the Text file T
}
var
SLen : longint;
begin
If (InOutRes<>0) then
exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
SLen:=Length(s);
If Len>SLen Then
fpc_WriteBlanks(f,Len-SLen);
if slen > 0 then
fpc_WriteBuffer(f,PChar(S)^,SLen);
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
end;
Procedure fpc_Write_Text_WideStr (Len : Longint; Var f : Text; const S : WideString); iocheck; [Public,alias:'FPC_WRITE_TEXT_WIDESTR']; compilerproc;
{
Writes a WideString to the Text file T
}
var
SLen : longint;
begin
If (pointer(S)=nil) or (InOutRes<>0) then
exit;
case TextRec(f).mode of
fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
begin
SLen:=Length(s);
If Len>SLen Then
fpc_WriteBlanks(f,Len-SLen);
fpc_WriteBuffer(f,PChar(AnsiString(S))^,SLen);
end;
fmInput: InOutRes:=105
else InOutRes:=103;
end;
end;
Procedure fpc_Write_Text_SInt(Len : Longint;var t : Text;l : ValSInt); iocheck; [Public,Alias:'FPC_WRITE_TEXT_SINT']; compilerproc;
var
s : String;
Begin
If (InOutRes<>0) then
exit;
Str(l,s);
Write_Str(Len,t,s);
End;
Procedure fpc_Write_Text_UInt(Len : Longint;var t : Text;l : ValUInt); iocheck; [Public,Alias:'FPC_WRITE_TEXT_UINT']; compilerproc;
var
s : String;
Begin
If (InOutRes<>0) then
exit;
Str(L,s);
Write_Str(Len,t,s);
End;
{$ifndef CPU64}
procedure fpc_write_text_qword(len : longint;var t : text;q : qword); iocheck; [public,alias:'FPC_WRITE_TEXT_QWORD']; compilerproc;
var
s : string;
begin
if (InOutRes<>0) then
exit;
str(q,s);
write_str(len,t,s);
end;
procedure fpc_write_text_int64(len : longint;var t : text;i : int64); iocheck; [public,alias:'FPC_WRITE_TEXT_INT64']; compilerproc;
var
s : string;
begin
if (InOutRes<>0) then
exit;
str(i,s);
write_str(len,t,s);
end;
{$endif CPU64}
Procedure fpc_Write_Text_Float(rt,fixkomma,Len : Longint;var t : Text;r : ValReal); iocheck; [Public,Alias:'FPC_WRITE_TEXT_FLOAT']; compilerproc;
var
s : String;
Begin
If (InOutRes<>0) then
exit;
Str_real(Len,fixkomma,r,treal_type(rt),s);
Write_Str(Len,t,s);
End;
procedure fpc_write_text_enum(typinfo,ord2strindex:pointer;len:sizeint;var t:text;ordinal:longint); iocheck; [Public,Alias:'FPC_WRITE_TEXT_ENUM']; compilerproc;
type Ptypeinfo=^Ttypeinfo;
Ttypeinfo=record
kind:byte;
name:shortstring;
end;
Penuminfo=^Tenuminfo;
Tenuminfo={$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif}record
ordtype:byte;
minvalue,maxvalue:longint;
basetype:pointer;
namelist:shortstring;
end;
Tsorted_array={$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif}record
o:longint;
s:Pstring;
end;
var e:Penuminfo;
p:Pstring;
l,h,m:cardinal;
sorted_array:^Tsorted_array;
s:string;
begin
if textrec(t).mode<>fmoutput then
begin
if textrec(t).mode=fminput then
inoutres:=105
else
inoutres:=103;
exit;
end;
if Pcardinal(ord2strindex)^=0 then
begin
{The compiler did generate a lookup table.}
with Penuminfo(Pbyte(typinfo)+2+length(Ptypeinfo(typinfo)^.name))^ do
begin
if (ordinal<minvalue) or (ordinal>maxvalue) then
begin
inoutres:=107; {Invalid ordinal value for this enum.}
exit;
end;
dec(ordinal,minvalue);
end;
{Get the address of the string.}
p:=Pshortstring((PPpointer(ord2strindex)+1+ordinal)^);
if p=nil then
begin
inoutres:=107; {Invalid ordinal value for this enum.}
exit;
end;
s:=p^;
end
else
begin
{The compiler did generate a sorted array of (ordvalue,Pstring) tuples.}
sorted_array:=pointer(Pcardinal(ord2strindex)+2);
{Use a binary search to get the string.}
l:=0;
h:=(Pcardinal(ord2strindex)+1)^-1;
repeat
m:=(l+h) div 2;
if ordinal>sorted_array[m].o then
l:=m+1
else if ordinal<sorted_array[m].o then
h:=m-1
else
break;
if l>h then
begin
inoutres:=107; {Invalid ordinal value for this enum.}
exit;
end;
until false;
s:=sorted_array[m].s^;
end;
fpc_writeBuffer(t,s[1],length(s));
{Pad the string with spaces if necessary.}
if len>length(s) then
fpc_writeblanks(t,len-length(s));
end;
{$ifdef FPC_HAS_STR_CURRENCY}
Procedure fpc_Write_Text_Currency(fixkomma,Len : Longint;var t : Text;c : Currency); iocheck; [Public,Alias:'FPC_WRITE_TEXT_CURRENCY']; compilerproc;
var
s : String;
Begin
If (InOutRes<>0) then
exit;
str(c:Len:fixkomma,s);
Write_Str(Len,t,s);
End;
{$endif FPC_HAS_STR_CURRENCY}
Procedure fpc_Write_Text_Boolean(Len : Longint;var t : Text;b : Boolean); iocheck; [Public,Alias:'FPC_WRITE_TEXT_BOOLEAN']; compilerproc;
Begin
If (InOutRes<>0) then
exit;
{ Can't use array[boolean] because b can be >0 ! }
if b then
Write_Str(Len,t,'TRUE')
else
Write_Str(Len,t,'FALSE');
End;
Procedure fpc_Write_Text_Char(Len : Longint;var t : Text;c : Char); iocheck; [Public,Alias:'FPC_WRITE_TEXT_CHAR']; compilerproc;
Begin
If (InOutRes<>0) then
exit;
if (TextRec(t).mode<>fmOutput) Then
begin
if TextRec(t).mode=fmClosed then
InOutRes:=103
else
InOutRes:=105;
exit;
end;
If Len>1 Then
fpc_WriteBlanks(t,Len-1);
If TextRec(t).BufPos>=TextRec(t).BufSize Then
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
TextRec(t).Bufptr^[TextRec(t).BufPos]:=c;
Inc(TextRec(t).BufPos);
End;
Procedure fpc_Write_Text_WideChar(Len : Longint;var t : Text;c : WideChar); iocheck; [Public,Alias:'FPC_WRITE_TEXT_WIDECHAR']; compilerproc;
var
ch : char;
Begin
If (InOutRes<>0) then
exit;
if (TextRec(t).mode<>fmOutput) Then
begin
if TextRec(t).mode=fmClosed then
InOutRes:=103
else
InOutRes:=105;
exit;
end;
If Len>1 Then
fpc_WriteBlanks(t,Len-1);
If TextRec(t).BufPos>=TextRec(t).BufSize Then
FileFunc(TextRec(t).InOutFunc)(TextRec(t));
ch:=c;
TextRec(t).Bufptr^[TextRec(t).BufPos]:=ch;
Inc(TextRec(t).BufPos);
End;
{*****************************************************************************
Read(Ln)
*****************************************************************************}
Function NextChar(var f:Text;var s:string):Boolean;
begin
NextChar:=false;
if (TextRec(f).BufPos<TextRec(f).BufEnd) then
if not (CtrlZMarksEOF) or (TextRec(f).Bufptr^[TextRec(f).BufPos]<>#26) then
begin
if length(s)<high(s) then
begin
inc(s[0]);
s[length(s)]:=TextRec(f).BufPtr^[TextRec(f).BufPos];
end;
Inc(TextRec(f).BufPos);
If TextRec(f).BufPos>=TextRec(f).BufEnd Then
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
NextChar:=true;
end;
end;
Function IgnoreSpaces(var f:Text):Boolean;
{
Removes all leading spaces,tab,eols from the input buffer, returns true if
the buffer is empty
}
var
s : string;
begin
s:='';
IgnoreSpaces:=false;
{ Return false when already at EOF }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
(* Check performed separately to avoid accessing memory outside buffer *)
if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
exit;
while (TextRec(f).Bufptr^[TextRec(f).BufPos] <= ' ') do
begin
if not NextChar(f,s) then
exit;
{ EOF? }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
break;
if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
break;
end;
IgnoreSpaces:=true;
end;
procedure ReadNumeric(var f:Text;var s:string);
{
Read numeric input, if buffer is empty then return True
}
begin
repeat
if not NextChar(f,s) then
exit;
until (length(s)=high(s)) or (TextRec(f).BufPtr^[TextRec(f).BufPos] <= ' ');
end;
function CheckRead(var f:Text):Boolean;
begin
CheckRead:=False;
{ Check error and if file is open and load buf if empty }
If (InOutRes<>0) then
exit;
if (TextRec(f).mode<>fmInput) Then
begin
case TextRec(f).mode of
fmOutPut,fmAppend:
InOutRes:=104;
else
InOutRes:=103;
end;
exit;
end;
if TextRec(f).BufPos>=TextRec(f).BufEnd Then
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
CheckRead:=True;
end;
Procedure fpc_Read_End(var f:Text);[Public,Alias:'FPC_READ_END']; iocheck; compilerproc;
begin
if TextRec(f).FlushFunc<>nil then
FileFunc(TextRec(f).FlushFunc)(TextRec(f));
end;
Procedure fpc_ReadLn_End(var f : Text);[Public,Alias:'FPC_READLN_END']; iocheck; compilerproc;
var prev: char;
Begin
If not CheckRead(f) then
exit;
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
{ Flush if set }
begin
if (TextRec(f).FlushFunc<>nil) then
FileFunc(TextRec(f).FlushFunc)(TextRec(f));
exit;
end;
if CtrlZMarksEOF and (TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26) then
Exit;
repeat
prev := TextRec(f).BufPtr^[TextRec(f).BufPos];
inc(TextRec(f).BufPos);
{ no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, }
{ #13#10 = Dos), so if we've got #10, we can safely exit }
if prev = #10 then
exit;
{$ifdef MACOS}
if prev = #13 then
{StdInput on macos never have dos line ending, so this is safe.}
if TextRec(f).Handle = StdInputHandle then
exit;
{$endif MACOS}
if TextRec(f).BufPos>=TextRec(f).BufEnd Then
begin
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
{ Flush if set }
begin
if (TextRec(f).FlushFunc<>nil) then
FileFunc(TextRec(f).FlushFunc)(TextRec(f));
exit;
end;
end;
if CtrlZMarksEOF and (TextRec (F).BufPtr^ [TextRec (F).BufPos] = #26) then
Exit;
if (prev=#13) then
{ is there also a #10 after it? }
begin
if (TextRec(f).BufPtr^[TextRec(f).BufPos]=#10) then
{ yes, skip that one as well }
inc(TextRec(f).BufPos);
exit;
end;
until false;
End;
Function ReadPCharLen(var f:Text;s:pchar;maxlen:longint):longint;
var
sPos,len : Longint;
p,q,startp,maxp : pchar;
stop_chars:array[0..2] of char;
end_of_string:boolean;
Begin
{Avoid use of ctrlZmarkseof in the inner loop.}
stop_chars[0]:=#13;
{ #10 must be always the last valid element in stop_chars - see below. }
if ctrlZmarkseof then
begin
stop_chars[1]:=#26;
stop_chars[2]:=#10;
end
else
stop_chars[1]:=#10;
ReadPCharLen:=0;
If not CheckRead(f) then
exit;
{ Read maximal until Maxlen is reached }
sPos:=0;
end_of_string:=false;
repeat
If TextRec(f).BufPos>=TextRec(f).BufEnd Then
begin
FileFunc(TextRec(f).InOutFunc)(TextRec(f));
If TextRec(f).BufPos>=TextRec(f).BufEnd Then
break;
end;
p:=@TextRec(f).Bufptr^[TextRec(f).BufPos];
if SPos+TextRec(f).BufEnd-TextRec(f).BufPos>MaxLen then
maxp:=@TextRec(f).BufPtr^[TextRec(f).BufPos+MaxLen-SPos]
else
maxp:=@TextRec(f).Bufptr^[TextRec(f).BufEnd];
startp:=p;
{ find stop character }
{ while (p<maxp) and not(P^ in [#10,#13]) do
inc(p);}
while p<maxp do
begin
q:=@stop_chars[0];
{ The following line relies on the fact that stop_chars array
is always initialized to have #10 as the last valid element. }
while (q^<>#10) and (p^<>q^) do
inc(q);
if p^=q^ then
begin
end_of_string:=true;
break;
end;
inc(p);
end;
{ calculate read bytes }
len:=p-startp;
inc(TextRec(f).BufPos,Len);
Move(startp^,s[sPos],Len);
inc(sPos,Len);
until (spos=MaxLen) or end_of_string;
ReadPCharLen:=spos;
End;
Procedure fpc_Read_Text_ShortStr(var f : Text;out s : String); iocheck; [Public,Alias:'FPC_READ_TEXT_SHORTSTR']; compilerproc;
Begin
s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
End;
Procedure fpc_Read_Text_PChar_As_Pointer(var f : Text; const s : PChar); iocheck; [Public,Alias:'FPC_READ_TEXT_PCHAR_AS_POINTER']; compilerproc;
Begin
pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
End;
Procedure fpc_Read_Text_PChar_As_Array(var f : Text;out s : array of char; zerobased: boolean = false); iocheck; [Public,Alias:'FPC_READ_TEXT_PCHAR_AS_ARRAY']; compilerproc;
var
len: longint;
Begin
len := ReadPCharLen(f,pchar(@s),high(s)+1);
if zerobased and
(len > high(s)) then
len := high(s);
if (len <= high(s)) then
s[len] := #0;
End;
Procedure fpc_Read_Text_AnsiStr(var f : Text;out s : AnsiString); iocheck; [Public,Alias:'FPC_READ_TEXT_ANSISTR']; compilerproc;
var
slen,len : SizeInt;
Begin
slen:=0;
Repeat
// SetLength will reallocate the length.
SetLength(S,slen+255);
len:=ReadPCharLen(f,pchar(Pointer(S)+slen),255);
inc(slen,len);
Until len<255;
// Set actual length
SetLength(S,Slen);
End;
procedure fpc_Read_Text_Char(var f : Text; out c: char); iocheck; [Public,Alias:'FPC_READ_TEXT_CHAR'];compilerproc;
Begin
c:=#0;
If not CheckRead(f) then
exit;
If TextRec(f).BufPos>=TextRec(f).BufEnd Then
begin
c := #26;
exit;
end;
c:=TextRec(f).Bufptr^[TextRec(f).BufPos];
inc(TextRec(f).BufPos);
end;
Procedure fpc_Read_Text_SInt(var f : Text; out l : ValSInt); iocheck; [Public,Alias:'FPC_READ_TEXT_SINT']; compilerproc;
var
hs : String;
code : longint;
Begin
l:=0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
if CtrlZMarksEOF and (TextRec(f).Bufptr^[TextRec(f).BufPos]=#26) then
exit;
ReadNumeric(f,hs);
end;
if (hs = '') then
L := 0
else
begin
Val(hs,l,code);
if Code <> 0 then
InOutRes:=106;
end;
End;
Procedure fpc_Read_Text_UInt(var f : Text; out u : ValUInt); iocheck; [Public,Alias:'FPC_READ_TEXT_UINT']; compilerproc;
var
hs : String;
code : longint;
Begin
u:=0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
ReadNumeric(f,hs);
end;
if (hs = '') then
u := 0
else
begin
val(hs,u,code);
If code<>0 Then
InOutRes:=106;
end;
End;
procedure fpc_Read_Text_Float(var f : Text; out v : ValReal); iocheck; [Public,Alias:'FPC_READ_TEXT_FLOAT']; compilerproc;
var
hs : string;
code : Word;
begin
v:=0.0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
ReadNumeric(f,hs);
end;
val(hs,v,code);
If code<>0 Then
InOutRes:=106;
end;
procedure fpc_read_text_enum(str2ordindex:pointer;var t:text;out ordinal:longint); iocheck; [Public,Alias:'FPC_READ_TEXT_ENUM'];compilerproc;
var s:string;
code:valsint;
begin
if not checkread(t) then
exit;
s:='';
if ignorespaces(t) then
begin
{ When spaces were found and we are now at EOF, then we return 0 }
if (TextRec(t).BufPos>=TextRec(t).BufEnd) then
exit;
ReadNumeric(t,s);
end;
ordinal:=fpc_val_enum_shortstr(str2ordindex,s,code);
if code<>0 then
InOutRes:=106;
end;
procedure fpc_Read_Text_Currency(var f : Text; out v : Currency); iocheck; [Public,Alias:'FPC_READ_TEXT_CURRENCY']; compilerproc;
var
hs : string;
code : Word;
begin
v:=0.0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
ReadNumeric(f,hs);
end;
val(hs,v,code);
If code<>0 Then
InOutRes:=106;
end;
{$ifndef cpu64}
procedure fpc_Read_Text_QWord(var f : text; out q : qword); iocheck; [public,alias:'FPC_READ_TEXT_QWORD']; compilerproc;
var
hs : String;
code : longint;
Begin
q:=0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
ReadNumeric(f,hs);
end;
val(hs,q,code);
If code<>0 Then
InOutRes:=106;
End;
procedure fpc_Read_Text_Int64(var f : text; out i : int64); iocheck; [public,alias:'FPC_READ_TEXT_INT64']; compilerproc;
var
hs : String;
code : Longint;
Begin
i:=0;
If not CheckRead(f) then
exit;
hs:='';
if IgnoreSpaces(f) then
begin
{ When spaces were found and we are now at EOF,
then we return 0 }
if (TextRec(f).BufPos>=TextRec(f).BufEnd) then
exit;
ReadNumeric(f,hs);
end;
Val(hs,i,code);
If code<>0 Then
InOutRes:=106;
End;
{$endif CPU64}
{*****************************************************************************
Initializing
*****************************************************************************}
procedure OpenStdIO(var f:text;mode,hdl:longint);
begin
Assign(f,'');
TextRec(f).Handle:=hdl;
TextRec(f).Mode:=mode;
TextRec(f).Closefunc:=@FileCloseFunc;
case mode of
fmInput :
TextRec(f).InOutFunc:=@FileReadFunc;
fmOutput :
begin
TextRec(f).InOutFunc:=@FileWriteFunc;
if Do_Isdevice(hdl) then
TextRec(f).FlushFunc:=@FileWriteFunc;
end;
else
HandleError(102);
end;
end;