diff options
Diffstat (limited to 'rtl')
-rw-r--r-- | rtl/arm/arm.inc | 20 | ||||
-rw-r--r-- | rtl/arm/setjump.inc | 4 | ||||
-rw-r--r-- | rtl/go32v2/Makefile | 31 | ||||
-rw-r--r-- | rtl/go32v2/Makefile.fpc | 68 | ||||
-rw-r--r-- | rtl/i386/i386.inc | 27 | ||||
-rw-r--r-- | rtl/inc/charset.pp | 166 | ||||
-rw-r--r-- | rtl/inc/generic.inc | 9 | ||||
-rw-r--r-- | rtl/inc/genmath.inc | 4 | ||||
-rw-r--r-- | rtl/inc/softfpu.pp | 2 | ||||
-rw-r--r-- | rtl/inc/system.inc | 4 | ||||
-rw-r--r-- | rtl/inc/systemh.inc | 2 | ||||
-rw-r--r-- | rtl/linux/arm/syscall.inc | 4 | ||||
-rw-r--r-- | rtl/msdos/classes.pp | 17 | ||||
-rw-r--r-- | rtl/objpas/character.pas | 130 | ||||
-rw-r--r-- | rtl/objpas/classes/classes.inc | 15 | ||||
-rw-r--r-- | rtl/objpas/classes/classesh.inc | 2 | ||||
-rw-r--r-- | rtl/objpas/classes/stringl.inc | 14 | ||||
-rw-r--r-- | rtl/objpas/fpwidestring.pp | 97 | ||||
-rw-r--r-- | rtl/objpas/sysutils/dati.inc | 9 | ||||
-rw-r--r-- | rtl/objpas/sysutils/datih.inc | 1 | ||||
-rw-r--r-- | rtl/objpas/unicodedata.pas | 1310 | ||||
-rw-r--r-- | rtl/os2/pmwsock.pas | 128 | ||||
-rw-r--r-- | rtl/win64/seh64.inc | 3 | ||||
-rw-r--r-- | rtl/x86_64/math.inc | 23 | ||||
-rw-r--r-- | rtl/x86_64/setjumph.inc | 2 | ||||
-rw-r--r-- | rtl/x86_64/x86_64.inc | 16 |
26 files changed, 1781 insertions, 327 deletions
diff --git a/rtl/arm/arm.inc b/rtl/arm/arm.inc index f1d8da6a3f..2f2d544a5f 100644 --- a/rtl/arm/arm.inc +++ b/rtl/arm/arm.inc @@ -607,7 +607,11 @@ asm movs r0, r1 // unlock and return str r2, [r3] +{$ifdef CPUARM_HAS_BX} bx lr +{$else} + mov pc,lr +{$endif} .Lfpc_system_lock: .long fpc_system_lock @@ -692,7 +696,11 @@ asm mov r0, r1 // unlock and return str r2, [r3] +{$ifdef CPUARM_HAS_BX} bx lr +{$else} + mov pc,lr +{$endif} .Lfpc_system_lock: .long fpc_system_lock @@ -752,7 +760,11 @@ asm // unlock and return mov r2, #0 str r2, [r3] +{$ifdef CPUARM_HAS_BX} bx lr +{$else} + mov pc,lr +{$endif} .Lfpc_system_lock: .long fpc_system_lock @@ -816,7 +828,11 @@ asm // unlock and return mov r2, #0 str r2, [r3] +{$ifdef CPUARM_HAS_BX} bx lr +{$else} + mov pc,lr +{$endif} .Lfpc_system_lock: .long fpc_system_lock @@ -881,7 +897,11 @@ asm // unlock and return mov r3, #0 str r3, [r12] +{$ifdef CPUARM_HAS_BX} bx lr +{$else} + mov pc,lr +{$endif} .Lfpc_system_lock: .long fpc_system_lock diff --git a/rtl/arm/setjump.inc b/rtl/arm/setjump.inc index cc8b729374..bcd66193d1 100644 --- a/rtl/arm/setjump.inc +++ b/rtl/arm/setjump.inc @@ -53,7 +53,11 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S {$else} stmia r0,{v1-v6, sl, fp, sp, lr} mov r0,#0 + {$ifdef CPUARM_HAS_BX} bx lr + {$else} + mov pc,lr + {$endif} {$endif} end; diff --git a/rtl/go32v2/Makefile b/rtl/go32v2/Makefile index 79c8a2fd36..a207dbed5d 100644 --- a/rtl/go32v2/Makefile +++ b/rtl/go32v2/Makefile @@ -1,5 +1,5 @@ # -# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013-04-26 rev 24324] +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/08/13] # default: all MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android i8086-msdos @@ -2837,26 +2837,41 @@ prt0$(OEXT) : v2prt0.as system$(PPUEXT) : system.pp $(SYSDEPS) $(COMPILER) -Us -Sg system.pp uuchar$(PPUEXT): $(SYSTEMUNIT)$(PPUEXT) $(INC)/uuchar.pp + $(COMPILER) $(INC)/uuchar.pp objpas$(PPUEXT): $(OBJPASDIR)/objpas.pp $(INC)/except.inc system$(PPUEXT) $(COMPILER) -Fi$(OBJPASDIR) $(OBJPASDIR)/objpas.pp strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc \ $(PROCINC)/strings.inc $(PROCINC)/stringss.inc \ system$(PPUEXT) + $(COMPILER) $(INC)/strings.pp +iso7185$(PPUEXT) : $(INC)/iso7185.pp system$(PPUEXT) + $(COMPILER) $(INC)/iso7185.pp go32$(PPUEXT) : go32.pp system$(PPUEXT) + $(COMPILER) go32.pp dpmiexcp$(PPUEXT) : dpmiexcp.pp exceptn$(OEXT) system$(PPUEXT) $(COMPILER) -Sg dpmiexcp.pp initc$(PPUEXT) : initc.pp system$(PPUEXT) + $(COMPILER) initc.pp profile$(PPUEXT) : profile.pp dpmiexcp$(PPUEXT) go32$(PPUEXT) + $(COMPILER) profile.pp dxetype$(PPUEXT) : dxetype.pp system$(PPUEXT) + $(COMPILER) dxetype.pp dxeload$(PPUEXT) : dxeload.pp dxetype$(PPUEXT) system$(PPUEXT) + $(COMPILER) dxeload.pp emu387$(PPUEXT) : emu387.pp fpu$(OEXT) strings$(PPUEXT) dxeload$(PPUEXT) \ dpmiexcp$(PPUEXT) + $(COMPILER) emu387.pp ports$(PPUEXT) : ports.pp objpas$(PPUEXT) system$(PPUEXT) + $(COMPILER) ports.pp dos$(PPUEXT) : dos.pp $(INC)/filerec.inc $(INC)/textrec.inc \ go32$(PPUEXT) strings$(PPUEXT) system$(PPUEXT) + $(COMPILER) dos.pp crt$(PPUEXT) : crt.pp $(INC)/textrec.inc go32$(PPUEXT) system$(PPUEXT) + $(COMPILER) crt.pp objects$(PPUEXT) : $(INC)/objects.pp system$(PPUEXT) + $(COMPILER) $(INC)/objects.pp printer$(PPUEXT) : printer.pp system$(PPUEXT) + $(COMPILER) printer.pp sysutils$(PPUEXT) : sysutils.pp $(wildcard $(OBJPASDIR)/sysutils/*.inc) \ objpas$(PPUEXT) dos$(PPUEXT) go32$(PPUEXT) sysconst$(PPUEXT) $(COMPILER) -Fi$(OBJPASDIR)/sysutils sysutils.pp @@ -2894,16 +2909,30 @@ stdconvs$(PPUEXT) : $(OBJPASDIR)/stdconvs.pp objpas$(PPUEXT) system$(PPUEXT) \ macpas$(PPUEXT) : $(INC)/macpas.pp objpas$(PPUEXT) math$(PPUEXT) $(COMPILER) $(INC)/macpas.pp $(REDIR) cpu$(PPUEXT) : $(PROCINC)/cpu.pp system$(PPUEXT) + $(COMPILER) $(PROCINC)/cpu.pp mmx$(PPUEXT) : $(PROCINC)/mmx.pp cpu$(PPUEXT) system$(PPUEXT) + $(COMPILER) $(PROCINC)/mmx.pp getopts$(PPUEXT) : $(INC)/getopts.pp system$(PPUEXT) + $(COMPILER) $(INC)/getopts.pp heaptrc$(PPUEXT) : $(INC)/heaptrc.pp system$(PPUEXT) $(COMPILER) -Sg $(INC)/heaptrc.pp lineinfo$(PPUEXT) : $(INC)/lineinfo.pp system$(PPUEXT) + $(COMPILER) $(INC)/lineinfo.pp lnfodwrf$(PPUEXT) : $(INC)/lnfodwrf.pp system$(PPUEXT) + $(COMPILER) $(INC)/lnfodwrf.pp charset$(PPUEXT) : $(INC)/charset.pp system$(PPUEXT) + $(COMPILER) $(INC)/charset.pp cpall$(PPUEXT): $(RTL)/charmaps/cpall.pas system$(PPUEXT) charset$(PPUEXT) $(COMPILER) -Fu$(INC) -Fi$(RTL)/charmaps $(RTL)/charmaps/cpall.pas +matrix$(PPUEXT) : $(INC)/matrix.pp $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(INC)/matrix.pp ucomplex$(PPUEXT) : $(INC)/ucomplex.pp math$(PPUEXT) system$(PPUEXT) + $(COMPILER) $(INC)/ucomplex.pp msmouse$(PPUEXT) : msmouse.pp system$(PPUEXT) + $(COMPILER) msmouse.pp callspec$(PPUEXT) : $(INC)/callspec.pp system$(PPUEXT) + $(COMPILER) $(INC)/callspec.pp +cmem$(PPUEXT) : $(INC)/cmem.pp $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(INC)/cmem.pp ctypes$(PPUEXT) : $(INC)/ctypes.pp system$(PPUEXT) + $(COMPILER) $(INC)/ctypes.pp diff --git a/rtl/go32v2/Makefile.fpc b/rtl/go32v2/Makefile.fpc index 674b99b691..d144fd487b 100644 --- a/rtl/go32v2/Makefile.fpc +++ b/rtl/go32v2/Makefile.fpc @@ -75,51 +75,87 @@ prt0$(OEXT) : v2prt0.as # system$(PPUEXT) : system.pp $(SYSDEPS) $(COMPILER) -Us -Sg system.pp + uuchar$(PPUEXT): $(SYSTEMUNIT)$(PPUEXT) $(INC)/uuchar.pp + $(COMPILER) $(INC)/uuchar.pp + objpas$(PPUEXT): $(OBJPASDIR)/objpas.pp $(INC)/except.inc system$(PPUEXT) $(COMPILER) -Fi$(OBJPASDIR) $(OBJPASDIR)/objpas.pp + strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc \ $(PROCINC)/strings.inc $(PROCINC)/stringss.inc \ system$(PPUEXT) + $(COMPILER) $(INC)/strings.pp + +iso7185$(PPUEXT) : $(INC)/iso7185.pp system$(PPUEXT) + $(COMPILER) $(INC)/iso7185.pp # # System Dependent Units # go32$(PPUEXT) : go32.pp system$(PPUEXT) + $(COMPILER) go32.pp + dpmiexcp$(PPUEXT) : dpmiexcp.pp exceptn$(OEXT) system$(PPUEXT) $(COMPILER) -Sg dpmiexcp.pp + initc$(PPUEXT) : initc.pp system$(PPUEXT) + $(COMPILER) initc.pp + profile$(PPUEXT) : profile.pp dpmiexcp$(PPUEXT) go32$(PPUEXT) + $(COMPILER) profile.pp + dxetype$(PPUEXT) : dxetype.pp system$(PPUEXT) + $(COMPILER) dxetype.pp + dxeload$(PPUEXT) : dxeload.pp dxetype$(PPUEXT) system$(PPUEXT) + $(COMPILER) dxeload.pp + emu387$(PPUEXT) : emu387.pp fpu$(OEXT) strings$(PPUEXT) dxeload$(PPUEXT) \ dpmiexcp$(PPUEXT) + $(COMPILER) emu387.pp + ports$(PPUEXT) : ports.pp objpas$(PPUEXT) system$(PPUEXT) + $(COMPILER) ports.pp + # # TP7 Compatible RTL Units # dos$(PPUEXT) : dos.pp $(INC)/filerec.inc $(INC)/textrec.inc \ go32$(PPUEXT) strings$(PPUEXT) system$(PPUEXT) + $(COMPILER) dos.pp + crt$(PPUEXT) : crt.pp $(INC)/textrec.inc go32$(PPUEXT) system$(PPUEXT) + $(COMPILER) crt.pp + objects$(PPUEXT) : $(INC)/objects.pp system$(PPUEXT) + $(COMPILER) $(INC)/objects.pp + printer$(PPUEXT) : printer.pp system$(PPUEXT) + $(COMPILER) printer.pp # # Delphi Compatible Units # sysutils$(PPUEXT) : sysutils.pp $(wildcard $(OBJPASDIR)/sysutils/*.inc) \ objpas$(PPUEXT) dos$(PPUEXT) go32$(PPUEXT) sysconst$(PPUEXT) $(COMPILER) -Fi$(OBJPASDIR)/sysutils sysutils.pp + classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \ sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) types$(PPUEXT) fgl$(PPUEXT) $(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp + fgl$(PPUEXT) : $(OBJPASDIR)/fgl.pp objpas$(PPUEXT) types$(PPUEXT) system$(PPUEXT) sysutils$(PPUEXT) $(COMPILER) $(OBJPASDIR)/fgl.pp + math$(PPUEXT): $(OBJPASDIR)/math.pp objpas$(PPUEXT) sysutils$(PPUEXT) $(COMPILER) $(OBJPASDIR)/math.pp + typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT) rtlconst$(PPUEXT) $(COMPILER) -Sg -Fi$(OBJPASDIR) $(OBJPASDIR)/typinfo.pp + varutils$(PPUEXT) : $(OBJPASDIR)/cvarutil.inc $(OBJPASDIR)/varutils.inc \ $(OBJPASDIR)/varutilh.inc varutils.pp sysutils$(PPUEXT) $(COMPILER) -I$(OBJPASDIR) varutils.pp + variants$(PPUEXT) : $(INC)/variants.pp varutils$(PPUEXT) sysutils$(PPUEXT) sysconst$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) $(COMPILER) -Fi$(INC) $(INC)/variants.pp @@ -128,16 +164,22 @@ fmtbcd$(PPUEXT) : $(OBJPASDIR)/fmtbcd.pp objpas$(PPUEXT) sysutils$(PPUEXT) varia types$(PPUEXT) : $(OBJPASDIR)/types.pp objpas$(PPUEXT) $(COMPILER) $(OBJPASDIR)/types.pp + rtlconst$(PPUEXT) : $(OBJPASDIR)/rtlconst.pp $(COMPILER) -Fi$(OBJPASDIR) $(OBJPASDIR)/rtlconst.pp + sysconst$(PPUEXT) : $(OBJPASDIR)/sysconst.pp objpas$(PPUEXT) $(COMPILER) $(OBJPASDIR)/sysconst.pp + dateutil$(PPUEXT) : $(OBJPASDIR)/dateutil.pp $(COMPILER) -Fi$(OBJPASDIR) $(OBJPASDIR)/dateutil.pp + convutil$(PPUEXT) : $(OBJPASDIR)/convutil.pp $(COMPILER) -Fi$(OBJPASDIR) $(OBJPASDIR)/convutil.pp + strutils$(PPUEXT) : $(OBJPASDIR)/strutils.pp $(COMPILER) $(OBJPASDIR)/strutils.pp + stdconvs$(PPUEXT) : $(OBJPASDIR)/stdconvs.pp objpas$(PPUEXT) system$(PPUEXT) \ sysutils$(PPUEXT) $(COMPILER) $(OBJPASDIR)/stdconvs.pp @@ -150,20 +192,46 @@ macpas$(PPUEXT) : $(INC)/macpas.pp objpas$(PPUEXT) math$(PPUEXT) # Other system-independent RTL Units # cpu$(PPUEXT) : $(PROCINC)/cpu.pp system$(PPUEXT) + $(COMPILER) $(PROCINC)/cpu.pp + mmx$(PPUEXT) : $(PROCINC)/mmx.pp cpu$(PPUEXT) system$(PPUEXT) + $(COMPILER) $(PROCINC)/mmx.pp + getopts$(PPUEXT) : $(INC)/getopts.pp system$(PPUEXT) + $(COMPILER) $(INC)/getopts.pp + heaptrc$(PPUEXT) : $(INC)/heaptrc.pp system$(PPUEXT) $(COMPILER) -Sg $(INC)/heaptrc.pp + lineinfo$(PPUEXT) : $(INC)/lineinfo.pp system$(PPUEXT) + $(COMPILER) $(INC)/lineinfo.pp + lnfodwrf$(PPUEXT) : $(INC)/lnfodwrf.pp system$(PPUEXT) + $(COMPILER) $(INC)/lnfodwrf.pp + charset$(PPUEXT) : $(INC)/charset.pp system$(PPUEXT) + $(COMPILER) $(INC)/charset.pp + cpall$(PPUEXT): $(RTL)/charmaps/cpall.pas system$(PPUEXT) charset$(PPUEXT) $(COMPILER) -Fu$(INC) -Fi$(RTL)/charmaps $(RTL)/charmaps/cpall.pas + +matrix$(PPUEXT) : $(INC)/matrix.pp $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(INC)/matrix.pp + ucomplex$(PPUEXT) : $(INC)/ucomplex.pp math$(PPUEXT) system$(PPUEXT) + $(COMPILER) $(INC)/ucomplex.pp # # Other system-dependent RTL Units # msmouse$(PPUEXT) : msmouse.pp system$(PPUEXT) + $(COMPILER) msmouse.pp + callspec$(PPUEXT) : $(INC)/callspec.pp system$(PPUEXT) + $(COMPILER) $(INC)/callspec.pp + +cmem$(PPUEXT) : $(INC)/cmem.pp $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(INC)/cmem.pp + ctypes$(PPUEXT) : $(INC)/ctypes.pp system$(PPUEXT) + $(COMPILER) $(INC)/ctypes.pp diff --git a/rtl/i386/i386.inc b/rtl/i386/i386.inc index b931e77d4a..7bd65eecdc 100644 --- a/rtl/i386/i386.inc +++ b/rtl/i386/i386.inc @@ -50,9 +50,9 @@ function cpuid_support : boolean;assembler; {$asmmode ATT} -function sse_support : boolean; +procedure check_sse_support; var - _edx : longint; + _ecx,_edx : longint; begin if cpuid_support then begin @@ -61,13 +61,20 @@ function sse_support : boolean; movl $1,%eax cpuid movl %edx,_edx + movl %ecx,_ecx popl %ebx end; - sse_support:=((_edx and $2000000)<>0) and os_supports_sse; + has_sse_support:=((_edx and $2000000)<>0) and os_supports_sse; + has_sse2_support:=((_edx and $4000000)<>0) and os_supports_sse; + has_sse3_support:=((_ecx and $200)<>0) and os_supports_sse; end else - { a cpu with without cpuid instruction supports never sse } - sse_support:=false; + begin + { a cpu with without cpuid instruction supports never sse } + has_sse_support:=false; + has_sse2_support:=false; + has_sse3_support:=false; + end; end; @@ -1424,7 +1431,8 @@ Procedure SysResetFPU; procedure fpc_cpucodeinit; begin os_supports_sse:=true; - os_supports_sse:=sse_support; + check_sse_support; + os_supports_sse:=has_sse_support; if os_supports_sse then begin sse_check:=true; @@ -1437,6 +1445,11 @@ procedure fpc_cpucodeinit; sse_check:=false; end; has_sse_support:=os_supports_sse; + if not(has_sse_support) then + begin + has_sse2_support:=false; + has_sse3_support:=false; + end; { don't let libraries influence the FPU cw set by the host program } if has_sse_support and IsLibrary then @@ -1611,4 +1624,4 @@ asm sarl %cl,%eax .Lexit: end; -{$endif FPC_SYSTEM_HAS_SAR_QWORD}
\ No newline at end of file +{$endif FPC_SYSTEM_HAS_SAR_QWORD} diff --git a/rtl/inc/charset.pp b/rtl/inc/charset.pp index d8d911009f..07efb7c1eb 100644 --- a/rtl/inc/charset.pp +++ b/rtl/inc/charset.pp @@ -15,6 +15,7 @@ **********************************************************************} {$mode objfpc} {$pointermath on} +{$PACKENUM 1} unit charset; interface @@ -31,14 +32,14 @@ unit charset; umf_unused); punicodecharmapping = ^tunicodecharmapping; - tunicodecharmapping = record + tunicodecharmapping = packed record unicode : tunicodechar; flag : tunicodecharmappingflag; reserved : byte; end; preversecharmapping = ^treversecharmapping; - treversecharmapping = record + treversecharmapping = packed record unicode : tunicodechar; char1 : Byte; char2 : Byte; @@ -59,8 +60,26 @@ unit charset; tcp2unicode = class(tcsconvert) end; + TSerializedMapHeader = packed record + cpName : string[20]; + cp : UInt16; + mapLength : UInt32; + lastChar : Int32; + reverseMapLength : UInt32; + end; + + const + BINARY_MAPPING_FILE_EXT = '.bcm'; + function loadunicodemapping(const cpname,f : string; cp :word) : punicodemap; + function loadbinaryunicodemapping(const directory,cpname : string) : punicodemap;overload; + function loadbinaryunicodemapping(const filename : string) : punicodemap;overload; + function loadbinaryunicodemapping( + const AData : Pointer; + const ADataLength : Integer + ) : punicodemap;overload; procedure registermapping(p : punicodemap); + function registerbinarymapping(const directory,cpname : string):Boolean; function getmap(const s : string) : punicodemap; function getmap(cp : word) : punicodemap; function mappingavailable(const s : string) : boolean;inline; @@ -371,6 +390,136 @@ unit charset; loadunicodemapping:=p; end; + + function loadbinaryunicodemapping(const directory, cpname : string) : punicodemap; + const + {$IFDEF ENDIAN_LITTLE} + ENDIAN_SUFFIX = 'le'; + {$ENDIF ENDIAN_LITTLE} + {$IFDEF ENDIAN_BIG} + ENDIAN_SUFFIX = 'be'; + {$ENDIF ENDIAN_BIG} + var + fileName : string; + begin + fileName := directory; + if (fileName <> '') then begin + if (fileName[Length(fileName)] <> DirectorySeparator) then + fileName := fileName + DirectorySeparator; + end; + fileName := fileName + cpname + '_' + ENDIAN_SUFFIX + BINARY_MAPPING_FILE_EXT; + Result := loadbinaryunicodemapping(fileName); + end; + + {$PUSH} + {$I-} + function loadbinaryunicodemapping(const filename : string) : punicodemap; + const + BLOCK_SIZE = 16*1024; + var + f : File of Byte; + locSize, locReaded, c : LongInt; + locBuffer : PByte; + locBlockSize : LongInt; + begin + Result := nil; + if (filename='') then + exit; + Assign(f,filename); + Reset(f); + if (IOResult<>0) then + begin + Close(f); + exit; + end; + locSize:=FileSize(f); + if (locSize<SizeOf(TSerializedMapHeader)) then + begin + Close(f); + exit; + end; + locBuffer:=GetMem(locSize); + locBlockSize:=BLOCK_SIZE; + locReaded:=0; + c := 0; + while (locReaded<locSize) do + begin + if (locBlockSize>(locSize-locReaded)) then + locBlockSize:=locSize-locReaded; + BlockRead(f,locBuffer[locReaded],locBlockSize,c); + if (IOResult<>0) or (c<=0) then + begin + FreeMem(locBuffer,locSize); + Close(f); + exit; + end; + locReaded:=locReaded+c; + end; + Result:=loadbinaryunicodemapping(locBuffer,locSize); + FreeMem(locBuffer,locSize); + Close(f); + end; + {$POP} + + procedure freemapping(amapping : punicodemap); + begin + if (amapping = nil) then + exit; + if (amapping^.map <> nil) then + freemem(amapping^.map); + if (amapping^.reversemap <> nil) then + freemem(amapping^.reversemap); + dispose(amapping); + end; + + function loadbinaryunicodemapping( + const AData : Pointer; + const ADataLength : Integer + ) : punicodemap; + var + dataPointer : PByte; + readedLength : LongInt; + + function ReadBuffer(ADest : Pointer; ALength : LongInt) : Boolean; + begin + Result := (readedLength + ALength) <= ADataLength; + if not result then + exit; + Move(dataPointer^,ADest^,ALength); + Inc(dataPointer,ALength); + readedLength := readedLength + ALength; + end; + + var + h : TSerializedMapHeader; + r : punicodemap; + begin + Result := nil; + readedLength := 0; + dataPointer := AData; + if not ReadBuffer(@h,SizeOf(h)) then + exit; + New(r); + FillChar(r^,SizeOf(tunicodemap),0); + r^.cpname := h.cpName; + r^.cp := h.cp; + r^.map := AllocMem(h.mapLength); + if not ReadBuffer(r^.map,h.mapLength) then + begin + freemapping(r); + exit; + end; + r^.lastchar := h.lastChar; + r^.reversemap := AllocMem(h.reverseMapLength); + if not ReadBuffer(r^.reversemap,h.reverseMapLength) then + begin + freemapping(r); + exit; + end; + r^.reversemaplength := (h.reverseMapLength div SizeOf(treversecharmapping)); + Result := r; + end; + procedure registermapping(p : punicodemap); begin @@ -385,6 +534,19 @@ unit charset; {$endif FPC_HAS_FEATURE_THREADING} strmapcache : string; strmapcachep : punicodemap; + + function registerbinarymapping(const directory, cpname : string) : Boolean; + var + p : punicodemap; + begin + Result := False; + p := loadbinaryunicodemapping(directory,cpname); + if (p = nil) then + exit; + registermapping(p); + Result := True; + end; + function getmap(const s : string) : punicodemap; var diff --git a/rtl/inc/generic.inc b/rtl/inc/generic.inc index 4ded841654..d8af3fac1f 100644 --- a/rtl/inc/generic.inc +++ b/rtl/inc/generic.inc @@ -358,7 +358,7 @@ begin if (len < 0) or (len > high(PtrInt) div 2) or (psrc+len < psrc) then - pend:=pdword(high(PtrUInt)-sizeof(dword)) + pend:=pdword(high(PtrUInt)-PtrUInt(sizeof(dword))) else pend:=psrc+len; {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} @@ -399,7 +399,7 @@ begin if (len < 0) or (len > high(PtrInt) div 4) or (psrc+len < psrc) then - pend:=pqword(high(PtrUInt)-sizeof(qword)) + pend:=pqword(high(PtrUInt)-PtrUInt(sizeof(qword))) else pend:=psrc+len; {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} @@ -548,8 +548,7 @@ begin inc(pptruint(psrc)); end; end; - if (len <= high(ptrint)) and - (psrc+len >= psrc) then + if (psrc+len >= psrc) then pend:=psrc+len else pend:=pword(high(ptruint)-2); @@ -689,7 +688,7 @@ begin { simulate assembler implementations behaviour, which is expected } { fpc_pchar_to_ansistr in astrings.inc } if (len < 0) then - pend:=pbyte(high(PtrUInt)-sizeof(byte)) + pend:=pbyte(high(PtrUInt)-PtrUInt(sizeof(byte))) else pend:=psrc+len; while (psrc<pend) and (psrc^<>0) do diff --git a/rtl/inc/genmath.inc b/rtl/inc/genmath.inc index ff07f35c90..90f385adf9 100644 --- a/rtl/inc/genmath.inc +++ b/rtl/inc/genmath.inc @@ -224,7 +224,7 @@ type invalid: float_raise(float_flag_invalid); if (aSign <> 0) then - float64_to_int32_round_to_zero:=$80000000 + float64_to_int32_round_to_zero:=longint($80000000) else float64_to_int32_round_to_zero:=$7FFFFFFF; exit; @@ -333,7 +333,7 @@ invalid: exit; end; End; - float32_to_int32_round_to_zero:=$80000000; + float32_to_int32_round_to_zero:=longint($80000000); exit; End else diff --git a/rtl/inc/softfpu.pp b/rtl/inc/softfpu.pp index e4c9a9d6f1..179292565a 100644 --- a/rtl/inc/softfpu.pp +++ b/rtl/inc/softfpu.pp @@ -762,7 +762,7 @@ begin end else begin - if ( count < 64 ) then + if ( count < 128 ) then z1 := a0 shr ( count and 63 ) else z1 := 0; diff --git a/rtl/inc/system.inc b/rtl/inc/system.inc index a087949aa4..0c4bebc037 100644 --- a/rtl/inc/system.inc +++ b/rtl/inc/system.inc @@ -217,10 +217,10 @@ function do_isdevice(handle:thandle):boolean;forward; {$Error Can't determine processor type !} {$endif} {$i armdefines.inc} - {$if defined(CPUARMV7EM) or defined(CPUARMV7M)} + {$if defined(CPUTHUMB2)} {$i thumb2.inc} { Case dependent, don't change } {$else} - {$if defined(CPUARMV6M)} + {$if defined(CPUTHUMB)} {$i thumb.inc} { Case dependent, don't change } {$else} {$i arm.inc} { Case dependent, don't change } diff --git a/rtl/inc/systemh.inc b/rtl/inc/systemh.inc index db6069c450..3631282117 100644 --- a/rtl/inc/systemh.inc +++ b/rtl/inc/systemh.inc @@ -594,6 +594,8 @@ const Test8087 : byte = 3; { will be detected at startup } has_sse_support : boolean = false; + has_sse2_support : boolean = false; + has_sse3_support : boolean = false; has_mmx_support : boolean = false; {$endif cpui386} {$ifdef cpui8086} diff --git a/rtl/linux/arm/syscall.inc b/rtl/linux/arm/syscall.inc index ccee630598..142cb99761 100644 --- a/rtl/linux/arm/syscall.inc +++ b/rtl/linux/arm/syscall.inc @@ -235,6 +235,7 @@ asm swi #0x0 cmn r0,#126 ldr r7,[sp],#4 + it ls movls pc,lr stmfd sp!,{lr} rsb r0,r0,#0 @@ -255,6 +256,7 @@ asm swi #0x0 cmn r0,#126 ldr r7,[sp],#4 + it ls movls pc,lr stmfd sp!,{lr} rsb r0,r0,#0 @@ -276,6 +278,7 @@ asm swi #0x0 cmn r0,#126 ldr r7,[sp],#4 + it ls movls pc,lr stmfd sp!,{lr} rsb r0,r0,#0 @@ -298,6 +301,7 @@ asm swi #0x0 cmn r0,#126 ldr r7,[sp],#4 + it ls movls pc,lr stmfd sp!,{lr} rsb r0,r0,#0 diff --git a/rtl/msdos/classes.pp b/rtl/msdos/classes.pp index cbd5d78c70..95fb6253c4 100644 --- a/rtl/msdos/classes.pp +++ b/rtl/msdos/classes.pp @@ -18,6 +18,14 @@ { determine the type of the resource/form file } {$define Win16Res} +{$if defined(FPC_MM_TINY) or defined(FPC_MM_SMALL) or defined(FPC_MM_LARGE) or defined(FPC_MM_HUGE)} + { CodePointer = Pointer; nothing to define } +{$elseif defined(FPC_MM_MEDIUM) or defined(FPC_MM_COMPACT)} + {$define FPC_CODEPOINTER_DIFFERENT_THAN_POINTER} +{$else} + {$fatal Unknown i8086 memory model.} +{$endif} + unit Classes; interface @@ -26,7 +34,7 @@ uses typinfo, rtlconsts, types, -{$ifdef FPC_TESTGENERICS} +{$if defined(FPC_TESTGENERICS) or defined(FPC_CODEPOINTER_DIFFERENT_THAN_POINTER)} fgl, {$endif} sysutils; @@ -35,6 +43,13 @@ uses implementation +type +{$ifdef FPC_CODEPOINTER_DIFFERENT_THAN_POINTER} + TCodePtrList = specialize TFPGList<CodePointer>; +{$else FPC_CODEPOINTER_DIFFERENT_THAN_POINTER} + TCodePtrList = TList; +{$endif FPC_CODEPOINTER_DIFFERENT_THAN_POINTER} + { OS - independent class implementations are in /inc directory. } {$i classes.inc} diff --git a/rtl/objpas/character.pas b/rtl/objpas/character.pas index b288df12ff..df7df76734 100644 --- a/rtl/objpas/character.pas +++ b/rtl/objpas/character.pas @@ -820,64 +820,13 @@ begin end; class function TCharacter.ToLower(const AString : UnicodeString; const AOptions : TCharacterOptions) : UnicodeString; -var - i, c : SizeInt; - pp, pr : PUnicodeChar; - pu : PUC_Prop; - locIsSurrogate, locIgnoreInvalid : Boolean; -begin - c := Length(AString); - SetLength(Result,2*c); - if (c > 0) then begin - locIgnoreInvalid := (TCharacterOption.coIgnoreInvalidSequence in AOptions); - pp := @AString[1]; - pr := @Result[1]; - i := 1; - while (i <= c) do begin - pu := GetProps(Word(pp^)); - locIsSurrogate := (TUnicodeCategory(pu^.Category) = TUnicodeCategory.ucSurrogate); - if locIsSurrogate then begin - if locIgnoreInvalid then begin - if (i = c) or not(IsSurrogatePair(pp[0],pp[1])) then begin - pr^ := pp^; - Inc(pp); - Inc(pr); - Inc(i); - Continue; - end; - end; - if not IsSurrogatePair(AString,i) then - raise EArgumentException.Create(SInvalidUnicodeCodePointSequence); - pu := GetProps(pp^,AString[i+1]); - end; - if (pu^.SimpleLowerCase = 0) then begin - pr^ := pp^; - if locIsSurrogate then begin - Inc(pp); - Inc(pr); - Inc(i); - pr^ := pp^; - end; - end else begin - if (pu^.SimpleLowerCase <= $FFFF) then begin - pr^ := UnicodeChar(Word(pu^.SimpleLowerCase)); - end else begin - FromUCS4(UCS4Char(Cardinal(pu^.SimpleLowerCase)),pr^,PUnicodeChar(PtrUInt(pr)+SizeOf(UnicodeChar))^); - Inc(pr); - end; - if locIsSurrogate then begin - Inc(pp); - Inc(i); - end; - end; - Inc(pp); - Inc(pr); - Inc(i); - end; - Dec(pp); - i := ((PtrUInt(pr) - PtrUInt(@Result[1])) div SizeOf(UnicodeChar)); - SetLength(Result,i) - end; +begin + if (UnicodeToLower( + AString,(TCharacterOption.coIgnoreInvalidSequence in AOptions),Result + ) <> 0 + ) + then + raise EArgumentException.Create(SInvalidUnicodeCodePointSequence); end; class function TCharacter.ToUpper(AChar : UnicodeChar) : UnicodeChar; @@ -893,64 +842,13 @@ begin end; class function TCharacter.ToUpper(const AString : UnicodeString; const AOptions : TCharacterOptions) : UnicodeString; -var - i, c : SizeInt; - pp, pr : PUnicodeChar; - pu : PUC_Prop; - locIsSurrogate, locIgnoreInvalid : Boolean; -begin - c := Length(AString); - SetLength(Result,2*c); - if (c > 0) then begin - locIgnoreInvalid := (TCharacterOption.coIgnoreInvalidSequence in AOptions); - pp := @AString[1]; - pr := @Result[1]; - i := 1; - while (i <= c) do begin - pu := GetProps(Word(pp^)); - locIsSurrogate := (TUnicodeCategory(pu^.Category) = TUnicodeCategory.ucSurrogate); - if locIsSurrogate then begin - if locIgnoreInvalid then begin - if (i = c) or not(IsSurrogatePair(pp[0],pp[1])) then begin - pr^ := pp^; - Inc(pp); - Inc(pr); - Inc(i); - Continue; - end; - end; - if not IsSurrogatePair(AString,i) then - raise EArgumentException.Create(SInvalidUnicodeCodePointSequence); - pu := GetProps(pp^,AString[i+1]); - end; - if (pu^.SimpleUpperCase = 0) then begin - pr^ := pp^; - if locIsSurrogate then begin - Inc(pp); - Inc(pr); - Inc(i); - pr^ := pp^; - end; - end else begin - if (pu^.SimpleUpperCase <= $FFFF) then begin - pr^ := UnicodeChar(Word(pu^.SimpleUpperCase)); - end else begin - FromUCS4(UCS4Char(Cardinal(pu^.SimpleUpperCase)),pr^,PUnicodeChar(PtrUInt(pr)+SizeOf(UnicodeChar))^); - Inc(pr); - end; - if locIsSurrogate then begin - Inc(pp); - Inc(i); - end; - end; - Inc(pp); - Inc(pr); - Inc(i); - end; - Dec(pp); - i := ((PtrUInt(pr) - PtrUInt(@Result[1])) div SizeOf(UnicodeChar)); - SetLength(Result,i) - end; +begin + if (UnicodeToUpper( + AString,(TCharacterOption.coIgnoreInvalidSequence in AOptions),Result + ) <> 0 + ) + then + raise EArgumentException.Create(SInvalidUnicodeCodePointSequence); end; {$endif VER2_4} diff --git a/rtl/objpas/classes/classes.inc b/rtl/objpas/classes/classes.inc index da6d0d46a9..970dd61dd0 100644 --- a/rtl/objpas/classes/classes.inc +++ b/rtl/objpas/classes/classes.inc @@ -881,23 +881,28 @@ Type AClass : TComponentClass; end; +{$ifndef i8086} +type + TCodePtrList = TList; +{$endif i8086} + Var InitHandlerList : TList; - FindGlobalComponentList : TList; + FindGlobalComponentList : TCodePtrList; procedure RegisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); begin if not(assigned(FindGlobalComponentList)) then - FindGlobalComponentList:=TList.Create; - if FindGlobalComponentList.IndexOf(Pointer(AFindGlobalComponent))<0 then - FindGlobalComponentList.Add(Pointer(AFindGlobalComponent)); + FindGlobalComponentList:=TCodePtrList.Create; + if FindGlobalComponentList.IndexOf(CodePointer(AFindGlobalComponent))<0 then + FindGlobalComponentList.Add(CodePointer(AFindGlobalComponent)); end; procedure UnregisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); begin if assigned(FindGlobalComponentList) then - FindGlobalComponentList.Remove(Pointer(AFindGlobalComponent)); + FindGlobalComponentList.Remove(CodePointer(AFindGlobalComponent)); end; diff --git a/rtl/objpas/classes/classesh.inc b/rtl/objpas/classes/classesh.inc index 7148cfc29b..472103c77b 100644 --- a/rtl/objpas/classes/classesh.inc +++ b/rtl/objpas/classes/classesh.inc @@ -730,7 +730,7 @@ type FOwnsObjects : Boolean; procedure ExchangeItems(Index1, Index2: Integer); procedure Grow; - procedure InternalClear; + procedure InternalClear(FromIndex : Integer = 0; ClearOnly : Boolean = False); procedure QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); procedure SetSorted(Value: Boolean); procedure SetCaseSensitive(b : boolean); diff --git a/rtl/objpas/classes/stringl.inc b/rtl/objpas/classes/stringl.inc index f7af390a2e..01d222794f 100644 --- a/rtl/objpas/classes/stringl.inc +++ b/rtl/objpas/classes/stringl.inc @@ -964,7 +964,7 @@ begin SetCapacity(NC); end; -Procedure TStringList.InternalClear; +Procedure TStringList.InternalClear(FromIndex : Integer = 0; ClearOnly : Boolean = False); Var I: Integer; @@ -972,7 +972,7 @@ Var begin if FOwnsObjects then begin - For I:=0 to FCount-1 do + For I:=FromIndex to FCount-1 do begin Flist^[I].FString:=''; freeandnil(Flist^[i].FObject); @@ -980,11 +980,12 @@ begin end else begin - For I:=0 to FCount-1 do + For I:=FromIndex to FCount-1 do Flist^[I].FString:=''; end; - FCount:=0; - SetCapacity(0); + FCount:=FromIndex; + if Not ClearOnly then + SetCapacity(0); end; Procedure TStringList.QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); @@ -1147,7 +1148,7 @@ end; Procedure TStringList.SetCapacity(NewCapacity: Integer); Var NewList : Pointer; - MSize : Longint; + I,MSize : Longint; begin If (NewCapacity<0) then @@ -1175,6 +1176,7 @@ begin FList := nil; end else begin + InternalClear(NewCapacity,True); GetMem(NewList, NewCapacity * SizeOf(TStringItem)); System.Move(FList^, NewList^, NewCapacity * SizeOf(TStringItem)); FreeMem(FList); diff --git a/rtl/objpas/fpwidestring.pp b/rtl/objpas/fpwidestring.pp index 536e451e5f..5aaf0928be 100644 --- a/rtl/objpas/fpwidestring.pp +++ b/rtl/objpas/fpwidestring.pp @@ -23,7 +23,7 @@ uses {$ifdef Unix} unixcp, {$endif} - sysutils, character, charset; + charset; procedure fpc_rangeerror; [external name 'FPC_RANGEERROR']; {$ifdef MSWINDOWS} @@ -31,7 +31,7 @@ procedure fpc_rangeerror; [external name 'FPC_RANGEERROR']; {$endif MSWINDOWS} const - CharacterOptions = [TCharacterOption.coIgnoreInvalidSequence]; + IgnoreInvalidSequenceFlag = True; var OldManager : TUnicodeStringManager; @@ -90,6 +90,21 @@ begin current_Map:=nil; end; +function FindMap(const cp: TSystemCodePage): punicodemap;inline; +begin + if (cp=DefaultSystemCodePage) then + begin + { update current_Map in case the DefaultSystemCodePage has been changed } + if (current_DefaultSystemCodePage<>DefaultSystemCodePage) or not Assigned(current_Map) then + begin + FiniThread; + InitThread; + end; + Result:=current_Map; + end + else + Result:=getmap(cp); +end; { return value: -1 if incomplete or invalid code point @@ -247,18 +262,7 @@ begin exit; end; - if (cp=DefaultSystemCodePage) then - begin - { update current_Map in case the DefaultSystemCodePage has been changed } - if current_DefaultSystemCodePage<>DefaultSystemCodePage then - begin - FiniThread; - InitThread; - end; - locMap:=current_Map; - end - else - locMap:=getmap(cp); + locMap:=FindMap(cp); if (locMap=nil) then begin DefaultUnicode2AnsiMove(source,dest,DefaultSystemCodePage,len); @@ -320,18 +324,7 @@ begin exit; end; - if (cp=DefaultSystemCodePage) then - begin - { update current_Map in case the DefaultSystemCodePage has been changed } - if current_DefaultSystemCodePage<>DefaultSystemCodePage then - begin - FiniThread; - InitThread; - end; - locMap:=current_Map; - end - else - locMap:=getmap(cp); + locMap:=FindMap(cp); if (locMap=nil) then begin DefaultAnsi2UnicodeMove(source,DefaultSystemCodePage,dest,len); @@ -355,18 +348,7 @@ begin exit; end; - if (cp=DefaultSystemCodePage) then - begin - { update current_Map in case the DefaultSystemCodePage has been changed } - if current_DefaultSystemCodePage<>DefaultSystemCodePage then - begin - FiniThread; - InitThread; - end; - locMap:=current_Map; - end - else - locMap:=getmap(cp); + locMap:=FindMap(cp); if (locMap=nil) then begin DefaultAnsi2WideMove(source,DefaultSystemCodePage,dest,len); @@ -381,7 +363,8 @@ end; function UpperUnicodeString(const S: UnicodeString): UnicodeString; begin - Result:=TCharacter.ToUpper(s,CharacterOptions); + if (UnicodeToUpper(S,IgnoreInvalidSequenceFlag,Result) <> 0) then + system.error(reRangeError); end; function UpperWideString(const S: WideString): WideString; @@ -394,7 +377,8 @@ end; function LowerUnicodeString(const S: UnicodeString): UnicodeString; begin - Result:=TCharacter.ToLower(s,CharacterOptions); + if (UnicodeToLower(S,IgnoreInvalidSequenceFlag,Result) <> 0) then + system.error(reRangeError); end; function LowerWideString(const S: WideString): WideString; @@ -405,16 +389,13 @@ begin Result:=LowerUnicodeString(u); end; -function CompareUnicodeStringUCA(p1,p2:PUnicodeChar; l1,l2:PtrInt) : PtrInt; -var - k1, k2 : TUCASortKey; + +function CompareUnicodeStringUCA(p1,p2:PUnicodeChar; l1,l2:PtrInt) : PtrInt;inline; begin - k1 := ComputeSortKey(p1,l1,current_Collation); - k2 := ComputeSortKey(p2,l2,current_Collation); - Result := CompareSortKey(k1,k2); + Result := IncrementalCompareString(p1,l1,p2,l2,current_Collation); end; -function CompareUnicodeString(p1,p2:PUnicodeChar; l1,l2:PtrInt) : PtrInt; +function CompareUnicodeString(p1,p2:PUnicodeChar; l1,l2:PtrInt) : PtrInt;inline; begin if (Pointer(p1)=Pointer(p2)) then exit(0); @@ -502,13 +483,8 @@ begin UnicodeToUtf8(@Result[1],slen,@us[1],ulen); exit; end; - - if current_DefaultSystemCodePage<>DefaultSystemCodePage then - begin - FiniThread; - InitThread; - end; - locMap:=current_Map; + + locMap:=FindMap(DefaultSystemCodePage); if (locMap=nil) then exit(System.UpCase(s)); @@ -532,7 +508,7 @@ begin ulen:=getunicode(p,mblen,locMap,@us[1]); if (Length(us)<>ulen) then SetLength(us,ulen); - usl:=TCharacter.ToUpper(us,CharacterOptions); + usl:=UpperUnicodeString(us); for k:=1 to Length(usl) do begin aalen:=getascii(tunicodechar(us[k]),locMap,@aa[Low(aa)],Length(aa)); @@ -574,12 +550,7 @@ begin UnicodeToUtf8(@Result[1],slen,@us[1],ulen); exit; end; - if current_DefaultSystemCodePage<>DefaultSystemCodePage then - begin - FiniThread; - InitThread; - end; - locMap:=current_Map; + locMap:=FindMap(DefaultSystemCodePage); if (locMap=nil) then exit(System.LowerCase(s)); @@ -603,7 +574,7 @@ begin ulen:=getunicode(p,mblen,locMap,@us[1]); if (Length(us)<>ulen) then SetLength(us,ulen); - usl:=TCharacter.ToLower(us,CharacterOptions); + usl:=LowerUnicodeString(us); for k:=1 to Length(usl) do begin aalen:=getascii(tunicodechar(us[k]),locMap,@aa[Low(aa)],Length(aa)); @@ -717,7 +688,7 @@ end; function StrCompAnsiString(S1, S2: PChar): PtrInt; var - l1,l2,l : PtrInt; + l1,l2 : PtrInt; begin l1:=strlen(S1); l2:=strlen(S2); diff --git a/rtl/objpas/sysutils/dati.inc b/rtl/objpas/sysutils/dati.inc index 3e0f901f78..832bbc0f48 100644 --- a/rtl/objpas/sysutils/dati.inc +++ b/rtl/objpas/sysutils/dati.inc @@ -502,6 +502,15 @@ begin Raise EConvertError.Create(Msg); end; +function StrToDate(const S: string; FormatSettings: TFormatSettings): TDateTime; +var + Msg: AnsiString; +begin + Result:=IntStrToDate(Msg,@S[1],Length(S),FormatSettings.ShortDateFormat,FormatSettings); + if Msg<>'' then + raise EConvertError.Create(Msg); +end; + function StrToDate(const S: ShortString; const useformat : string; separator : char = #0): TDateTime; begin result := StrToDate(@S[1],Length(s),UseFormat,separator); diff --git a/rtl/objpas/sysutils/datih.inc b/rtl/objpas/sysutils/datih.inc index 783a427a01..b8dde2ea2b 100644 --- a/rtl/objpas/sysutils/datih.inc +++ b/rtl/objpas/sysutils/datih.inc @@ -125,6 +125,7 @@ function StrToDate(const S: ShortString): TDateTime; {$ifdef SY function StrToDate(const S: Ansistring): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif} function StrToDate(const S: ShortString; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif} function StrToDate(const S: AnsiString; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif} +function StrToDate(const S: string; FormatSettings : TFormatSettings): TDateTime; function StrToTime(const S: Shortstring): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif} function StrToTime(const S: Ansistring): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif} function StrToTime(const S: ShortString; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif} diff --git a/rtl/objpas/unicodedata.pas b/rtl/objpas/unicodedata.pas index 2403a9b658..fc39f0ad0a 100644 --- a/rtl/objpas/unicodedata.pas +++ b/rtl/objpas/unicodedata.pas @@ -274,6 +274,7 @@ type Props : PUCA_PropItemRec; VariableLowLimit : Word; VariableHighLimit : Word; + Dynamic : Boolean; public function IsVariable(const AWeight : PUCA_PropWeights) : Boolean; inline; end; @@ -283,6 +284,7 @@ type const ROOT_COLLATION_NAME = 'DUCET'; + ERROR_INVALID_CODEPOINT_SEQUENCE = 1; procedure FromUCS4(const AValue : UCS4Char; var AHighS, ALowS : UnicodeChar);inline; function ToUCS4(const AHighS, ALowS : UnicodeChar) : UCS4Char;inline; @@ -292,6 +294,16 @@ const ) : Boolean;inline; function UnicodeIsHighSurrogate(const AValue : UnicodeChar) : Boolean;inline; function UnicodeIsLowSurrogate(const AValue : UnicodeChar) : Boolean;inline; + function UnicodeToUpper( + const AString : UnicodeString; + const AIgnoreInvalidSequence : Boolean; + out AResultString : UnicodeString + ) : Integer; + function UnicodeToLower( + const AString : UnicodeString; + const AIgnoreInvalidSequence : Boolean; + out AResultString : UnicodeString + ) : Integer; function GetProps(const ACodePoint : Word) : PUC_Prop;overload;inline; function GetProps(const AHighS, ALowS : UnicodeChar): PUC_Prop;overload;inline; @@ -319,9 +331,26 @@ type ) : TUCASortKey;overload; function CompareSortKey(const A, B : TUCASortKey) : Integer;overload; function CompareSortKey(const A : TUCASortKey; const B : array of Word) : Integer;overload; + function IncrementalCompareString( + const AStrA : PUnicodeChar; + const ALengthA : SizeInt; + const AStrB : PUnicodeChar; + const ALengthB : SizeInt; + const ACollation : PUCA_DataBook + ) : Integer;overload; + function IncrementalCompareString( + const AStrA, + AStrB : UnicodeString; + const ACollation : PUCA_DataBook + ) : Integer;inline;overload; - function RegisterCollation(const ACollation : PUCA_DataBook) : Boolean; + function RegisterCollation(const ACollation : PUCA_DataBook) : Boolean;overload; + function RegisterCollation( + const ADirectory, + ALanguage : string + ) : Boolean;overload; function UnregisterCollation(const AName : ansistring): Boolean; + procedure UnregisterCollations(const AFreeDynamicCollations : Boolean); function FindCollation(const AName : ansistring): PUCA_DataBook;overload; function FindCollation(const AIndex : Integer): PUCA_DataBook;overload; function GetCollationCount() : Integer; @@ -330,6 +359,29 @@ type const ABaseName : ansistring; const AChangedFields : TCollationFields ); + function LoadCollation( + const AData : Pointer; + const ADataLength : Integer + ) : PUCA_DataBook;overload; + function LoadCollation(const AFileName : string) : PUCA_DataBook;overload; + function LoadCollation( + const ADirectory, + ALanguage : string + ) : PUCA_DataBook;overload; + procedure FreeCollation(AItem : PUCA_DataBook); + +type + TEndianKind = (Little, Big); +const + ENDIAN_SUFFIX : array[TEndianKind] of string[2] = ('le','be'); +{$IFDEF ENDIAN_LITTLE} + ENDIAN_NATIVE = TEndianKind.Little; + ENDIAN_NON_NATIVE = TEndianKind.Big; +{$ENDIF ENDIAN_LITTLE} +{$IFDEF ENDIAN_BIG} + ENDIAN_NATIVE = TEndianKind.Big; + ENDIAN_NON_NATIVE = TEndianKind.Little; +{$ENDIF ENDIAN_BIG} resourcestring SCollationNotFound = 'Collation not found : "%s".'; @@ -535,6 +587,21 @@ begin Result := a <= Cardinal(b); end; +type + TBitOrder = 0..7; +function IsBitON(const AData : Byte; const ABit : TBitOrder) : Boolean ;inline; +begin + Result := ( ( AData and ( 1 shl ABit ) ) <> 0 ); +end; + +procedure SetBit(var AData : Byte; const ABit : TBitOrder; const AValue : Boolean);inline; +begin + if AValue then + AData := AData or (1 shl (ABit mod 8)) + else + AData := AData and ( not ( 1 shl ( ABit mod 8 ) ) ); +end; + var CollationTable : array of PUCA_DataBook; function IndexOfCollation(const AName : string) : Integer; @@ -565,6 +632,23 @@ begin end; end; +function RegisterCollation(const ADirectory, ALanguage : string) : Boolean; +var + cl : PUCA_DataBook; +begin + cl := LoadCollation(ADirectory,ALanguage); + if (cl = nil) then + exit(False); + try + Result := RegisterCollation(cl); + except + FreeCollation(cl); + raise; + end; + if not Result then + FreeCollation(cl); +end; + function UnregisterCollation(const AName : ansistring): Boolean; var i, c : Integer; @@ -582,6 +666,23 @@ begin end; end; +procedure UnregisterCollations(const AFreeDynamicCollations : Boolean); +var + i : Integer; + cl : PUCA_DataBook; +begin + if AFreeDynamicCollations then begin + for i := Low(CollationTable) to High(CollationTable) do begin + if CollationTable[i].Dynamic then begin + cl := CollationTable[i]; + CollationTable[i] := nil; + FreeCollation(cl); + end; + end; + end; + SetLength(CollationTable,0); +end; + function FindCollation(const AName : ansistring): PUCA_DataBook;overload; var i : Integer; @@ -632,6 +733,190 @@ begin p^.VariableLowLimit := base^.VariableHighLimit; end; +type + TSerializedCollationHeader = packed record + Base : TCollationName; + Version : TCollationName; + CollationName : TCollationName; + VariableWeight : Byte; + Backwards : Byte; + BMP_Table1Length : DWord; + BMP_Table2Length : DWord; + OBMP_Table1Length : DWord; + OBMP_Table2Length : DWord; + PropCount : DWord; + VariableLowLimit : Word; + VariableHighLimit : Word; + ChangedFields : Byte; + end; + PSerializedCollationHeader = ^TSerializedCollationHeader; + +procedure FreeCollation(AItem : PUCA_DataBook); +var + h : PSerializedCollationHeader; +begin + if (AItem = nil) or not(AItem^.Dynamic) then + exit; + h := PSerializedCollationHeader(PtrUInt(AItem) + SizeOf(TUCA_DataBook)); + if (AItem^.BMP_Table1 <> nil) then + FreeMem(AItem^.BMP_Table1,h^.BMP_Table1Length); + if (AItem^.BMP_Table2 <> nil) then + FreeMem(AItem^.BMP_Table2,h^.BMP_Table2Length); + if (AItem^.OBMP_Table1 <> nil) then + FreeMem(AItem^.OBMP_Table1,h^.OBMP_Table1Length); + if (AItem^.OBMP_Table2 <> nil) then + FreeMem(AItem^.OBMP_Table2,h^.OBMP_Table2Length); + if (AItem^.Props <> nil) then + FreeMem(AItem^.Props,h^.PropCount); + FreeMem(AItem,(SizeOf(TUCA_DataBook)+SizeOf(TSerializedCollationHeader))); +end; + +function LoadCollation( + const AData : Pointer; + const ADataLength : Integer +) : PUCA_DataBook; +var + dataPointer : PByte; + readedLength : LongInt; + + function ReadBuffer(ADest : Pointer; ALength : LongInt) : Boolean; + begin + Result := (readedLength + ALength) <= ADataLength; + if not result then + exit; + Move(dataPointer^,ADest^,ALength); + Inc(dataPointer,ALength); + readedLength := readedLength + ALength; + end; + +var + r : PUCA_DataBook; + h : PSerializedCollationHeader; + cfs : TCollationFields; + i : Integer; + baseName : TCollationName; +begin + readedLength := 0; + dataPointer := AData; + r := AllocMem((SizeOf(TUCA_DataBook)+SizeOf(TSerializedCollationHeader))); + try + h := PSerializedCollationHeader(PtrUInt(r) + SizeOf(TUCA_DataBook)); + if not ReadBuffer(h,SizeOf(TSerializedCollationHeader)) then + exit; + r^.Version := h^.Version; + r^.CollationName := h^.CollationName; + r^.VariableWeight := TUCA_VariableKind(h^.VariableWeight); + r^.Backwards[0] := IsBitON(h^.Backwards,0); + r^.Backwards[1] := IsBitON(h^.Backwards,1); + r^.Backwards[2] := IsBitON(h^.Backwards,2); + r^.Backwards[3] := IsBitON(h^.Backwards,3); + if (h^.BMP_Table1Length > 0) then begin + r^.BMP_Table1 := GetMem(h^.BMP_Table1Length); + if not ReadBuffer(r^.BMP_Table1,h^.BMP_Table1Length) then + exit; + end; + if (h^.BMP_Table2Length > 0) then begin + r^.BMP_Table2 := GetMem(h^.BMP_Table2Length); + if not ReadBuffer(r^.BMP_Table2,h^.BMP_Table2Length) then + exit; + end; + if (h^.OBMP_Table1Length > 0) then begin + r^.OBMP_Table1 := GetMem(h^.OBMP_Table1Length); + if not ReadBuffer(r^.OBMP_Table1,h^.OBMP_Table1Length) then + exit; + end; + if (h^.OBMP_Table2Length > 0) then begin + r^.OBMP_Table2 := GetMem(h^.OBMP_Table2Length); + if not ReadBuffer(r^.OBMP_Table2,h^.OBMP_Table2Length) then + exit; + end; + r^.PropCount := h^.PropCount; + if (h^.PropCount > 0) then begin + r^.Props := GetMem(h^.PropCount); + if not ReadBuffer(r^.Props,h^.PropCount) then + exit; + end; + r^.VariableLowLimit := h^.VariableLowLimit; + r^.VariableHighLimit := h^.VariableHighLimit; + + cfs := []; + for i := Ord(Low(TCollationField)) to Ord(High(TCollationField)) do begin + if IsBitON(h^.ChangedFields,i) then + cfs := cfs + [TCollationField(i)]; + end; + if (h^.Base <> '') then + baseName := h^.Base + else if (h^.CollationName <> ROOT_COLLATION_NAME) then + baseName := ROOT_COLLATION_NAME + else + baseName := ''; + if (baseName <> '') then + PrepareCollation(r,baseName,cfs); + r^.Dynamic := True; + Result := r; + except + FreeCollation(r); + raise; + end; +end; + +{$PUSH} +function LoadCollation(const AFileName : string) : PUCA_DataBook; +const + BLOCK_SIZE = 16*1024; +var + f : File of Byte; + locSize, locReaded, c : LongInt; + locBuffer : PByte; + locBlockSize : LongInt; +begin + Result := nil; +{$I-} + if (AFileName = '') then + exit; + Assign(f,AFileName); + Reset(f); + try + if (IOResult <> 0) then + exit; + locSize := FileSize(f); + if (locSize < SizeOf(TSerializedCollationHeader)) then + exit; + locBuffer := GetMem(locSize); + try + locBlockSize := BLOCK_SIZE; + locReaded := 0; + while (locReaded < locSize) do begin + if (locBlockSize > (locSize-locReaded)) then + locBlockSize := locSize-locReaded; + BlockRead(f,locBuffer[locReaded],locBlockSize,c); + if (IOResult <> 0) or (c <= 0) then + exit; + locReaded := locReaded + c; + end; + Result := LoadCollation(locBuffer,locSize); + finally + FreeMem(locBuffer,locSize); + end; + finally + Close(f); + end; +end; +{$POP} + +function LoadCollation(const ADirectory, ALanguage : string) : PUCA_DataBook; +var + fileName : string; +begin + fileName := ADirectory; + if (fileName <> '') then begin + if (fileName[Length(fileName)] <> DirectorySeparator) then + fileName := fileName + DirectorySeparator; + end; + fileName := fileName + 'collation_' + ALanguage + '_' + ENDIAN_SUFFIX[ENDIAN_NATIVE] + '.bco'; + Result := LoadCollation(fileName); +end; + {$INCLUDE unicodedata.inc} {$IFDEF ENDIAN_LITTLE} {$INCLUDE unicodedata_le.inc} @@ -723,7 +1008,137 @@ begin Result := GetProps(h,l); end; +function UnicodeToUpper( + const AString : UnicodeString; + const AIgnoreInvalidSequence : Boolean; + out AResultString : UnicodeString +) : Integer; +var + i, c : SizeInt; + pp, pr : PUnicodeChar; + pu : PUC_Prop; + locIsSurrogate : Boolean; + r : UnicodeString; +begin + c := Length(AString); + SetLength(r,2*c); + if (c > 0) then begin + pp := @AString[1]; + pr := @r[1]; + i := 1; + while (i <= c) do begin + pu := GetProps(Word(pp^)); + locIsSurrogate := (pu^.Category = UGC_Surrogate); + if locIsSurrogate then begin + if (i = c) or not(UnicodeIsSurrogatePair(pp[0],pp[1])) then begin + if AIgnoreInvalidSequence then begin + pr^ := pp^; + Inc(pp); + Inc(pr); + Inc(i); + Continue; + end; + exit(ERROR_INVALID_CODEPOINT_SEQUENCE); + end; + pu := GetProps(pp^,AString[i+1]); + end; + if (pu^.SimpleUpperCase = 0) then begin + pr^ := pp^; + if locIsSurrogate then begin + Inc(pp); + Inc(pr); + Inc(i); + pr^ := pp^; + end; + end else begin + if (pu^.SimpleUpperCase <= $FFFF) then begin + pr^ := UnicodeChar(Word(pu^.SimpleUpperCase)); + end else begin + FromUCS4(UCS4Char(Cardinal(pu^.SimpleUpperCase)),pr^,PUnicodeChar(PtrUInt(pr)+SizeOf(UnicodeChar))^); + Inc(pr); + end; + if locIsSurrogate then begin + Inc(pp); + Inc(i); + end; + end; + Inc(pp); + Inc(pr); + Inc(i); + end; + Dec(pp); + i := ((PtrUInt(pr) - PtrUInt(@r[1])) div SizeOf(UnicodeChar)); + SetLength(r,i); + AResultString := r; + end; + Result := 0; +end; +function UnicodeToLower( + const AString : UnicodeString; + const AIgnoreInvalidSequence : Boolean; + out AResultString : UnicodeString +) : Integer; +var + i, c : SizeInt; + pp, pr : PUnicodeChar; + pu : PUC_Prop; + locIsSurrogate : Boolean; + r : UnicodeString; +begin + c := Length(AString); + SetLength(r,2*c); + if (c > 0) then begin + pp := @AString[1]; + pr := @r[1]; + i := 1; + while (i <= c) do begin + pu := GetProps(Word(pp^)); + locIsSurrogate := (pu^.Category = UGC_Surrogate); + if locIsSurrogate then begin + if (i = c) or not(UnicodeIsSurrogatePair(pp[0],pp[1])) then begin + if AIgnoreInvalidSequence then begin + pr^ := pp^; + Inc(pp); + Inc(pr); + Inc(i); + Continue; + end; + exit(ERROR_INVALID_CODEPOINT_SEQUENCE); + end; + pu := GetProps(pp^,AString[i+1]); + end; + if (pu^.SimpleLowerCase = 0) then begin + pr^ := pp^; + if locIsSurrogate then begin + Inc(pp); + Inc(pr); + Inc(i); + pr^ := pp^; + end; + end else begin + if (pu^.SimpleLowerCase <= $FFFF) then begin + pr^ := UnicodeChar(Word(pu^.SimpleLowerCase)); + end else begin + FromUCS4(UCS4Char(Cardinal(pu^.SimpleLowerCase)),pr^,PUnicodeChar(PtrUInt(pr)+SizeOf(UnicodeChar))^); + Inc(pr); + end; + if locIsSurrogate then begin + Inc(pp); + Inc(i); + end; + end; + Inc(pp); + Inc(pr); + Inc(i); + end; + Dec(pp); + i := ((PtrUInt(pr) - PtrUInt(@r[1])) div SizeOf(UnicodeChar)); + SetLength(r,i); + AResultString := r; + end; + Result := 0; +end; //---------------------------------------------------------------------- function DecomposeHangul(const AChar : Cardinal; ABuffer : PCardinal) : Integer; @@ -1026,21 +1441,6 @@ begin end; end; -type - TBitOrder = 0..7; -function IsBitON(const AData : Byte; const ABit : TBitOrder) : Boolean ;inline; -begin - Result := ( ( AData and ( 1 shl ABit ) ) <> 0 ); -end; - -procedure SetBit(var AData : Byte; const ABit : TBitOrder; const AValue : Boolean);inline; -begin - if AValue then - AData := AData or (1 shl (ABit mod 8)) - else - AData := AData and ( not ( 1 shl ( ABit mod 8 ) ) ); -end; - { TUCA_PropItemContextTreeNodeRec } function TUCA_PropItemContextTreeNodeRec.GetLeftNode: PUCA_PropItemContextTreeNodeRec; @@ -2134,6 +2534,875 @@ begin Result := r; end; +type + TComputeKeyContext = record + Collation : PUCA_DataBook; + r : TUCA_PropWeightsArray; + ral {used length of "r"}: Integer; + rl {capacity of "r"} : Integer; + i : Integer; + s : UnicodeString; + ps : PUnicodeChar; + cp : Cardinal; + cl : PUCA_DataBook; + pp : PUCA_PropItemRec; + ppLevel : Byte; + removedCharIndex : array of DWord; + removedCharIndexLength : DWord; + locHistoryTop : Integer; + locHistory : array[0..24] of record + i : Integer; + cl : PUCA_DataBook; + pp : PUCA_PropItemRec; + ppLevel : Byte; + cp : Cardinal; + removedCharIndexLength : DWord; + end; + suppressState : record + cl : PUCA_DataBook; + CharCount : Integer; + end; + LastKeyOwner : record + Length : Integer; + Chars : array[0..24] of UInt24; + end; + c : Integer; + lastUnblockedNonstarterCCC : Byte; + surrogateState : Boolean; + Finished : Boolean; + end; + PComputeKeyContext = ^TComputeKeyContext; + +procedure ClearPP(AContext : PComputeKeyContext; const AClearSuppressInfo : Boolean = True);inline; +begin + AContext^.cl := nil; + AContext^.pp := nil; + AContext^.ppLevel := 0; + if AClearSuppressInfo then begin + AContext^.suppressState.cl := nil; + AContext^.suppressState.CharCount := 0; + end; +end; + +procedure InitContext( + AContext : PComputeKeyContext; + const AStr : PUnicodeChar; + const ALength : SizeInt; + const ACollation : PUCA_DataBook +); +begin + AContext^.Collation := ACollation; + AContext^.c := ALength; + AContext^.s := NormalizeNFD(AStr,AContext^.c); + AContext^.c := Length(AContext^.s); + AContext^.rl := 3*AContext^.c; + SetLength(AContext^.r,AContext^.rl); + AContext^.ral := 0; + AContext^.ps := @AContext^.s[1]; + ClearPP(AContext); + AContext^.locHistoryTop := -1; + AContext^.removedCharIndexLength := 0; + FillByte(AContext^.suppressState,SizeOf(AContext^.suppressState),0); + AContext^.LastKeyOwner.Length := 0; + AContext^.i := 1; + AContext^.Finished := False; +end; + +function FormKey( + const AWeightArray : TUCA_PropWeightsArray; + const ACollation : PUCA_DataBook +) : TUCASortKey;inline; +begin + case ACollation.VariableWeight of + TUCA_VariableKind.ucaShifted : Result := FormKeyShifted(AWeightArray,ACollation); + TUCA_VariableKind.ucaBlanked : Result := FormKeyBlanked(AWeightArray,ACollation); + TUCA_VariableKind.ucaNonIgnorable : Result := FormKeyNonIgnorable(AWeightArray,ACollation); + TUCA_VariableKind.ucaShiftedTrimmed : Result := FormKeyShiftedTrimmed(AWeightArray,ACollation); + else + Result := FormKeyShifted(AWeightArray,ACollation); + end; +end; + +function ComputeRawSortKeyNextItem( + const AContext : PComputeKeyContext +) : Boolean;forward; +function IncrementalCompareString_NonIgnorable( + const AStrA : PUnicodeChar; + const ALengthA : SizeInt; + const AStrB : PUnicodeChar; + const ALengthB : SizeInt; + const ACollation : PUCA_DataBook +) : Integer; +var + ctxA, ctxB : TComputeKeyContext; + lastKeyIndexA, keyIndexA, lengthMaxA : Integer; + keyIndexB : Integer; + keyA, keyB : TUCASortKey; +begin + if ( (ALengthA = 0) and (ALengthB = 0) ) or + ( (PtrUInt(AStrA) = PtrUInt(AStrB)) and + (ALengthA = ALengthB) + ) + then + exit(0); + if (ALengthA = 0) then + exit(-1); + if (ALengthB = 0) then + exit(1); + + InitContext(@ctxA,AStrA,ALengthA,ACollation); + InitContext(@ctxB,AStrB,ALengthB,ACollation); + lastKeyIndexA := -1; + keyIndexA := -1; + lengthMaxA := 0; + keyIndexB := -1; + while True do begin + if not ComputeRawSortKeyNextItem(@ctxA) then + Break; + if (ctxA.ral = lengthMaxA) then + Continue; + lengthMaxA := ctxA.ral; + keyIndexA := lastKeyIndexA + 1; + while (keyIndexA < lengthMaxA) and (ctxA.r[keyIndexA].Weights[0] = 0) do begin + Inc(keyIndexA); + end; + if (keyIndexA = lengthMaxA) then begin + lastKeyIndexA := keyIndexA-1; + Continue; + end; + + while (keyIndexA < lengthMaxA) do begin + if (ctxA.r[keyIndexA].Weights[0] = 0) then begin + Inc(keyIndexA); + Continue; + end; + Inc(keyIndexB); + while (ctxB.ral <= keyIndexB) or (ctxB.r[keyIndexB].Weights[0] = 0) do begin + if (ctxB.ral <= keyIndexB) then begin + if not ComputeRawSortKeyNextItem(@ctxB) then + Break; + Continue; + end; + Inc(keyIndexB); + end; + if (ctxB.ral <= keyIndexB) then + exit(1); + if (ctxA.r[keyIndexA].Weights[0] > ctxB.r[keyIndexB].Weights[0]) then + exit(1); + if (ctxA.r[keyIndexA].Weights[0] < ctxB.r[keyIndexB].Weights[0]) then + exit(-1); + Inc(keyIndexA); + end; + lastKeyIndexA := keyIndexA - 1; + end; + //Key(A) is completed ! + Inc(keyIndexB); + while (ctxB.ral <= keyIndexB) or (ctxB.r[keyIndexB].Weights[0] = 0) do begin + if (ctxB.ral <= keyIndexB) then begin + if not ComputeRawSortKeyNextItem(@ctxB) then + Break; + Continue; + end; + Inc(keyIndexB); + end; + if (ctxB.ral > keyIndexB) then begin + //B has at least one more primary weight that A + exit(-1); + end; + while ComputeRawSortKeyNextItem(@ctxB) do begin + // + end; + //Key(B) is completed ! + keyA := FormKey(ctxA.r,ctxA.Collation); + keyB := FormKey(ctxB.r,ctxB.Collation); + Result := CompareSortKey(keyA,keyB); +end; + +function IncrementalCompareString_Shift( + const AStrA : PUnicodeChar; + const ALengthA : SizeInt; + const AStrB : PUnicodeChar; + const ALengthB : SizeInt; + const ACollation : PUCA_DataBook +) : Integer; +var + ctxA, ctxB : TComputeKeyContext; + lastKeyIndexA, keyIndexA, lengthMaxA : Integer; + keyIndexB : Integer; + keyA, keyB : TUCASortKey; +begin + if ( (ALengthA = 0) and (ALengthB = 0) ) or + ( (PtrUInt(AStrA) = PtrUInt(AStrB)) and + (ALengthA = ALengthB) + ) + then + exit(0); + if (ALengthA = 0) then + exit(-1); + if (ALengthB = 0) then + exit(1); + + InitContext(@ctxA,AStrA,ALengthA,ACollation); + InitContext(@ctxB,AStrB,ALengthB,ACollation); + lastKeyIndexA := -1; + keyIndexA := -1; + lengthMaxA := 0; + keyIndexB := -1; + while True do begin + if not ComputeRawSortKeyNextItem(@ctxA) then + Break; + if (ctxA.ral = lengthMaxA) then + Continue; + lengthMaxA := ctxA.ral; + keyIndexA := lastKeyIndexA + 1; + while (keyIndexA < lengthMaxA) and + ( (ctxA.r[keyIndexA].Weights[0] = 0) or + ctxA.Collation^.IsVariable(@ctxA.r[keyIndexA].Weights) + ) + do begin + Inc(keyIndexA); + end; + if (keyIndexA = lengthMaxA) then begin + lastKeyIndexA := keyIndexA-1; + Continue; + end; + + while (keyIndexA < lengthMaxA) do begin + if (ctxA.r[keyIndexA].Weights[0] = 0) or + ctxA.Collation^.IsVariable(@ctxA.r[keyIndexA].Weights) + then begin + Inc(keyIndexA); + Continue; + end; + Inc(keyIndexB); + while (ctxB.ral <= keyIndexB) or + (ctxB.r[keyIndexB].Weights[0] = 0) or + ctxB.Collation^.IsVariable(@ctxB.r[keyIndexB].Weights) + do begin + if (ctxB.ral <= keyIndexB) then begin + if not ComputeRawSortKeyNextItem(@ctxB) then + Break; + Continue; + end; + Inc(keyIndexB); + end; + if (ctxB.ral <= keyIndexB) then + exit(1); + if (ctxA.r[keyIndexA].Weights[0] > ctxB.r[keyIndexB].Weights[0]) then + exit(1); + if (ctxA.r[keyIndexA].Weights[0] < ctxB.r[keyIndexB].Weights[0]) then + exit(-1); + Inc(keyIndexA); + end; + lastKeyIndexA := keyIndexA - 1; + end; + //Key(A) is completed ! + Inc(keyIndexB); + while (ctxB.ral <= keyIndexB) or + (ctxB.r[keyIndexB].Weights[0] = 0) or + ctxB.Collation^.IsVariable(@ctxB.r[keyIndexB].Weights) + do begin + if (ctxB.ral <= keyIndexB) then begin + if not ComputeRawSortKeyNextItem(@ctxB) then + Break; + Continue; + end; + Inc(keyIndexB); + end; + if (ctxB.ral > keyIndexB) then begin + //B has at least one more primary weight that A + exit(-1); + end; + while ComputeRawSortKeyNextItem(@ctxB) do begin + // + end; + //Key(B) is completed ! + keyA := FormKey(ctxA.r,ctxA.Collation); + keyB := FormKey(ctxB.r,ctxB.Collation); + Result := CompareSortKey(keyA,keyB); +end; + +function IncrementalCompareString( + const AStrA : PUnicodeChar; + const ALengthA : SizeInt; + const AStrB : PUnicodeChar; + const ALengthB : SizeInt; + const ACollation : PUCA_DataBook +) : Integer; +begin + case ACollation^.VariableWeight of + TUCA_VariableKind.ucaNonIgnorable : + begin + Result := IncrementalCompareString_NonIgnorable( + AStrA,ALengthA,AStrB,ALengthB,ACollation + ); + end; + TUCA_VariableKind.ucaBlanked, + TUCA_VariableKind.ucaShiftedTrimmed, + TUCA_VariableKind.ucaIgnoreSP, + TUCA_VariableKind.ucaShifted: + begin + Result := IncrementalCompareString_Shift( + AStrA,ALengthA,AStrB,ALengthB,ACollation + ); + end; + else + begin + Result := IncrementalCompareString_Shift( + AStrA,ALengthA,AStrB,ALengthB,ACollation + ); + end; + end; +end; + +function IncrementalCompareString( + const AStrA, + AStrB : UnicodeString; + const ACollation : PUCA_DataBook +) : Integer; +begin + Result := IncrementalCompareString( + Pointer(AStrA),Length(AStrA),Pointer(AStrB),Length(AStrB), + ACollation + ); +end; + +function ComputeRawSortKeyNextItem( + const AContext : PComputeKeyContext +) : Boolean; +var + ctx : PComputeKeyContext; + + procedure GrowKey(const AMinGrow : Integer = 0);inline; + begin + if (ctx^.rl < AMinGrow) then + ctx^.rl := ctx^.rl + AMinGrow + else + ctx^.rl := 2 * ctx^.rl; + SetLength(ctx^.r,ctx^.rl); + end; + + procedure SaveKeyOwner(); + var + k : Integer; + kppLevel : Byte; + begin + k := 0; + kppLevel := High(Byte); + while (k <= ctx^.locHistoryTop) do begin + if (kppLevel <> ctx^.locHistory[k].ppLevel) then begin + ctx^.LastKeyOwner.Chars[k] := ctx^.locHistory[k].cp; + kppLevel := ctx^.locHistory[k].ppLevel; + end; + k := k + 1; + end; + if (k = 0) or (kppLevel <> ctx^.ppLevel) then begin + ctx^.LastKeyOwner.Chars[k] := ctx^.cp; + k := k + 1; + end; + ctx^.LastKeyOwner.Length := k; + end; + + procedure AddWeights(AItem : PUCA_PropItemRec);inline; + begin + SaveKeyOwner(); + if ((ctx^.ral + AItem^.WeightLength) > ctx^.rl) then + GrowKey(AItem^.WeightLength); + AItem^.GetWeightArray(@ctx^.r[ctx^.ral]); + ctx^.ral := ctx^.ral + AItem^.WeightLength; + end; + + procedure AddContextWeights(AItem : PUCA_PropItemContextRec);inline; + begin + if ((ctx^.ral + AItem^.WeightCount) > ctx^.rl) then + GrowKey(AItem^.WeightCount); + Move(AItem^.GetWeights()^,ctx^.r[ctx^.ral],(AItem^.WeightCount*SizeOf(ctx^.r[0]))); + ctx^.ral := ctx^.ral + AItem^.WeightCount; + end; + + procedure AddComputedWeights(ACodePoint : Cardinal);inline; + begin + SaveKeyOwner(); + if ((ctx^.ral + 2) > ctx^.rl) then + GrowKey(); + DeriveWeight(ACodePoint,@ctx^.r[ctx^.ral]); + ctx^.ral := ctx^.ral + 2; + end; + + procedure RecordDeletion();inline; + begin + if ctx^.pp^.IsValid() and ctx^.pp^.IsDeleted() (*pp^.GetWeightLength() = 0*) then begin + if (ctx^.suppressState.cl = nil) or + (ctx^.suppressState.CharCount > ctx^.ppLevel) + then begin + ctx^.suppressState.cl := ctx^.cl; + ctx^.suppressState.CharCount := ctx^.ppLevel; + end; + end; + end; + + procedure RecordStep();inline; + begin + Inc(ctx^.locHistoryTop); + ctx^.locHistory[ctx^.locHistoryTop].i := ctx^.i; + ctx^.locHistory[ctx^.locHistoryTop].cl := ctx^.cl; + ctx^.locHistory[ctx^.locHistoryTop].pp := ctx^.pp; + ctx^.locHistory[ctx^.locHistoryTop].ppLevel := ctx^.ppLevel; + ctx^.locHistory[ctx^.locHistoryTop].cp := ctx^.cp; + ctx^.locHistory[ctx^.locHistoryTop].removedCharIndexLength := ctx^.removedCharIndexLength; + RecordDeletion(); + end; + + procedure ClearHistory();inline; + begin + ctx^.locHistoryTop := -1; + end; + + function HasHistory() : Boolean;inline; + begin + Result := (ctx^.locHistoryTop >= 0); + end; + + function GetHistoryLength() : Integer;inline; + begin + Result := (ctx^.locHistoryTop + 1); + end; + + procedure GoBack();inline; + begin + Assert(ctx^.locHistoryTop >= 0); + ctx^.i := ctx^.locHistory[ctx^.locHistoryTop].i; + ctx^.cp := ctx^.locHistory[ctx^.locHistoryTop].cp; + ctx^.cl := ctx^.locHistory[ctx^.locHistoryTop].cl; + ctx^.pp := ctx^.locHistory[ctx^.locHistoryTop].pp; + ctx^.ppLevel := ctx^.locHistory[ctx^.locHistoryTop].ppLevel; + ctx^.removedCharIndexLength := ctx^.locHistory[ctx^.locHistoryTop].removedCharIndexLength; + ctx^.ps := @ctx^.s[ctx^.i]; + Dec(ctx^.locHistoryTop); + end; + + function IsUnblockedNonstarter(const AStartFrom : Integer) : Boolean; + var + k : DWord; + pk : PUnicodeChar; + puk : PUC_Prop; + begin + k := AStartFrom; + if (k > ctx^.c) then + exit(False); + if (ctx^.removedCharIndexLength>0) and + (IndexDWord(ctx^.removedCharIndex[0],ctx^.removedCharIndexLength,k) >= 0) + then begin + exit(False); + end; + {if (k = (i+1)) or + ( (k = (i+2)) and UnicodeIsHighSurrogate(s[i]) ) + then + lastUnblockedNonstarterCCC := 0;} + pk := @ctx^.s[k]; + if UnicodeIsHighSurrogate(pk^) then begin + if (k = ctx^.c) then + exit(False); + if UnicodeIsLowSurrogate(pk[1]) then + puk := GetProps(pk[0],pk[1]) + else + puk := GetProps(Word(pk^)); + end else begin + puk := GetProps(Word(pk^)); + end; + if (puk^.CCC = 0) or (ctx^.lastUnblockedNonstarterCCC >= puk^.CCC) then + exit(False); + ctx^.lastUnblockedNonstarterCCC := puk^.CCC; + Result := True; + end; + + procedure RemoveChar(APos : Integer);inline; + begin + if (ctx^.removedCharIndexLength >= Length(ctx^.removedCharIndex)) then + SetLength(ctx^.removedCharIndex,(2*ctx^.removedCharIndexLength + 2)); + ctx^.removedCharIndex[ctx^.removedCharIndexLength] := APos; + Inc(ctx^.removedCharIndexLength); + if UnicodeIsHighSurrogate(ctx^.s[APos]) and (APos < ctx^.c) and UnicodeIsLowSurrogate(ctx^.s[APos+1]) then begin + if (ctx^.removedCharIndexLength >= Length(ctx^.removedCharIndex)) then + SetLength(ctx^.removedCharIndex,(2*ctx^.removedCharIndexLength + 2)); + ctx^.removedCharIndex[ctx^.removedCharIndexLength] := APos+1; + Inc(ctx^.removedCharIndexLength); + end; + end; + + procedure Inc_I();inline; + begin + if (ctx^.removedCharIndexLength = 0) then begin + Inc(ctx^.i); + Inc(ctx^.ps); + exit; + end; + while True do begin + Inc(ctx^.i); + Inc(ctx^.ps); + if (IndexDWord(ctx^.removedCharIndex[0],ctx^.removedCharIndexLength,ctx^.i) = -1) then + Break; + end; + end; + + function MoveToNextChar() : Boolean;inline; + begin + Result := True; + if UnicodeIsHighSurrogate(ctx^.ps[0]) then begin + if (ctx^.i = ctx^.c) then + exit(False); + if UnicodeIsLowSurrogate(ctx^.ps[1]) then begin + ctx^.surrogateState := True; + ctx^.cp := ToUCS4(ctx^.ps[0],ctx^.ps[1]); + end else begin + ctx^.surrogateState := False; + ctx^.cp := Word(ctx^.ps[0]); + end; + end else begin + ctx^.surrogateState := False; + ctx^.cp := Word(ctx^.ps[0]); + end; + end; + + function FindPropUCA() : Boolean; + var + candidateCL : PUCA_DataBook; + begin + ctx^.pp := nil; + if (ctx^.cl = nil) then + candidateCL := ctx^.Collation + else + candidateCL := ctx^.cl; + if ctx^.surrogateState then begin + while (candidateCL <> nil) do begin + ctx^.pp := GetPropUCA(ctx^.ps[0],ctx^.ps[1],candidateCL); + if (ctx^.pp <> nil) then + break; + candidateCL := candidateCL^.Base; + end; + end else begin + while (candidateCL <> nil) do begin + ctx^.pp := GetPropUCA(ctx^.ps[0],candidateCL); + if (ctx^.pp <> nil) then + break; + candidateCL := candidateCL^.Base; + end; + end; + ctx^.cl := candidateCL; + Result := (ctx^.pp <> nil); + end; + + procedure AddWeightsAndClear();inline; + var + ctxNode : PUCA_PropItemContextTreeNodeRec; + begin + if (ctx^.pp^.WeightLength > 0) then begin + AddWeights(ctx^.pp); + end else + if (ctx^.LastKeyOwner.Length > 0) and ctx^.pp^.Contextual and + ctx^.pp^.GetContext()^.Find(@ctx^.LastKeyOwner.Chars[0],ctx^.LastKeyOwner.Length,ctxNode) and + (ctxNode^.Data.WeightCount > 0) + then begin + AddContextWeights(@ctxNode^.Data); + end; + //AddWeights(pp); + ClearHistory(); + ClearPP(ctx); + end; + + function StartMatch() : Boolean; + + procedure HandleLastChar(); + var + ctxNode : PUCA_PropItemContextTreeNodeRec; + begin + while True do begin + if ctx^.pp^.IsValid() then begin + if (ctx^.pp^.WeightLength > 0) then + AddWeights(ctx^.pp) + else + if (ctx^.LastKeyOwner.Length > 0) and ctx^.pp^.Contextual and + ctx^.pp^.GetContext()^.Find(@ctx^.LastKeyOwner.Chars[0],ctx^.LastKeyOwner.Length,ctxNode) and + (ctxNode^.Data.WeightCount > 0) + then + AddContextWeights(@ctxNode^.Data) + else + AddComputedWeights(ctx^.cp){handle deletion of code point}; + break; + end; + if (ctx^.cl^.Base = nil) then begin + AddComputedWeights(ctx^.cp); + break; + end; + ctx^.cl := ctx^.cl^.Base; + if not FindPropUCA() then begin + AddComputedWeights(ctx^.cp); + break; + end; + end; + end; + var + tmpCtxNode : PUCA_PropItemContextTreeNodeRec; + begin + Result := False; + ctx^.ppLevel := 0; + if not FindPropUCA() then begin + AddComputedWeights(ctx^.cp); + ClearHistory(); + ClearPP(ctx); + Result := True; + end else begin + if (ctx^.i = ctx^.c) then begin + HandleLastChar(); + Result := True; + end else begin + if ctx^.pp^.IsValid()then begin + if (ctx^.pp^.ChildCount = 0) then begin + if (ctx^.pp^.WeightLength > 0) then + AddWeights(ctx^.pp) + else + if (ctx^.LastKeyOwner.Length > 0) and ctx^.pp^.Contextual and + ctx^.pp^.GetContext()^.Find(@ctx^.LastKeyOwner.Chars[0],ctx^.LastKeyOwner.Length,tmpCtxNode) and + (tmpCtxNode^.Data.WeightCount > 0) + then + AddContextWeights(@tmpCtxNode^.Data) + else + AddComputedWeights(ctx^.cp){handle deletion of code point}; + ClearPP(ctx); + ClearHistory(); + Result := True; + end else begin + RecordStep(); + end + end else begin + if (ctx^.pp^.ChildCount = 0) then begin + AddComputedWeights(ctx^.cp); + ClearPP(ctx); + ClearHistory(); + Result := True; + end else begin + RecordStep(); + end; + end; + end; + end; + end; + + function TryPermutation() : Boolean; + var + kk : Integer; + b : Boolean; + puk : PUC_Prop; + ppk : PUCA_PropItemRec; + begin + Result := False; + puk := GetProps(ctx^.cp); + if (puk^.CCC = 0) then + exit; + ctx^.lastUnblockedNonstarterCCC := puk^.CCC; + if ctx^.surrogateState then + kk := ctx^.i + 2 + else + kk := ctx^.i + 1; + while IsUnblockedNonstarter(kk) do begin + b := UnicodeIsHighSurrogate(ctx^.s[kk]) and (kk<ctx^.c) and UnicodeIsLowSurrogate(ctx^.s[kk+1]); + if b then + ppk := FindChild(ToUCS4(ctx^.s[kk],ctx^.s[kk+1]),ctx^.pp) + else + ppk := FindChild(Word(ctx^.s[kk]),ctx^.pp); + if (ppk <> nil) then begin + ctx^.pp := ppk; + RemoveChar(kk); + Inc(ctx^.ppLevel); + RecordStep(); + Result := True; + if (ctx^.pp^.ChildCount = 0 ) then + Break; + end; + if b then + Inc(kk); + Inc(kk); + end; + end; + + procedure AdvanceCharPos();inline; + begin + if UnicodeIsHighSurrogate(ctx^.ps[0]) and (ctx^.i<ctx^.c) and UnicodeIsLowSurrogate(ctx^.ps[1]) then begin + Inc(ctx^.i); + Inc(ctx^.ps); + end; + Inc_I(); + end; + +var + ok : Boolean; + pp1 : PUCA_PropItemRec; + cltemp : PUCA_DataBook; + ctxNode : PUCA_PropItemContextTreeNodeRec; +begin + if AContext^.Finished then + exit(False); + ctx := AContext; + while (ctx^.i <= ctx^.c) and MoveToNextChar() do begin + ok := False; + if (ctx^.pp = nil) then begin // Start Matching + ok := StartMatch(); + end else begin + pp1 := FindChild(ctx^.cp,ctx^.pp); + if (pp1 <> nil) then begin + Inc(ctx^.ppLevel); + ctx^.pp := pp1; + if (ctx^.pp^.ChildCount = 0) or (ctx^.i = ctx^.c) then begin + ok := False; + if ctx^.pp^.IsValid() and (ctx^.suppressState.CharCount = 0) then begin + if (ctx^.pp^.WeightLength > 0) then begin + AddWeightsAndClear(); + ok := True; + end else + if (ctx^.LastKeyOwner.Length > 0) and ctx^.pp^.Contextual and + ctx^.pp^.GetContext()^.Find(@ctx^.LastKeyOwner.Chars[0],ctx^.LastKeyOwner.Length,ctxNode) and + (ctxNode^.Data.WeightCount > 0) + then begin + AddContextWeights(@ctxNode^.Data); + ClearHistory(); + ClearPP(ctx); + ok := True; + end + end; + if not ok then begin + RecordDeletion(); + while HasHistory() do begin + GoBack(); + if ctx^.pp^.IsValid() and + ( ( (ctx^.cl = ctx^.suppressState.cl) and (ctx^.ppLevel <> ctx^.suppressState.CharCount) ) or + ( (ctx^.cl <> ctx^.suppressState.cl) and (ctx^.ppLevel < ctx^.suppressState.CharCount) ) + ) + then begin + AddWeightsAndClear(); + ok := True; + Break; + end; + end; + if not ok then begin + cltemp := ctx^.cl^.Base; + if (cltemp <> nil) then begin + ClearPP(ctx,False); + ctx^.cl := cltemp; + Continue; + end; + end; + + if not ok then begin + AddComputedWeights(ctx^.cp); + ClearHistory(); + ClearPP(ctx); + ok := True; + end; + end; + end else begin + RecordStep(); + end; + end else begin + // permutations ! + ok := False; + if TryPermutation() and ctx^.pp^.IsValid() then begin + if (ctx^.suppressState.CharCount = 0) then begin + AddWeightsAndClear(); + ok := True; + exit(True);// Continue; + end; + while True do begin + if ctx^.pp^.IsValid() and + (ctx^.pp^.WeightLength > 0) and + ( ( (ctx^.cl = ctx^.suppressState.cl) and (ctx^.ppLevel <> ctx^.suppressState.CharCount) ) or + ( (ctx^.cl <> ctx^.suppressState.cl) and (ctx^.ppLevel < ctx^.suppressState.CharCount) ) + ) + then begin + AddWeightsAndClear(); + ok := True; + break; + end; + if not HasHistory() then + break; + GoBack(); + if (ctx^.pp = nil) then + break; + end; + end; + if not ok then begin + if ctx^.pp^.IsValid() and (ctx^.suppressState.CharCount = 0) then begin + if (ctx^.pp^.WeightLength > 0) then begin + AddWeightsAndClear(); + ok := True; + end else + if (ctx^.LastKeyOwner.Length > 0) and ctx^.pp^.Contextual and + ctx^.pp^.GetContext()^.Find(@ctx^.LastKeyOwner.Chars[0],ctx^.LastKeyOwner.Length,ctxNode) and + (ctxNode^.Data.WeightCount > 0) + then begin + AddContextWeights(@ctxNode^.Data); + ClearHistory(); + ClearPP(ctx); + ok := True; + end + end; + if ok then + exit(True);// Continue; + end; + if not ok then begin + if (ctx^.cl^.Base <> nil) then begin + cltemp := ctx^.cl^.Base; + while HasHistory() do + GoBack(); + ctx^.pp := nil; + ctx^.ppLevel := 0; + ctx^.cl := cltemp; + Continue; + end; + + //walk back + ok := False; + while HasHistory() do begin + GoBack(); + if ctx^.pp^.IsValid() and + (ctx^.pp^.WeightLength > 0) and + ( (ctx^.suppressState.CharCount = 0) or + ( ( (ctx^.cl = ctx^.suppressState.cl) and (ctx^.ppLevel <> ctx^.suppressState.CharCount) ) or + ( (ctx^.cl <> ctx^.suppressState.cl) and (ctx^.ppLevel < ctx^.suppressState.CharCount) ) + ) + ) + then begin + AddWeightsAndClear(); + ok := True; + Break; + end; + end; + if ok then begin + AdvanceCharPos(); + exit(True);// Continue; + end; + if (ctx^.pp <> nil) then begin + AddComputedWeights(ctx^.cp); + ClearHistory(); + ClearPP(ctx); + ok := True; + end; + end; + end; + end; + if ctx^.surrogateState then begin + Inc(ctx^.ps); + Inc(ctx^.i); + end; + // + Inc_I(); + if ok then + exit(True); + end; + SetLength(ctx^.r,ctx^.ral); + ctx^.Finished := True; + Result := True; +end; + function ComputeSortKey( const AStr : PUnicodeChar; const ALength : SizeInt; @@ -2143,14 +3412,7 @@ var r : TUCA_PropWeightsArray; begin r := ComputeRawSortKey(AStr,ALength,ACollation); - case ACollation^.VariableWeight of - TUCA_VariableKind.ucaShifted : Result := FormKeyShifted(r,ACollation); - TUCA_VariableKind.ucaBlanked : Result := FormKeyBlanked(r,ACollation); - TUCA_VariableKind.ucaNonIgnorable : Result := FormKeyNonIgnorable(r,ACollation); - TUCA_VariableKind.ucaShiftedTrimmed : Result := FormKeyShiftedTrimmed(r,ACollation); - else - Result := FormKeyShifted(r,ACollation); - end; + Result := FormKey(r,ACollation); end; end. diff --git a/rtl/os2/pmwsock.pas b/rtl/os2/pmwsock.pas index 5a12f6f549..9891f2443f 100644 --- a/rtl/os2/pmwsock.pas +++ b/rtl/os2/pmwsock.pas @@ -52,17 +52,17 @@ type Function __WSAFDIsSet(a: TSocket;var b: fdset): Longint; cdecl; - external 'PMWSock' name '__WSAFDIsSet'; + external 'PMWSock' index 151; Function __WSAFDIsSet_(s:TSocket; var FDSet:TFDSet): Longint; cdecl; - external 'PMWSock' name '__WSAFDIsSet'; + external 'PMWSock' index 151; Function __WSAFDIsSet2_(s:TSocket; var FDSet:TFDSet): boolean; cdecl; - external 'PMWSock' name '__WSAFDIsSet'; + external 'PMWSock' index 151; Function FD_ISSET2(a: TSocket;var b: fdset): Longint; cdecl; - external 'PMWSock' name '__WSAFDIsSet'; + external 'PMWSock' index 151; Function FD_ISSET(a: TSocket;var b: fdset): boolean; cdecl; - external 'PMWSock' name '__WSAFDIsSet'; + external 'PMWSock' index 151; Procedure FD_CLR(ASocket: TSocket; var aset: fdset); Procedure FD_SET(Socket:TSocket; var FDSet:TFDSet); @@ -708,195 +708,195 @@ Const // Socket function prototypes Function accept(s: TSocket; Var addr; Var addrlen: LongInt): TSocket; cdecl; - external 'PMWSock' name 'accept'; + external 'PMWSock' index 1; Function accept(s:TSocket; addr: PSockAddr; addrlen : PLongint) : TSocket; cdecl; - external 'PMWSock' name 'accept'; + external 'PMWSock' index 1; Function accept(s:TSocket; addr: PSockAddr; var addrlen : Longint) : TSocket; cdecl; - external 'PMWSock' name 'accept'; + external 'PMWSock' index 1; Function bind(s: TSocket; Const addr; namelen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'bind'; + external 'PMWSock' index 2; Function bind(s:TSocket; addr: PSockaddr;namelen: Longint): Longint; cdecl; - external 'PMWSock' name 'bind'; + external 'PMWSock' index 2; Function closesocket(s: TSocket): LongInt; cdecl; - external 'PMWSock' name 'closesocket'; + external 'PMWSock' index 3; Function connect(s: TSocket; Const name: sockaddr; namelen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'connect'; + external 'PMWSock' index 4; Function connect(s:TSocket; addr:PSockAddr; namelen: Longint): Longint; cdecl; - external 'PMWSock' name 'connect'; + external 'PMWSock' index 4; Function ioctlsocket(s: TSocket; cmd: LongInt; Var argp: Cardinal): LongInt; cdecl; - external 'PMWSock' name 'ioctlsocket'; + external 'PMWSock' index 12; Function ioctlsocket(s: TSocket; cmd: longint; var arg:longint): Longint; cdecl; - external 'PMWSock' name 'ioctlsocket'; + external 'PMWSock' index 12; Function ioctlsocket(s: TSocket; cmd: longint; argp: PCardinal): Longint; cdecl; - external 'PMWSock' name 'ioctlsocket'; + external 'PMWSock' index 12; Function getpeername(s: TSocket; Var name: sockaddr; Var nameLen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'getpeername'; + external 'PMWSock' index 5; Function getsockname(s: TSocket;Var name: sockaddr; Var namelen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'getsockname'; + external 'PMWSock' index 6; Function getsockopt(s: TSocket; level, optname: LongInt;Var optval; Var optlen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'getsockopt'; + external 'PMWSock' index 7; Function getsockopt(s: TSocket; level: Longint; optname: Longint; optval:pchar;var optlen: Longint): Longint; cdecl; - external 'PMWSock' name 'getsockopt'; + external 'PMWSock' index 7; Function htonl(hostlong: Cardinal): Cardinal; cdecl; - external 'PMWSock' name 'htonl'; + external 'PMWSock' index 8; Function htons(hostshort: Word): Word; cdecl; - external 'PMWSock' name 'htons'; + external 'PMWSock' index 9; Function inet_addr(cp: pchar): Cardinal; cdecl; - external 'PMWSock' name 'inet_addr'; + external 'PMWSock' index 10; Function inet_ntoa(Var _in: in_addr): PChar; cdecl; - external 'PMWSock' name 'inet_ntoa'; + external 'PMWSock' index 11; Function inet_ntoa(i: PInAddr): pchar; cdecl; - external 'PMWSock' name 'inet_ntoa'; + external 'PMWSock' index 11; Function listen(s: TSocket; backlog: LongInt): LongInt; cdecl; - external 'PMWSock' name 'listen'; + external 'PMWSock' index 13; Function ntohl(netlong: Cardinal): Cardinal; cdecl; - external 'PMWSock' name 'ntohl'; + external 'PMWSock' index 14; Function ntohs(netshort: Word): Word; cdecl; - external 'PMWSock' name 'ntohs'; + external 'PMWSock' index 15; Function recv(s: TSocket;Var Buf; len, flags: LongInt): LongInt; cdecl; - external 'PMWSock' name 'recv'; + external 'PMWSock' index 16; Function recv(s: TSocket; buf:pchar; len: Longint; flags: Longint): Longint; cdecl; - external 'PMWSock' name 'recv'; + external 'PMWSock' index 16; Function recvfrom(s: TSocket; Var Buf: PChar; len, flags:LongInt; Var from: sockaddr; Var fromLen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'recvfrom'; + external 'PMWSock' index 17; Function recvfrom(s: TSocket; buf:pchar; len: Longint; flags: Longint; from: PSockAddr; fromlen: Longint): Longint; cdecl; - external 'PMWSock' name 'recvfrom'; + external 'PMWSock' index 17; Function recvfrom(s: TSocket; var buf; len: Longint; flags: Longint; Const from: TSockAddr; var fromlen: Longint): Longint; cdecl; - external 'PMWSock' name 'recvfrom'; + external 'PMWSock' index 17; Function select(nfds: LongInt; Var readfds, writefds, exceptfds: fdset; Const timeout: timeval): LongInt; cdecl; - external 'PMWSock' name 'select'; + external 'PMWSock' index 18; Function select(nfds: Longint; readfds, writefds, exceptfds : PFDSet; timeout: PTimeVal): Longint; cdecl; - external 'PMWSock' name 'select'; + external 'PMWSock' index 18; Function send(s: TSocket; Const Buf: PChar; len, flags: LongInt): LongInt; cdecl; - external 'PMWSock' name 'send'; + external 'PMWSock' index 19; Function sendto(s: TSocket; Const Buf: PChar; len, flags: LongInt; Const _to: sockaddr; tolen: LongInt): LongInt; cdecl; - external 'PMWSock' name 'sendto'; + external 'PMWSock' index 20; Function sendto(s: TSocket; buf: pchar; len: Longint; flags: Longint; toaddr: PSockAddr; tolen: Longint): Longint; cdecl; - external 'PMWSock' name 'sendto'; + external 'PMWSock' index 20; Function setsockopt(s: TSocket; level: Longint; optname: Longint; optval: pchar; optlen: Longint): Longint; cdecl; - external 'PMWSock' name 'setsockopt'; + external 'PMWSock' index 21; Function shutdown(s: TSocket; how: LongInt): LongInt; cdecl; - external 'PMWSock' name 'shutdown'; + external 'PMWSock' index 22; Function socket(af, typ, protocol: LongInt): TSocket; cdecl; - external 'PMWSock' name 'socket'; + external 'PMWSock' index 23; // Database function prototypes Function gethostbyaddr(addr: pchar; len: Longint; t: Longint): PHostEnt; cdecl; - external 'PMWSock' name 'gethostbyaddr'; + external 'PMWSock' index 51; Function gethostbyname(name: pchar): PHostEnt; cdecl; - external 'PMWSock' name 'gethostbyname'; + external 'PMWSock' index 52; Function gethostname(name: pchar; namelen: Longint): Longint; cdecl; - external 'PMWSock' name 'gethostname'; + external 'PMWSock' index 57; Function getservbyport(port: Longint; proto: pchar): PServEnt; cdecl; - external 'PMWSock' name 'getservbyport'; + external 'PMWSock' index 56; Function getservbyname(name: pchar; proto: pchar): PServEnt; cdecl; - external 'PMWSock' name 'getservbyname'; + external 'PMWSock' index 55; Function getprotobynumber(proto: LongInt): pprotoent; cdecl; - external 'PMWSock' name 'getprotobynumber'; + external 'PMWSock' index 54; Function getprotobyname(name: pchar): PProtoEnt; cdecl; - external 'PMWSock' name 'getprotobyname'; + external 'PMWSock' index 53; // Microsoft Windows Extension function prototypes Function WSAStartup(wVersionRequired: Word;Var aWSAData: WSAData): LongInt; cdecl; - external 'PMWSock' name 'WSAStartup'; + external 'PMWSock' index 115; Function WSACleanup: LongInt; cdecl; - external 'PMWSock' name 'WSACleanup'; + external 'PMWSock' index 116; Procedure WSASetLastError(iError: LongInt); cdecl; - external 'PMWSock' name 'WSASetLastError'; + external 'PMWSock' index 112; Function WSAGetLastError: LongInt; cdecl; - external 'PMWSock' name 'WSAGetLastError'; + external 'PMWSock' index 111; Function WSAIsBlocking: Longbool; cdecl; - external 'PMWSock' name 'WSAIsBlocking'; + external 'PMWSock' index 114; Function WSAUnhookBlockingHook: LongInt; cdecl; - external 'PMWSock' name 'WSAUnhookBlockingHook'; + external 'PMWSock' index 110; Function WSASetBlockingHook(lpBlockFunc: Pointer): Pointer; cdecl; - external 'PMWSock' name 'WSASetBlockingHook'; + external 'PMWSock' index 109; Function WSACancelBlockingCall: LongInt; cdecl; - external 'PMWSock' name 'WSACancelBlockingCall'; + external 'PMWSock' index 113; Function WSAAsyncGetServByName(hWnd: HWND; wMsg: Cardinal; name: pchar; proto: pchar; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetServByName'; + external 'PMWSock' index 107; Function WSAAsyncGetServByPort(hWnd: HWND; wMsg: Cardinal; port: Longint; proto: pchar; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetServByPort'; + external 'PMWSock' index 106; Function WSAAsyncGetProtoByName(hWnd: HWND; wMsg: Cardinal; name: pchar; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetProtoByName'; + external 'PMWSock' index 105; Function WSAAsyncGetProtoByNumber(hWnd: HWND; wMsg: Cardinal; number: Longint; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetProtoByNumber'; + external 'PMWSock' index 104; Function WSAAsyncGetHostByName(hWnd: HWND; wMsg: Cardinal; name: pchar; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetHostByName'; + external 'PMWSock' index 103; Function WSAAsyncGetHostByAddr(hWnd: HWND; wMsg: Cardinal; addr: pchar; len: Longint; t: Longint; buf: pchar; buflen: Longint): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncGetHostByAddr'; + external 'PMWSock' index 102; Function WSACancelAsyncRequest(hAsyncTaskHandle: Cardinal): LongInt; cdecl; - external 'PMWSock' name 'WSACancelAsyncRequest'; + external 'PMWSock' index 108; Function WSAAsyncSelect(s: TSocket; ahWnd: HWND; wMsg: Cardinal; lEvent: LongInt): Cardinal; cdecl; - external 'PMWSock' name 'WSAAsyncSelect'; + external 'PMWSock' index 101; // Windows message parameter composition and decomposition // macros. diff --git a/rtl/win64/seh64.inc b/rtl/win64/seh64.inc index c25e7cfbeb..c4411d6b44 100644 --- a/rtl/win64/seh64.inc +++ b/rtl/win64/seh64.inc @@ -304,6 +304,7 @@ begin args[1]:=PtrUint(Obj); args[2]:=GetBacktrace(ctx,AFrame,PPointer(args[3])); RaiseException(FPC_EXCEPTION_CODE,EXCEPTION_NONCONTINUABLE,4,@args[0]); + result:=nil; end; procedure _fpc_local_unwind(frame,target: Pointer);[public,alias:'_FPC_local_unwind'];compilerproc; @@ -429,7 +430,7 @@ var begin Adr:=rec.ExceptionInformation[0]; Obj:=TObject(rec.ExceptionInformation[1]); - Framecount:=Longint(rec.ExceptionInformation[2]); + Framecount:=Longint(PtrUInt(rec.ExceptionInformation[2])); Frames:=rec.ExceptionInformation[3]; if rec.ExceptionCode<>FPC_EXCEPTION_CODE then diff --git a/rtl/x86_64/math.inc b/rtl/x86_64/math.inc index f910dcd763..e88764cb8e 100644 --- a/rtl/x86_64/math.inc +++ b/rtl/x86_64/math.inc @@ -13,24 +13,13 @@ **********************************************************************} -label - FPC_ABSMASK_DOUBLE, - FPC_ABSMASK_SINGLE; -procedure dummyproc;assembler;nostackframe; - asm - .data - .balign 16 - .globl FPC_ABSMASK_SINGLE -FPC_ABSMASK_SINGLE: - .quad 0x7FFFFFFF7FFFFFFF - .quad 0x7FFFFFFF7FFFFFFF - .globl FPC_ABSMASK_DOUBLE -FPC_ABSMASK_DOUBLE: - .quad 0x7FFFFFFFFFFFFFFF - .quad 0x7FFFFFFFFFFFFFFF - .text - end; +{$push} +{$codealign constmin=16} +const + FPC_ABSMASK_SINGLE: array[0..1] of qword=($7fffffff7fffffff,$7fffffff7fffffff); cvar; public; + FPC_ABSMASK_DOUBLE: array[0..1] of qword=($7fffffffffffffff,$7fffffffffffffff); cvar; public; +{$pop} {**************************************************************************** FPU Control word diff --git a/rtl/x86_64/setjumph.inc b/rtl/x86_64/setjumph.inc index c988185d0b..28e2bf258d 100644 --- a/rtl/x86_64/setjumph.inc +++ b/rtl/x86_64/setjumph.inc @@ -19,7 +19,7 @@ type rbx,rbp,r12,r13,r14,r15,rsp,rip : qword; {$ifdef win64} rsi,rdi : qword; - xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15: array [boolean] of qword; + xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15: record m1,m2: qword; end; mxcsr: longword; fpucw: word; padding: word; diff --git a/rtl/x86_64/x86_64.inc b/rtl/x86_64/x86_64.inc index cfa0f5dfde..d75e2383db 100644 --- a/rtl/x86_64/x86_64.inc +++ b/rtl/x86_64/x86_64.inc @@ -673,9 +673,9 @@ function declocked(var l : longint) : boolean;assembler; nostackframe; { of time! } {$ifdef FPC_PIC} movq IsMultithread@GOTPCREL(%rip),%rax - cmpb $0,(%rax) + cmpl $0,(%rax) {$else FPC_PIC} - cmpb $0,IsMultithread(%rip) + cmpl $0,IsMultithread(%rip) {$endif FPC_PIC} {$ifndef win64} mov %rdi, %rcx @@ -698,9 +698,9 @@ function declocked(var l : int64) : boolean;assembler; nostackframe; { of time! } {$ifdef FPC_PIC} movq IsMultithread@GOTPCREL(%rip),%rax - cmpb $0,(%rax) + cmpl $0,(%rax) {$else FPC_PIC} - cmpb $0,IsMultithread(%rip) + cmpl $0,IsMultithread(%rip) {$endif FPC_PIC} {$ifndef win64} mov %rdi, %rcx @@ -724,9 +724,9 @@ procedure inclocked(var l : longint);assembler; nostackframe; { of time! } {$ifdef FPC_PIC} movq IsMultithread@GOTPCREL(%rip),%rax - cmpb $0,(%rax) + cmpl $0,(%rax) {$else FPC_PIC} - cmpb $0,IsMultithread(%rip) + cmpl $0,IsMultithread(%rip) {$endif FPC_PIC} {$ifndef win64} mov %rdi, %rcx @@ -749,9 +749,9 @@ procedure inclocked(var l : int64);assembler; nostackframe; { of time! } {$ifdef FPC_PIC} movq IsMultithread@GOTPCREL(%rip),%rax - cmpb $0,(%rax) + cmpl $0,(%rax) {$else FPC_PIC} - cmpb $0,IsMultithread(%rip) + cmpl $0,IsMultithread(%rip) {$endif FPC_PIC} {$ifndef win64} mov %rdi, %rcx |