Browse Source

* synchronized with fixes_3_0 till r30840

git-svn-id: branches/fixes_3_0_ios@30961 -
Jonas Maebe 10 years ago
parent
commit
b4691fbdb0

+ 1 - 0
.gitattributes

@@ -12354,6 +12354,7 @@ tests/test/tunit3.pp svneol=native#text/plain
 tests/test/tunroll1.pp svneol=native#text/plain
 tests/test/tunroll1.pp svneol=native#text/plain
 tests/test/tutf81.pp svneol=native#text/plain
 tests/test/tutf81.pp svneol=native#text/plain
 tests/test/tutf82.pp svneol=native#text/plain
 tests/test/tutf82.pp svneol=native#text/plain
+tests/test/tutf8cpl.pp svneol=native#text/plain
 tests/test/tvarpropsetter1.pp svneol=native#text/plain
 tests/test/tvarpropsetter1.pp svneol=native#text/plain
 tests/test/tvarpropsetter2.pp svneol=native#text/plain
 tests/test/tvarpropsetter2.pp svneol=native#text/plain
 tests/test/tvarset1.pp svneol=native#text/plain
 tests/test/tvarset1.pp svneol=native#text/plain

+ 1 - 1
packages/amunits/src/coreunits/amigados.pas

@@ -1069,7 +1069,7 @@ Type
        tExAllData = record
        tExAllData = record
         ed_Next     : pExAllData;
         ed_Next     : pExAllData;
         ed_Name     : STRPTR;
         ed_Name     : STRPTR;
-        ed_Type,
+        ed_Type     : LongInt;
         ed_Size,
         ed_Size,
         ed_Prot,
         ed_Prot,
         ed_Days,
         ed_Days,

+ 1 - 1
packages/arosunits/src/amigados.pas

@@ -1023,7 +1023,7 @@ type
   TExAllData = record
   TExAllData = record
     ed_Next: PExAllData;
     ed_Next: PExAllData;
     ed_Name: PChar;        // Name of the file
     ed_Name: PChar;        // Name of the file
-    ed_Type,               // Type of File
+    ed_Type: LongInt;      // Type of File
     ed_Size,               // Size of File
     ed_Size,               // Size of File
     ed_Prot,               // Protection Bits
     ed_Prot,               // Protection Bits
 { The following three fields are de facto an embedded datestamp
 { The following three fields are de facto an embedded datestamp

+ 1 - 0
packages/fcl-image/src/freetype.pp

@@ -461,6 +461,7 @@ begin
       CurSize := CreateSize (aSize,aResolution)
       CurSize := CreateSize (aSize,aResolution)
     else
     else
       CurSize := PMgrSize(CurFont.FSizes[r]);
       CurSize := PMgrSize(CurFont.FSizes[r]);
+    SetPixelSize(CurSize^.Size, CurSize^.resolution);
     CurFont.LastSize := CurSize;
     CurFont.LastSize := CurSize;
     end;
     end;
 end;
 end;

+ 3 - 3
packages/libc/src/typesh.inc

@@ -37,7 +37,7 @@ type
         __val : array[0..1] of longint;
         __val : array[0..1] of longint;
      end;
      end;
    __daddr_t = longint;
    __daddr_t = longint;
-   __caddr_t = char;
+   __caddr_t = pchar;
    __time_t = longint;
    __time_t = longint;
    __useconds_t = dword;
    __useconds_t = dword;
    __suseconds_t = longint;
    __suseconds_t = longint;
@@ -169,7 +169,7 @@ Type
   Ppid_t = ^pid_t;
   Ppid_t = ^pid_t;
   Pssize_t = ^ssize_t;
   Pssize_t = ^ssize_t;
   Pdaddr_t = ^daddr_t;
   Pdaddr_t = ^daddr_t;
-  Pcaddr_t = ^caddr_t;
+//  Pcaddr_t = ^caddr_t;
   Pkey_t = ^key_t;
   Pkey_t = ^key_t;
   Puseconds_t = ^useconds_t;
   Puseconds_t = ^useconds_t;
   Psuseconds_t = ^suseconds_t;
   Psuseconds_t = ^suseconds_t;
@@ -207,7 +207,7 @@ Type
   P__id_t = ^__id_t;
   P__id_t = ^__id_t;
   P__fsid_t = ^__fsid_t;
   P__fsid_t = ^__fsid_t;
   P__daddr_t = ^__daddr_t;
   P__daddr_t = ^__daddr_t;
-  P__caddr_t = ^__caddr_t;
+  //P__caddr_t = ^__caddr_t;
   P__time_t = ^__time_t;
   P__time_t = ^__time_t;
   P__useconds_t = ^__useconds_t;
   P__useconds_t = ^__useconds_t;
   P__suseconds_t = ^__suseconds_t;
   P__suseconds_t = ^__suseconds_t;

+ 44 - 38
packages/paszlib/src/zipper.pp

@@ -33,6 +33,38 @@ Const
   CENTRAL_FILE_HEADER_SIGNATURE              = $02014B50;
   CENTRAL_FILE_HEADER_SIGNATURE              = $02014B50;
   ZIP64_HEADER_ID                            = $0001;
   ZIP64_HEADER_ID                            = $0001;
 
 
+const
+  OS_FAT  = 0; //MS-DOS and OS/2 (FAT/VFAT/FAT32)
+  OS_UNIX = 3;
+  OS_OS2  = 6; //OS/2 HPFS
+  OS_NTFS = 10;
+  OS_VFAT = 14;
+  OS_OSX  = 19;
+
+  UNIX_MASK = $F000;
+  UNIX_FIFO = $1000;
+  UNIX_CHAR = $2000;
+  UNIX_DIR  = $4000;
+  UNIX_BLK  = $6000;
+  UNIX_FILE = $8000;
+  UNIX_LINK = $A000;
+  UNIX_SOCK = $C000;
+
+
+  UNIX_RUSR = $0100;
+  UNIX_WUSR = $0080;
+  UNIX_XUSR = $0040;
+
+  UNIX_RGRP = $0020;
+  UNIX_WGRP = $0010;
+  UNIX_XGRP = $0008;
+
+  UNIX_ROTH = $0004;
+  UNIX_WOTH = $0002;
+  UNIX_XOTH = $0001;
+
+  UNIX_DEFAULT = UNIX_RUSR or UNIX_WUSR or UNIX_XUSR or UNIX_RGRP or UNIX_ROTH;
+
 Type
 Type
    Local_File_Header_Type = Packed Record //1 per zipped file
    Local_File_Header_Type = Packed Record //1 per zipped file
      Signature              :  LongInt; //4 bytes
      Signature              :  LongInt; //4 bytes
@@ -692,37 +724,6 @@ begin
   DT:=ComposeDateTime(EncodeDate(Y,M,D),EncodeTime(H,N,S,MS));
   DT:=ComposeDateTime(EncodeDate(Y,M,D),EncodeTime(H,N,S,MS));
 end;
 end;
 
 
-const
-  OS_FAT  = 0; //MS-DOS and OS/2 (FAT/VFAT/FAT32)
-  OS_UNIX = 3;
-  OS_OS2  = 6; //OS/2 HPFS
-  OS_NTFS = 10;
-  OS_VFAT = 14;
-  OS_OSX  = 19;
-
-  UNIX_MASK = $F000;
-  UNIX_FIFO = $1000;
-  UNIX_CHAR = $2000;
-  UNIX_DIR  = $4000;
-  UNIX_BLK  = $6000;
-  UNIX_FILE = $8000;
-  UNIX_LINK = $A000;
-  UNIX_SOCK = $C000;
-
-
-  UNIX_RUSR = $0100;
-  UNIX_WUSR = $0080;
-  UNIX_XUSR = $0040;
-
-  UNIX_RGRP = $0020;
-  UNIX_WGRP = $0010;
-  UNIX_XGRP = $0008;
-
-  UNIX_ROTH = $0004;
-  UNIX_WOTH = $0002;
-  UNIX_XOTH = $0001;
-
-  UNIX_DEFAULT = UNIX_RUSR or UNIX_WUSR or UNIX_XUSR or UNIX_RGRP or UNIX_ROTH;
 
 
 
 
 function ZipUnixAttrsToFatAttrs(const Name: String; Attrs: Longint): Longint;
 function ZipUnixAttrsToFatAttrs(const Name: String; Attrs: Longint): Longint;
@@ -1357,17 +1358,20 @@ Begin
         Raise EZipError.CreateFmt(SErrFileDoesNotExist,[F.DiskFileName]);
         Raise EZipError.CreateFmt(SErrFileDoesNotExist,[F.DiskFileName]);
       end
       end
     else
     else
-      begin
+    begin
       If (F.ArchiveFileName='') then
       If (F.ArchiveFileName='') then
         Raise EZipError.CreateFmt(SErrMissingArchiveName,[I]);
         Raise EZipError.CreateFmt(SErrMissingArchiveName,[I]);
       F.Size:=F.Stream.Size;
       F.Size:=F.Stream.Size;
-    {$IFDEF UNIX}
-      F.Attributes := UNIX_FILE or UNIX_DEFAULT;
-    {$ELSE}
-      F.Attributes := faArchive;
-    {$ENDIF}
-      end;
+      if (F.Attributes = 0) then
+      begin
+      {$IFDEF UNIX}
+        F.Attributes := UNIX_FILE or UNIX_DEFAULT;
+      {$ELSE}
+        F.Attributes := faArchive;
+      {$ENDIF}
+      end;	
     end;
     end;
+  end;
 end;
 end;
 
 
 
 
@@ -2634,6 +2638,8 @@ begin
   FCompressionLevel:=cldefault;
   FCompressionLevel:=cldefault;
   FDateTime:=now;
   FDateTime:=now;
   FNeedsZip64:=false;
   FNeedsZip64:=false;
+  FAttributes:=0;
+
   inherited create(ACollection);
   inherited create(ACollection);
 end;
 end;
 
 

+ 6 - 0
packages/winunits-base/src/eventsink.pp

@@ -81,6 +81,7 @@ type
   constructor Create(AOwner: TComponent); override;
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   destructor Destroy; override;
   procedure Connect(AnAppDispatch: IDispatch; const AnAppDispIntfIID: TGUID);
   procedure Connect(AnAppDispatch: IDispatch; const AnAppDispIntfIID: TGUID);
+  procedure Disconnect;
  published
  published
   property OnInvoke: TInvokeEvent read FOnInvoke write FOnInvoke;
   property OnInvoke: TInvokeEvent read FOnInvoke write FOnInvoke;
  end;
  end;
@@ -182,6 +183,11 @@ begin
  FSink.Connect(AnAppDispatch, AnAppDispIntfIID);
  FSink.Connect(AnAppDispatch, AnAppDispIntfIID);
 end;
 end;
 
 
+procedure TEventSink.Disconnect;
+begin
+  FSink.Disconnect;
+end;
+
 constructor TEventSink.Create(AOwner: TComponent);
 constructor TEventSink.Create(AOwner: TComponent);
 begin
 begin
  inherited Create(AOwner);
  inherited Create(AOwner);

+ 1 - 1
packages/winunits-jedi/src/jwaiptypes.pas

@@ -350,7 +350,7 @@ const
 
 
 type
 type
   IF_OPER_STATUS = (
   IF_OPER_STATUS = (
-    IfOperStatusUp,
+    IfOperStatusUp = 1,
     IfOperStatusDown,
     IfOperStatusDown,
     IfOperStatusTesting,
     IfOperStatusTesting,
     IfOperStatusUnknown,
     IfOperStatusUnknown,

+ 1 - 1
packages/winunits-jedi/src/jwawinnt.pas

@@ -9155,7 +9155,7 @@ end;
 
 
 function IMAGE_FIRST_SECTION(NtHeader: PImageNtHeaders): PImageSectionHeader;
 function IMAGE_FIRST_SECTION(NtHeader: PImageNtHeaders): PImageSectionHeader;
 begin
 begin
-  Result := PImageSectionHeader(Cardinal(NtHeader) +
+  Result := PImageSectionHeader(ptruint(NtHeader) +
       FieldOffset(NtHeader^, NtHeader^.OptionalHeader) +
       FieldOffset(NtHeader^, NtHeader^.OptionalHeader) +
       NtHeader^.FileHeader.SizeOfOptionalHeader);
       NtHeader^.FileHeader.SizeOfOptionalHeader);
 end;
 end;

+ 138 - 0
rtl/inc/generic.inc

@@ -1076,6 +1076,144 @@ function strpas(p:pchar):shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
 
 
 {$endif not cpujvm}
 {$endif not cpujvm}
 
 
+
+function Utf8CodePointLen(P: PAnsiChar; MaxLookAhead: SizeInt; IncludeCombiningDiacriticalMarks: Boolean): SizeInt;
+  var
+    bytes: sizeint;
+    firstzerobit: byte;
+  begin
+    { see https://en.wikipedia.org/wiki/UTF-8#Description for details }
+
+    if maxlookahead<=0 then
+      begin
+        { incomplete }
+        result:=0;
+        exit;
+      end;
+    { inlcude the first byte }
+    result:=1;
+    { multiple byte utf-8 code point? }
+    if p[0]>#127 then
+      begin
+        { bsr searches for the leftmost 1 bit. We are interested in the
+          leftmost 0 bit, so first invert the value
+        }
+        firstzerobit:=bsrbyte(not(byte(p[0])));
+        { if there is no zero bit or the first zero bit is the rightmost bit
+          (bit 0), this is an invalid UTF-8 byte ($ff cannot appear in an
+          UTF-8-encoded string, and in the worst case bit 1 has to be zero)
+          Additionally, 5-byte UTF-8 sequences don't exist either, so bit 1
+          cannot be the first zero-bit either. And bits 6 and 7 can't be 0
+          either in the first byte.
+        }
+        if (firstzerobit<=1) or (firstzerobit>=6)  then
+          begin
+            result:=-result;
+            exit;
+          end;
+        { the number of bytes belonging to this code point is
+          7-(pos first 0-bit). Subtract 1 since we're already at the first
+          byte. All subsequent bytes of the same sequence must have their
+          highest bit set and the next one unset. We stop when we detect an
+          invalid sequence.
+        }
+        bytes:=6-firstzerobit;
+        while (result<maxlookahead) and
+              (bytes>0) and
+              ((ord(p[result]) and %11000000)=%10000000) do
+          begin
+            inc(result);
+            dec(bytes);
+          end;
+        { stopped because of invalid/incomplete sequence -> exit }
+        if bytes<>0 then
+          begin
+            if result>=maxlookahead then
+              result:=0
+            else
+              result:=-result;
+            exit;
+          end;
+      end;
+    if includecombiningdiacriticalmarks then
+      begin
+        { combining diacritical marks?
+            1) U+0300 - U+036F in UTF-8 = %11001100 10000000 - %11001101 10101111
+            2) U+1AB0 - U+1AFF in UTF-8 = %11100001 10101010 10110000 - %11100001 10101011 10111111
+            3) U+1DC0 - U+1DFF in UTF-8 = %11100001 10110111 10000000 - %11100001 10110111 10111111
+            4) U+20D0 - U+20FF in UTF-8 = %11100010 10000011 10010000 - %11100010 10000011 10111111
+            5) U+FE20 - U+FE2F in UTF-8 = %11101111 10111000 10100000 - %11101111 10111000 10101111
+        }
+        repeat
+          bytes:=result;
+          if result+1<maxlookahead then
+            begin
+              { case 1) }
+              if ((ord(p[result]) and %11001100=%11001100)) and
+                  (ord(p[result+1])>=%10000000) and
+                  (ord(p[result+1])<=%10101111) then
+                inc(result,2)
+                  { case 2), 3), 4), 5) }
+              else if (result+2<maxlookahead) and
+                 (ord(p[result])>=%11100001) then
+                begin
+                     { case 2) }
+                  if ((ord(p[result])=%11100001) and
+                      (ord(p[result+1])=%10101010) and
+                      (ord(p[result+2])>=%10110000) and
+                      (ord(p[result+2])<=%10111111)) or
+                     { case 3) }
+                     ((ord(p[result])=%11100001) and
+                      (ord(p[result+1])=%10110111) and
+                      (ord(p[result+2])>=%10000000) and
+                      (ord(p[result+2])<=%10111111)) or
+                     { case 4) }
+                     ((ord(p[result])=%11100010) and
+                      (ord(p[result+1])=%10000011) and
+                      (ord(p[result+2])>=%10010000) and
+                      (ord(p[result+2])<=%10111111)) or
+                     { case 5) }
+                     ((ord(p[result])=%11101111) and
+                      (ord(p[result+1])=%10111000) and
+                      (ord(p[result+2])>=%10100000) and
+                      (ord(p[result+2])<=%10101111)) then
+                    inc(result,3);
+                end;
+            end;
+        until bytes=result;
+        { is there an incomplete diacritical mark? (invalid makes little sense:
+          either a sequence is a combining diacritical mark, or it's not ; if
+          it's invalid, it may also not have been a combining diacritical mark)
+        }
+        if result<maxlookahead then
+          begin
+               { case 1) }
+            if (((ord(p[result]) and %11001100=%11001100)) and
+                (result+1>=maxlookahead)) or
+               { case 2) and 3)}
+               ((ord(p[result])=%11100001) and
+                ((result+1>=maxlookahead) or
+                 (((ord(p[result+1])=%10101010) or
+                   (ord(p[result+1])=%10110111)) and
+                  (result+2>=maxlookahead)))) or
+               { case 4 }
+               ((ord(p[result])=%11100010) and
+                ((result+1>=maxlookahead) or
+                 ((ord(p[result+1])=%10000011) and
+                  (result+2>=maxlookahead)))) or
+               { case 5 }
+               ((ord(p[result])=%11101111) and
+                ((result+1>=maxlookahead) or
+                 ((ord(p[result+1])=%10111000) and
+                  (result+2>=maxlookahead)))) then
+              begin
+                result:=0;
+                exit;
+              end;
+          end;
+      end;
+  end;
+
 {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
 {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
 
 
 procedure fpc_chararray_to_shortstr(out res : shortstring;const arr: array of char; zerobased: boolean = true);[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
 procedure fpc_chararray_to_shortstr(out res : shortstring;const arr: array of char; zerobased: boolean = true);[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;

+ 8 - 0
rtl/inc/systemh.inc

@@ -1081,6 +1081,14 @@ Function  Sseg:Word;{$ifdef SYSTEMINLINE}inline;{$endif}
 function strpas(p:pchar):shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
 function strpas(p:pchar):shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
 function strlen(p:pchar):sizeint;external name 'FPC_PCHAR_LENGTH';
 function strlen(p:pchar):sizeint;external name 'FPC_PCHAR_LENGTH';
 
 
+{ result:
+  <0: invalid sequence detected after processing "-result" bytes
+  0: incomplete (may still be valid if MaxLookAhead is increased)
+  >0: sequence of result bytes forms a codepoint (+ combining diacritics if that
+      parameter was true)
+}
+function Utf8CodePointLen(P: PAnsiChar; MaxLookAhead: SizeInt; IncludeCombiningDiacriticalMarks: Boolean): SizeInt;
+
 { Shortstring functions }
 { Shortstring functions }
 Procedure Delete(var s:shortstring;index:SizeInt;count:SizeInt);
 Procedure Delete(var s:shortstring;index:SizeInt;count:SizeInt);
 Procedure Insert(const source:shortstring;var s:shortstring;index:SizeInt);
 Procedure Insert(const source:shortstring;var s:shortstring;index:SizeInt);

+ 9 - 0
rtl/java/jsystemh.inc

@@ -442,6 +442,15 @@ function strpas(p:pchar):shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
 function strlen(p:pchar):sizeint;external name 'FPC_PCHAR_LENGTH';
 function strlen(p:pchar):sizeint;external name 'FPC_PCHAR_LENGTH';
 *)
 *)
 
 
+{ result:
+  <0: invalid sequence detected after processing "-result" bytes
+  0: incomplete (may still be valid if MaxLookAhead is increased)
+  >0: sequence of result bytes forms a codepoint (+ combining diacritics if that
+      parameter was true)
+}
+function Utf8CodePointLen(P: PAnsiChar; MaxLookAhead: SizeInt; IncludeCombiningDiacriticalMarks: Boolean): SizeInt;
+
+
 var
 var
   { separated compared to generic version, for Java type safety }
   { separated compared to generic version, for Java type safety }
   FPC_EMPTYANSICHAR : array[0..0] of ansichar;
   FPC_EMPTYANSICHAR : array[0..0] of ansichar;

+ 17 - 3
rtl/netbsd/ptypes.inc

@@ -169,7 +169,8 @@ struct statfs12 {
         1: (_mbstateL: cint64); { for alignment }
         1: (_mbstateL: cint64); { for alignment }
     end;
     end;
    pmbstate_t = ^mbstate_t;
    pmbstate_t = ^mbstate_t;
-  
+ 
+{ records transcripted fromm NetBSD 5.1 libpthread sources } 
    pthread_t            = pointer;
    pthread_t            = pointer;
    pthread_attr_t       = record
    pthread_attr_t       = record
      pta_magic : cuint;
      pta_magic : cuint;
@@ -181,8 +182,21 @@ struct statfs12 {
      ptma_magic : cint;
      ptma_magic : cint;
      ptma_private : pointer;
      ptma_private : pointer;
    end;
    end;
-   pthread_cond_t       = pointer;
-   pthread_condattr_t   = pointer;
+   pthread_spin_t = char;
+   pthread_queue_t = record
+       first, last : pointer;
+     end;
+   pthread_cond_t       = record
+       ptc_magic : cuint;
+       ptc_lock : pthread_spin_t;
+       ptc_waiters : pthread_queue_t;
+       ptc_mutex : ^pthread_mutex_t;
+       ptc_private : pointer;
+     end;
+   pthread_condattr_t   = record
+       ptca_magic : cuint;
+       ptca_private : pointer;
+     end;
    pthread_key_t        = cint;
    pthread_key_t        = cint;
    pthread_rwlock_t     = pointer;
    pthread_rwlock_t     = pointer;
    pthread_rwlockattr_t = pointer;
    pthread_rwlockattr_t = pointer;

+ 59 - 0
rtl/win/wininc/base.inc

@@ -593,6 +593,21 @@
   #endif
   #endif
    }
    }
 
 
+
+  function IMAGE_ORDINAL64(Ordinal : uint64) : uint64; inline;
+  function IMAGE_ORDINAL32(Ordinal : cardinal) : cardinal;inline;
+  function IMAGE_SNAP_BY_ORDINAL64(Ordinal : uint64) : boolean;  inline;
+  function IMAGE_SNAP_BY_ORDINAL32(Ordinal : cardinal) : boolean; inline;
+  {$ifdef WIN64}
+    function IMAGE_ORDINAL(Ordinal : uint64) : uint64; inline;
+    function IMAGE_SNAP_BY_ORDINAL(Ordinal : uint64) : boolean; inline;
+  {$else}
+    function IMAGE_ORDINAL(Ordinal : cardinal) : cardinal; inline;
+    function IMAGE_SNAP_BY_ORDINAL(Ordinal : cardinal) : boolean; inline;
+  {$endif}
+ 
+
+
  {
  {
     Definitions for callback procedures
     Definitions for callback procedures
  }
  }
@@ -1057,5 +1072,49 @@ type
        PALETTERGB:=$02000000 or (RGB(r,g,b));
        PALETTERGB:=$02000000 or (RGB(r,g,b));
     end;
     end;
 
 
+  function IMAGE_ORDINAL64(Ordinal : uint64) : uint64;
+  begin
+    IMAGE_ORDINAL64:=Ordinal and $ffff;
+  end;
+
+  function IMAGE_ORDINAL32(Ordinal : cardinal) : cardinal;
+  begin
+    IMAGE_ORDINAL32:=Ordinal and $ffff;
+  end;
+
+  function IMAGE_SNAP_BY_ORDINAL64(Ordinal : uint64) : boolean;
+  begin
+    IMAGE_SNAP_BY_ORDINAL64:=(Ordinal and IMAGE_ORDINAL_FLAG64)<>0;
+  end;
+
+  function IMAGE_SNAP_BY_ORDINAL32(Ordinal : cardinal) : boolean;
+  begin
+    IMAGE_SNAP_BY_ORDINAL32:=(Ordinal and IMAGE_ORDINAL_FLAG32)<>0;
+  end;
+
+  {$ifdef win64}
+  function IMAGE_ORDINAL(Ordinal : uint64) : uint64;
+  begin
+    IMAGE_ORDINAL:=IMAGE_ORDINAL64(Ordinal);
+  end;
+
+
+  function IMAGE_SNAP_BY_ORDINAL(Ordinal : uint64) : boolean;
+  begin
+    IMAGE_SNAP_BY_ORDINAL:=IMAGE_SNAP_BY_ORDINAL64(Ordinal);
+  end;
+
+  {$else}
+
+  function IMAGE_ORDINAL(Ordinal : cardinal) : cardinal;
+  begin
+    IMAGE_ORDINAL:=IMAGE_ORDINAL32(Ordinal);
+  end;
+
+  function IMAGE_SNAP_BY_ORDINAL(Ordinal : cardinal) : boolean;
+  begin
+    IMAGE_SNAP_BY_ORDINAL:=IMAGE_SNAP_BY_ORDINAL32(Ordinal);
+  end;
+ {$endif}
 {$endif read_implementation}
 {$endif read_implementation}
 
 

+ 82 - 0
rtl/win/wininc/defines.inc

@@ -5913,6 +5913,68 @@ const
     IMAGE_FILE_MACHINE_CEE               = $C0EE;
     IMAGE_FILE_MACHINE_CEE               = $C0EE;
     IMAGE_FILE_LARGE_ADDRESS_AWARE       = $20;    // for peflags.
     IMAGE_FILE_LARGE_ADDRESS_AWARE       = $20;    // for peflags.
 
 
+  //
+  // Section characteristics.
+  //
+  //      IMAGE_SCN_TYPE_REG                   = $00000000;  // Reserved.
+  //      IMAGE_SCN_TYPE_DSECT                 = $00000001;  // Reserved.
+  //      IMAGE_SCN_TYPE_NOLOAD                = $00000002;  // Reserved.
+  //      IMAGE_SCN_TYPE_GROUP                 = $00000004;  // Reserved.
+     IMAGE_SCN_TYPE_NO_PAD                = $00000008;  // Reserved.
+  //      IMAGE_SCN_TYPE_COPY                  = $00000010;  // Reserved.
+
+     IMAGE_SCN_CNT_CODE                   = $00000020;  // Section contains code.
+     IMAGE_SCN_CNT_INITIALIZED_DATA       = $00000040;  // Section contains initialized data.
+     IMAGE_SCN_CNT_UNINITIALIZED_DATA     = $00000080;  // Section contains uninitialized data.
+
+     IMAGE_SCN_LNK_OTHER                  = $00000100;  // Reserved.
+     IMAGE_SCN_LNK_INFO                   = $00000200;  // Section contains comments or some other type of information.
+  //      IMAGE_SCN_TYPE_OVER                  = $00000400  // Reserved.
+     IMAGE_SCN_LNK_REMOVE                 = $00000800;  // Section contents will not become part of image.
+     IMAGE_SCN_LNK_COMDAT                 = $00001000;  // Section contents comdat.
+  //                                           = $00002000  // Reserved.
+  //      IMAGE_SCN_MEM_PROTECTED - Obsolete   = $00004000
+     IMAGE_SCN_NO_DEFER_SPEC_EXC          = $00004000;  // Reset speculative exceptions handling bits in the TLB entries for this section.
+     IMAGE_SCN_GPREL                      = $00008000;  // Section content can be accessed relative to GP
+     IMAGE_SCN_MEM_FARDATA                = $00008000;
+  //      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    = $00010000;
+     IMAGE_SCN_MEM_PURGEABLE              = $00020000;
+     IMAGE_SCN_MEM_16BIT                  = $00020000;
+     IMAGE_SCN_MEM_LOCKED                 = $00040000;
+     IMAGE_SCN_MEM_PRELOAD                = $00080000;
+
+     IMAGE_SCN_ALIGN_1BYTES               = $00100000;  //
+     IMAGE_SCN_ALIGN_2BYTES               = $00200000;  //
+     IMAGE_SCN_ALIGN_4BYTES               = $00300000;  //
+     IMAGE_SCN_ALIGN_8BYTES               = $00400000;  //
+     IMAGE_SCN_ALIGN_16BYTES              = $00500000;  // Default alignment if no others are specified.
+     IMAGE_SCN_ALIGN_32BYTES              = $00600000;  //
+     IMAGE_SCN_ALIGN_64BYTES              = $00700000;  //
+     IMAGE_SCN_ALIGN_128BYTES             = $00800000;  //
+     IMAGE_SCN_ALIGN_256BYTES             = $00900000;  //
+     IMAGE_SCN_ALIGN_512BYTES             = $00A00000;  //
+     IMAGE_SCN_ALIGN_1024BYTES            = $00B00000;  //
+     IMAGE_SCN_ALIGN_2048BYTES            = $00C00000;  //
+     IMAGE_SCN_ALIGN_4096BYTES            = $00D00000;  //
+     IMAGE_SCN_ALIGN_8192BYTES            = $00E00000;  //
+  // Unused                                    = $00F00000;
+     IMAGE_SCN_ALIGN_MASK                 = $00F00000;
+
+     IMAGE_SCN_LNK_NRELOC_OVFL            = $01000000;  // Section contains extended relocations.
+     IMAGE_SCN_MEM_DISCARDABLE            = $02000000;  // Section can be discarded.
+     IMAGE_SCN_MEM_NOT_CACHED             = $04000000;  // Section is not cachable.
+     IMAGE_SCN_MEM_NOT_PAGED              = $08000000;  // Section is not pageable.
+     IMAGE_SCN_MEM_SHARED                 = $10000000;  // Section is shareable.
+     IMAGE_SCN_MEM_EXECUTE                = $20000000;  // Section is executable.
+     IMAGE_SCN_MEM_READ                   = $40000000;  // Section is readable.
+     IMAGE_SCN_MEM_WRITE                  = $80000000;  // Section is writeable.
+
+  //
+  // TLS Characteristic Flags
+  //
+     IMAGE_SCN_SCALE_INDEX                = $00000001;  // Tls index is scaled
+
+
     GWLP_WNDPROC        		 = -4; 
     GWLP_WNDPROC        		 = -4; 
     GWLP_HINSTANCE      		 = -6; 
     GWLP_HINSTANCE      		 = -6; 
     GWLP_HWNDPARENT     		 = -8; 
     GWLP_HWNDPARENT     		 = -8; 
@@ -5927,6 +5989,26 @@ const
     GCLP_WNDPROC                         = -24;
     GCLP_WNDPROC                         = -24;
     GCLP_HICONSM                         = -34;
     GCLP_HICONSM                         = -34;
 
 
+    IMAGE_ORDINAL_FLAG64 = uint64($8000000000000000);
+    IMAGE_ORDINAL_FLAG32 = uint32($80000000);
+    bm__IMAGE_TLS_DIRECTORY64_Reserved0 = $FFFFF;
+    bp__IMAGE_TLS_DIRECTORY64_Reserved0 = 0;
+    bm__IMAGE_TLS_DIRECTORY64_Alignment = $F00000;
+    bp__IMAGE_TLS_DIRECTORY64_Alignment = 20;
+    bm__IMAGE_TLS_DIRECTORY64_Reserved1 = $FF000000;
+    bp__IMAGE_TLS_DIRECTORY64_Reserved1 = 24;
+    bm__IMAGE_TLS_DIRECTORY32_Reserved0 = $FFFFF;
+    bp__IMAGE_TLS_DIRECTORY32_Reserved0 = 0;
+    bm__IMAGE_TLS_DIRECTORY32_Alignment = $F00000;
+    bp__IMAGE_TLS_DIRECTORY32_Alignment = 20;
+    bm__IMAGE_TLS_DIRECTORY32_Reserved1 = $FF000000;
+    bp__IMAGE_TLS_DIRECTORY32_Reserved1 = 24;
+
+{$ifdef WIN64}
+    IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG64;
+{$else}
+    IMAGE_ORDINAL_FLAG = IMAGE_ORDINAL_FLAG32;
+{$endif}                                                          
 
 
 // #if(WINVER >= 0x0500)
 // #if(WINVER >= 0x0500)
 {/*
 {/*

+ 17 - 0
rtl/win/wininc/func.inc

@@ -245,6 +245,7 @@ function SetSystemTime(lpSystemTime:LPSYSTEMTIME):WINBOOL; external 'kernel32' n
 procedure GetLocalTime(lpSystemTime:LPSYSTEMTIME); external 'kernel32' name 'GetLocalTime';
 procedure GetLocalTime(lpSystemTime:LPSYSTEMTIME); external 'kernel32' name 'GetLocalTime';
 function SetLocalTime(lpSystemTime:LPSYSTEMTIME):WINBOOL; external 'kernel32' name 'SetLocalTime';
 function SetLocalTime(lpSystemTime:LPSYSTEMTIME):WINBOOL; external 'kernel32' name 'SetLocalTime';
 procedure GetSystemInfo(lpSystemInfo:LPSYSTEM_INFO); external 'kernel32' name 'GetSystemInfo';
 procedure GetSystemInfo(lpSystemInfo:LPSYSTEM_INFO); external 'kernel32' name 'GetSystemInfo';
+procedure GetNativeSystemInfo(lpSystemInfo:LPSYSTEM_INFO); external 'kernel32' name 'GetNativeSystemInfo';
 function SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION; lpUniversalTime:LPSYSTEMTIME; lpLocalTime:LPSYSTEMTIME):WINBOOL; external 'kernel32' name 'SystemTimeToTzSpecificLocalTime';
 function SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION; lpUniversalTime:LPSYSTEMTIME; lpLocalTime:LPSYSTEMTIME):WINBOOL; external 'kernel32' name 'SystemTimeToTzSpecificLocalTime';
 function GetTimeZoneInformation(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION):DWORD; external 'kernel32' name 'GetTimeZoneInformation';
 function GetTimeZoneInformation(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION):DWORD; external 'kernel32' name 'GetTimeZoneInformation';
 function SetTimeZoneInformation(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION):WINBOOL; external 'kernel32' name 'SetTimeZoneInformation';
 function SetTimeZoneInformation(lpTimeZoneInformation:LPTIME_ZONE_INFORMATION):WINBOOL; external 'kernel32' name 'SetTimeZoneInformation';
@@ -1273,6 +1274,7 @@ function EndMenu:BOOL; external 'user32' name 'EndMenu';
 
 
 
 
 function GetMenuBarInfo(_hwnd:HWND; idObject:longint; idItem:longint; pmbi:LPMENUBARINFO):BOOL; external 'user32' name 'GetMenuBarInfo';
 function GetMenuBarInfo(_hwnd:HWND; idObject:longint; idItem:longint; pmbi:LPMENUBARINFO):BOOL; external 'user32' name 'GetMenuBarInfo';
+function IMAGE_FIRST_SECTION(ntheader : PIMAGE_NT_HEADERS):PIMAGE_SECTION_HEADER;
 
 
 {$endif read_interface}
 {$endif read_interface}
 
 
@@ -2372,5 +2374,20 @@ begin
   GetLargestConsoleWindowSize:=COORD(res);
   GetLargestConsoleWindowSize:=COORD(res);
 end;
 end;
 
 
+{
+#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
+    ((ULONG_PTR)(ntheader) + \
+     FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
+     ((ntheader))->FileHeader.SizeOfOptionalHeader \
+    )) 
+
+}
+
+function IMAGE_FIRST_SECTION(ntheader : PIMAGE_NT_HEADERS):PIMAGE_SECTION_HEADER;
+// (PTRUINT(ntheader)+ OFS(ntheader^.OptionalHeader) - OFS(NTHEADER);  -> address of ntheader cancels.
+begin
+  IMAGE_FIRST_SECTION:=PIMAGE_SECTION_HEADER(OFS(ntheader^.OptionalHeader) + ntheader^.FileHeader.SizeOfOptionalHeader);
+end;
+
 {$endif read_implementation}
 {$endif read_implementation}
 
 

+ 215 - 0
rtl/win/wininc/struct.inc

@@ -8344,6 +8344,221 @@ type
      PIMAGE_LOAD_CONFIG_DIRECTORY = PIMAGE_LOAD_CONFIG_DIRECTORY32;
      PIMAGE_LOAD_CONFIG_DIRECTORY = PIMAGE_LOAD_CONFIG_DIRECTORY32;
 {$endif}
 {$endif}
 
 
+{$push}
+{$packrecords 4}
+
+    PIMAGE_EXPORT_DIRECTORY = ^TIMAGE_EXPORT_DIRECTORY;
+    IMAGE_EXPORT_DIRECTORY = record
+        Characteristics : DWORD;
+        TimeDateStamp   : DWORD;
+        MajorVersion    : WORD;
+        MinorVersion    : WORD;
+        Name 	        : DWORD;
+        Base 		    : DWORD;
+        NumberOfFunctions : DWORD;
+        NumberOfNames   : DWORD;
+        AddressOfFunctions : DWORD;     { RVA from base of image }
+        AddressOfNames  : DWORD;        { RVA from base of image }
+        AddressOfNameOrdinals : DWORD;  { RVA from base of image }
+      end;
+    TIMAGE_EXPORT_DIRECTORY = IMAGE_EXPORT_DIRECTORY; 
+    _IMAGE_EXPORT_DIRECTORY = IMAGE_EXPORT_DIRECTORY;
+    LPIMAGE_EXPORT_DIRECTORY= PIMAGE_EXPORT_DIRECTORY;
+
+  P_IMAGE_IMPORT_BY_NAME = ^_IMAGE_IMPORT_BY_NAME;
+  _IMAGE_IMPORT_BY_NAME =  record
+      Hint : WORD;
+      Name : array[0..0] of AnsiCHAR;
+    end;
+  IMAGE_IMPORT_BY_NAME = _IMAGE_IMPORT_BY_NAME;
+  PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
+  LPIMAGE_IMPORT_BY_NAME = P_IMAGE_IMPORT_BY_NAME;
+  PPIMAGE_IMPORT_BY_NAME = ^PIMAGE_IMPORT_BY_NAME;
+
+  {$push}{$packrecords 8}              // Use align 8 for the 64-bit IAT.}
+  P_IMAGE_THUNK_DATA64 = ^_IMAGE_THUNK_DATA64;
+  _IMAGE_THUNK_DATA64 =  record
+      u1 :  record
+          case longint of
+            0 : ( ForwarderString : ULONGLONG );    { PBYTE  }
+            1 : ( _Function : ULONGLONG );          { PDWORD }
+            2 : ( Ordinal : ULONGLONG );
+            3 : ( AddressOfData : ULONGLONG );      { PIMAGE_IMPORT_BY_NAME }
+          end;
+    end;
+  IMAGE_THUNK_DATA64 = _IMAGE_THUNK_DATA64;
+  PIMAGE_THUNK_DATA64 = ^IMAGE_THUNK_DATA64;
+
+  PPIMAGE_THUNK_DATA64 = ^PIMAGE_THUNK_DATA64;
+  LPIMAGE_THUNK_DATA64 = PIMAGE_THUNK_DATA64;
+  {$pop}                        // Back to 4 byte packing}
+
+  P_IMAGE_THUNK_DATA32 = ^_IMAGE_THUNK_DATA32;
+  _IMAGE_THUNK_DATA32 =  record
+      u1 :  record
+          case longint of
+            0 : ( ForwarderString : DWORD );          { PBYTE  }
+            1 : ( _Function : DWORD );                { PDWORD }
+            2 : ( Ordinal : DWORD );
+            3 : ( AddressOfData : DWORD );            { PIMAGE_IMPORT_BY_NAME }
+          end;
+    end;
+  IMAGE_THUNK_DATA32 = _IMAGE_THUNK_DATA32;
+  PIMAGE_THUNK_DATA32 = ^IMAGE_THUNK_DATA32;
+
+  PPIMAGE_THUNK_DATA32 = ^PIMAGE_THUNK_DATA32;
+  LPIMAGE_THUNK_DATA32 = PIMAGE_THUNK_DATA32;
+
+  { }
+  { Thread Local Storage }
+  { }
+
+  PIMAGE_TLS_CALLBACK = procedure (DllHandle:PVOID; Reason:DWORD; Reserved:PVOID);stdcall; {NTAPI}
+
+  P_IMAGE_TLS_DIRECTORY64 = ^_IMAGE_TLS_DIRECTORY64;
+  _IMAGE_TLS_DIRECTORY64 =  record
+      StartAddressOfRawData : ULONGLONG;
+      EndAddressOfRawData : ULONGLONG;
+      AddressOfIndex : ULONGLONG;               { PDWORD }
+      AddressOfCallBacks : ULONGLONG;           { PIMAGE_TLS_CALLBACK *; }
+      SizeOfZeroFill : DWORD;
+          case longint of
+            0 : ( Characteristics : DWORD );
+            1 : ( CharacteristicsFields:  bitpacked record
+                                  Reserved0 : 0..$FFFFF; // 5 nibbles=20 bits
+                                  Alignment : 0..$F;      // 4 bits
+                                  Reserved1 : 0..$FF;     // 8 bits
+              end );
+    end;
+  IMAGE_TLS_DIRECTORY64 = _IMAGE_TLS_DIRECTORY64;
+  PIMAGE_TLS_DIRECTORY64 = ^IMAGE_TLS_DIRECTORY64;
+
+  PPIMAGE_TLS_DIRECTORY64 = ^PIMAGE_TLS_DIRECTORY64;
+  LPIMAGE_TLS_DIRECTORY64 = PIMAGE_TLS_DIRECTORY64;
+  P_IMAGE_TLS_DIRECTORY32 = ^_IMAGE_TLS_DIRECTORY32;
+  _IMAGE_TLS_DIRECTORY32 =  record
+      StartAddressOfRawData : DWORD;
+      EndAddressOfRawData : DWORD;
+      AddressOfIndex : DWORD;                      { PDWORD }
+      AddressOfCallBacks : DWORD;                  { PIMAGE_TLS_CALLBACK * }
+      SizeOfZeroFill : DWORD;
+          case longint of
+            0 : ( Characteristics : DWORD );
+            1 : ( CharacteristicsFields : bitpacked  record
+                                 Reserved0 : 0..$FFFFF; // 5 nibbles=20 bits
+                                 Alignment : 0..$F;      // 4 bits
+                                 Reserved1 : 0..$FF;     // 8 bits
+              end );
+
+    end;
+  IMAGE_TLS_DIRECTORY32 = _IMAGE_TLS_DIRECTORY32;
+  PIMAGE_TLS_DIRECTORY32 = ^IMAGE_TLS_DIRECTORY32;
+
+
+
+  PPIMAGE_TLS_DIRECTORY32 = ^PIMAGE_TLS_DIRECTORY32;
+  LPIMAGE_TLS_DIRECTORY32 = PIMAGE_TLS_DIRECTORY32;
+
+  {$ifdef WIN64}
+
+  PIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA64;
+  IMAGE_THUNK_DATA = IMAGE_THUNK_DATA64;
+
+  PPIMAGE_THUNK_DATA = ^PIMAGE_THUNK_DATA64;
+  LPIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA64;
+
+  PIMAGE_TLS_DIRECTORY = ^IMAGE_TLS_DIRECTORY;
+  IMAGE_TLS_DIRECTORY = IMAGE_TLS_DIRECTORY64;
+
+  PPIMAGE_TLS_DIRECTORY = ^PIMAGE_TLS_DIRECTORY;
+  LPIMAGE_TLS_DIRECTORY = PIMAGE_TLS_DIRECTORY64;
+  {$else}
+
+  PIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA32;
+  IMAGE_THUNK_DATA = IMAGE_THUNK_DATA32;
+
+  PPIMAGE_THUNK_DATA = ^PIMAGE_THUNK_DATA;
+  LPIMAGE_THUNK_DATA = PIMAGE_THUNK_DATA32;
+  PIMAGE_TLS_DIRECTORY = ^IMAGE_TLS_DIRECTORY;
+  IMAGE_TLS_DIRECTORY = IMAGE_TLS_DIRECTORY32;
+
+  PPIMAGE_TLS_DIRECTORY = ^PIMAGE_TLS_DIRECTORY;
+  LPIMAGE_TLS_DIRECTORY = PIMAGE_TLS_DIRECTORY32;
+  {$endif}
+
+  P_IMAGE_IMPORT_DESCRIPTOR = ^_IMAGE_IMPORT_DESCRIPTOR;
+  _IMAGE_IMPORT_DESCRIPTOR =  record
+          case longint of
+            0 : ( Characteristics : DWORD );     { 0 for terminating null import descriptor }
+            1 : ( OriginalFirstThunk : DWORD;    { RVA to original unbound IAT (PIMAGE_THUNK_DATA) }
+                  TimeDateStamp : DWORD;         { 0 if not bound, }
+                                                 // -1 if bound, and real date\time stamp
+                                                 //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
+                                                 // O.W. date/time stamp of DLL bound to (Old BIND)
+                  ForwarderChain : DWORD;        // -1 if no forwarders
+                  Name : DWORD;
+                  FirstThunk : DWORD;            // RVA to IAT (if bound this IAT has actual addresses)
+                );  
+    end;
+  IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
+  PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR   {UNALIGNED  }     ;
+
+
+  PPIMAGE_IMPORT_DESCRIPTOR = ^PIMAGE_IMPORT_DESCRIPTOR;
+  LPIMAGE_IMPORT_DESCRIPTOR = PIMAGE_IMPORT_DESCRIPTOR;
+  { }
+  { New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] }
+  { }
+
+
+  P_IMAGE_BOUND_IMPORT_DESCRIPTOR = ^_IMAGE_BOUND_IMPORT_DESCRIPTOR;
+  _IMAGE_BOUND_IMPORT_DESCRIPTOR =  record
+      TimeDateStamp : DWORD;
+      OffsetModuleName : WORD;
+      NumberOfModuleForwarderRefs : WORD;
+      { Array of zero or more IMAGE_BOUND_FORWARDER_REF follows }
+    end;
+
+  IMAGE_BOUND_IMPORT_DESCRIPTOR = _IMAGE_BOUND_IMPORT_DESCRIPTOR;
+  PIMAGE_BOUND_IMPORT_DESCRIPTOR = ^IMAGE_BOUND_IMPORT_DESCRIPTOR;
+  LPIMAGE_BOUND_IMPORT_DESCRIPTOR = P_IMAGE_BOUND_IMPORT_DESCRIPTOR;
+  PPIMAGE_BOUND_IMPORT_DESCRIPTOR = ^PIMAGE_BOUND_IMPORT_DESCRIPTOR;
+
+  P_IMAGE_BOUND_FORWARDER_REF = ^_IMAGE_BOUND_FORWARDER_REF;
+  _IMAGE_BOUND_FORWARDER_REF =  record
+      TimeDateStamp : DWORD;
+      OffsetModuleName : WORD;
+      Reserved : WORD;
+    end;
+  IMAGE_BOUND_FORWARDER_REF = _IMAGE_BOUND_FORWARDER_REF;
+  PIMAGE_BOUND_FORWARDER_REF = ^IMAGE_BOUND_FORWARDER_REF;
+  LPIMAGE_BOUND_FORWARDER_REF = P_IMAGE_BOUND_FORWARDER_REF;
+  PPIMAGE_BOUND_FORWARDER_REF = ^PIMAGE_BOUND_FORWARDER_REF;
+  { Delay load version 2 }
+
+  _IMAGE_DELAYLOAD_DESCRIPTOR = record
+        case longint of
+        0: (AllAttributes :Dword;
+            DllNameRVA,                       // RVA to the name of the target library (NULL-terminate ASCII string)
+            ModuleHandleRVA,                  // RVA to the HMODULE caching location (PHMODULE)
+            ImportAddressTableRVA,            // RVA to the start of the IAT (PIMAGE_THUNK_DATA)
+            ImportNameTableRVA,               // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData)
+            BoundImportAddressTableRVA,       // RVA to an optional bound IAT
+            UnloadInformationTableRVA,        // RVA to an optional unload info table
+            TimeDateStamp            : DWORD; // 0 if not bound,
+                                            // Otherwise, date/time of the target DLL
+         );
+        1: (Attributes:bitpacked record
+             rvabased:0..1;  {1 bits}                 // Delay load version 2
+             ReservedAttributes: 0..$7FFFFFF; {31 bits}
+             end;)
+     end;
+
+  IMAGE_DELAYLOAD_DESCRIPTOR= _IMAGE_DELAYLOAD_DESCRIPTOR;
+  PIMAGE_DELAYLOAD_DESCRIPTOR= ^_IMAGE_DELAYLOAD_DESCRIPTOR;
+  PCIMAGE_DELAYLOAD_DESCRIPTOR= PIMAGE_DELAYLOAD_DESCRIPTOR;
+{$pop}
+
  tagCOMBOBOXINFO = record
  tagCOMBOBOXINFO = record
     cbSize: DWORD;
     cbSize: DWORD;
     rcItem: TRect;
     rcItem: TRect;

+ 148 - 0
tests/test/tutf8cpl.pp

@@ -0,0 +1,148 @@
+{$mode objfpc}
+{$codepage utf8}
+
+var
+  name: utf8string;
+  
+procedure check(index, lookahead: longint; combiningdiacritics: boolean; expectedresult: longint; checknr: longint);
+begin
+  if Utf8CodePointLen(pchar(@name[index]),lookahead,combiningdiacritics)<>expectedresult then
+    begin
+      writeln('check ',checknr,': Utf8CodePointLen(',copy(name,index,length(name)),',',lookahead,',',combiningdiacritics,') = ',Utf8CodePointLen(pchar(@name[index]),lookahead,false),' <> expected ',expectedresult);
+      halt(1);
+    end;
+end;
+
+begin
+  name:='a';
+  check(1,0,false,0,1);
+  check(1,1,false,1,2);
+  check(1,1,true,1,3);
+  check(1,6,false,1,4);
+  check(1,6,true,1,5);
+  name:='ab';
+  check(1,6,false,1,6);
+  check(1,6,true,1,7);
+  check(1,1,false,1,8);
+  check(1,1,true,1,9);
+  check(2,6,false,1,10);
+  check(2,6,true,1,11);
+  name:='é';
+  check(1,1,false,0,12);
+  check(1,1,true,0,13);
+  check(1,2,false,2,14);
+  check(1,2,true,2,15);
+  check(2,1,false,-1,16);
+  check(2,1,true,-1,17);
+  check(2,3,false,-1,18);
+  check(2,3,true,-1,19);
+  name:='éa';
+  check(1,1,false,0,20);
+  check(1,1,true,0,21);
+  check(1,2,false,2,22);
+  check(1,2,true,2,23);
+  check(2,1,false,-1,24);
+  check(2,1,true,-1,25);
+  check(2,3,false,-1,26);
+  check(2,3,true,-1,27);
+  check(3,1,false,1,28);
+  check(3,1,true,1,29);
+  check(3,4,false,1,30);
+  check(3,4,true,1,31);
+  name[3]:=name[2];
+  check(1,1,false,0,32);
+  check(1,1,true,0,33);
+  check(1,2,false,2,34);
+  check(1,2,true,2,35);
+  check(2,1,false,-1,36);
+  check(2,1,true,-1,37);
+  check(2,3,false,-1,38);
+  check(2,3,true,-1,39);
+  check(3,1,false,-1,40);
+  check(3,1,true,-1,41);
+  check(3,4,false,-1,42);
+  check(3,4,true,-1,43);
+  { e + combining ` }
+  name:='e'#$0300'b';
+  { check just the e without accent }
+  check(1,1,false,1,44);
+  check(1,1,true,1,45);
+  check(1,2,false,1,46);
+  { partial diacritical mark }
+  check(1,2,true,0,47);
+  check(1,3,false,1,48);
+  { complete diacritical mark }
+  check(1,3,true,3,49);
+  check(1,4,false,1,50);
+  { complete diacritical mark (ignore extra character) }
+  check(1,4,true,3,51);
+  { start of combining diacritical mark -- treated as independent utf-8 codepoint }
+  check(2,1,false,0,52);
+  check(2,1,true,0,53);
+  check(2,3,false,2,54);
+  check(2,3,true,2,55);
+  { middle of the combining diacritical mark }
+  check(3,1,false,-1,56);
+  check(3,1,true,-1,57);
+  check(3,4,false,-1,58);
+  check(3,4,true,-1,59);
+  { corrupt diacritical mark = no diacritical mark }
+  name[3]:=name[4];
+  { partial diacritical mark (the corrupted byte is not included in the
+    lookahead) }
+  check(1,2,true,0,60);
+  check(1,3,false,1,61);
+  { ignore corrupt diacritical mark }
+  check(1,3,true,1,62);
+  check(1,4,false,1,63);
+  check(1,4,true,1,64);
+  { e + combining circle + combining superscript 'n' }
+  name:='e'#$20DD#$1DE0'b';
+  { partial diacritical mark }
+  check(1,2,true,0,65);
+  check(1,3,false,1,66);
+  check(1,3,true,0,67);
+  check(1,4,false,1,68);
+  { complete diacritical mark }
+  check(1,4,true,4,69);
+  check(1,4,false,1,70);
+  { partial second diacritical mark }
+  check(1,5,true,0,71);
+  check(1,5,false,1,72);
+  check(1,6,true,0,73);
+  check(1,6,false,1,74);
+  { complete both diacritical marks }
+  check(1,7,true,7,75);
+  check(1,7,false,1,76);
+  check(1,10,true,7,77);
+  check(1,10,false,1,78);
+  { complete both diacritical marks without first character }
+  check(2,6,true,6,79);
+  check(2,20,true,6,80);
+  { only the first one, treated as independent codepoint }
+  check(2,7,false,3,81);
+  { corrupt second diacritical mark }
+  name[7]:=name[8];
+  { partial second diacritical mark }
+  check(1,5,true,0,82);
+  check(1,5,false,1,83);
+  check(1,6,true,0,84);
+  check(1,6,false,1,85);
+  { including bad byte -> ignore second diacritical mark completely
+    (can't know it's part of a diacritical mark or something else) }
+  check(1,7,true,4,86);
+  check(1,7,false,1,87);
+  { complete both diacritical marks without first character,
+    but with corrupted byte }
+  check(2,7,true,3,88);
+  check(2,20,true,3,89);
+  { corrupted diacritical mark by itself }
+  { 1) incomplete }
+  check(5,1,false,0,90);
+  check(5,1,true,0,91);
+  check(5,2,false,0,92);
+  check(5,2,true,0,93);
+  { 2) invalid }
+  check(5,3,false,-2,94);
+  check(5,3,true,-2,95);
+end.

+ 0 - 3
utils/fpdoc/dglobals.pp

@@ -475,9 +475,6 @@ begin
       LastChild := Child;
       LastChild := Child;
       Child := Child.NextSibling;
       Child := Child.NextSibling;
     end;
     end;
-    { No child found, let's create one if we are at the end of the path }
-    if DotPos > 0 then
-      Raise Exception.CreateFmt('Link path does not exist: %s',[APathName]);
     Result := TLinkNode.Create(ChildName, ALinkTo);
     Result := TLinkNode.Create(ChildName, ALinkTo);
     if Assigned(LastChild) then
     if Assigned(LastChild) then
       LastChild.FNextSibling := Result
       LastChild.FNextSibling := Result

+ 1 - 1
utils/fpdoc/fpdoc.pp

@@ -284,7 +284,7 @@ begin
   else if s = '--warn-no-node' then
   else if s = '--warn-no-node' then
     FCreator.Options.WarnNoNode := True
     FCreator.Options.WarnNoNode := True
   else if s = '--show-private' then
   else if s = '--show-private' then
-    FCreator.Options.ShowPrivate := False
+    FCreator.Options.ShowPrivate := True
   else if s = '--stop-on-parser-error' then
   else if s = '--stop-on-parser-error' then
     FCreator.Options.StopOnParseError := True
     FCreator.Options.StopOnParseError := True
   else if s = '--dont-trim' then
   else if s = '--dont-trim' then

+ 2 - 0
utils/fpdoc/unitdiff.pp

@@ -12,6 +12,8 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 }
 }
 
 
+{$mode objfpc}
+{$h+}
 
 
 program unitdiff;
 program unitdiff;
 
 

+ 49 - 13
utils/fppkg/lnet/lcontrolstack.pp

@@ -37,15 +37,18 @@ type
    private
    private
     FItems: array of Char;
     FItems: array of Char;
     FIndex: Byte;
     FIndex: Byte;
+    FAllowInflation: Boolean;
     FOnFull: TLOnFull;
     FOnFull: TLOnFull;
     function GetFull: Boolean;
     function GetFull: Boolean;
     function GetItem(const i: Byte): Char;
     function GetItem(const i: Byte): Char;
     procedure SetItem(const i: Byte; const Value: Char);
     procedure SetItem(const i: Byte; const Value: Char);
+    procedure SetAllowInflation(const b: boolean);
    public
    public
     constructor Create;
     constructor Create;
     procedure Clear;
     procedure Clear;
     procedure Push(const Value: Char);
     procedure Push(const Value: Char);
     property ItemIndex: Byte read FIndex;
     property ItemIndex: Byte read FIndex;
+    property AllowInflation: Boolean read FAllowInflation write SetAllowInflation;
     property Items[i: Byte]: Char read GetItem write SetItem; default;
     property Items[i: Byte]: Char read GetItem write SetItem; default;
     property Full: Boolean read GetFull;
     property Full: Boolean read GetFull;
     property OnFull: TLOnFull read FOnFull write FOnFull;
     property OnFull: TLOnFull read FOnFull write FOnFull;
@@ -55,47 +58,80 @@ implementation
 
 
 uses
 uses
   lTelnet;
   lTelnet;
+
+(* The normal situation is that there are up to TL_CSLENGTH items on the stack. *)
+(* However this may be relaxed in cases (assumed to be rare) where subcommand   *)
+(* parameters are being accumulated.                                            *)
   
   
 constructor TLControlStack.Create;
 constructor TLControlStack.Create;
 begin
 begin
   FOnFull:=nil;
   FOnFull:=nil;
-  FIndex:=0;
+  FIndex:=0;                            (* Next insertion point, [0] when empty *)
+  FAllowInflation := false;
   SetLength(FItems, TL_CSLENGTH);
   SetLength(FItems, TL_CSLENGTH);
 end;
 end;
 
 
 function TLControlStack.GetFull: Boolean;
 function TLControlStack.GetFull: Boolean;
 begin
 begin
-  Result:=False;
-  if FIndex >= TL_CSLENGTH then
-    Result:=True;
+  Result:=False;                        (* It's full when it has a complete     *)
+  if FIndex >= TL_CSLENGTH then         (* command, irrespective of whether the *)
+    Result:=True;                       (* stack's inflated by a subcommand.    *)
 end;
 end;
 
 
 function TLControlStack.GetItem(const i: Byte): Char;
 function TLControlStack.GetItem(const i: Byte): Char;
 begin
 begin
   Result:=TS_NOP;
   Result:=TS_NOP;
-  if i < TL_CSLENGTH then
-    Result:=FItems[i];
+  if not FAllowInflation then begin
+    if i < TL_CSLENGTH then
+      Result:=FItems[i]
+  end else
+    if i < Length(FItems) then
+      Result:=FItems[i]
 end;
 end;
 
 
 procedure TLControlStack.SetItem(const i: Byte; const Value: Char);
 procedure TLControlStack.SetItem(const i: Byte; const Value: Char);
 begin
 begin
-  if i < TL_CSLENGTH then
-    FItems[i]:=Value;
+  if not FAllowInflation then begin
+    if i < TL_CSLENGTH then
+      FItems[i]:=Value
+  end else begin
+    while i >= Length(FItems) do begin
+      SetLength(FItems, Length(FItems) + 1);
+      FItems[Length(FItems) - 1] := TS_NOP
+    end;
+    FItems[i] := Value
+  end
+end;
+
+procedure TLControlStack.SetAllowInflation(const b: boolean);
+
+begin
+  FAllowInflation := b;
+  if not b then                         (* No more funny stuff please           *)
+    Clear
 end;
 end;
 
 
 procedure TLControlStack.Clear;
 procedure TLControlStack.Clear;
 begin
 begin
   FIndex:=0;
   FIndex:=0;
+  FAllowInflation := false;
+  SetLength(FItems, TL_CSLENGTH)        (* In case inflation was allowed        *)
 end;
 end;
 
 
 procedure TLControlStack.Push(const Value: Char);
 procedure TLControlStack.Push(const Value: Char);
 begin
 begin
-  if FIndex < TL_CSLENGTH then begin
-    FItems[FIndex]:=Value;
-    Inc(FIndex);
-    if Full and Assigned(FOnFull) then
-      FOnFull;
+  if not FAllowInflation then
+    if FIndex < TL_CSLENGTH then begin
+      FItems[FIndex]:=Value;
+      Inc(FIndex)
+    end else begin end
+  else begin
+    SetLength(FItems, Length(FItems) + 1);
+    FItems[Length(FItems) - 1] := Value;
+    FIndex := Length(FItems)
   end;
   end;
+  if Full and Assigned(FOnFull) then
+    FOnFull;
 end;
 end;
 
 
 end.
 end.

+ 3 - 2
utils/fppkg/lnet/lftp.pp

@@ -106,7 +106,7 @@ type
   
   
   TLFTPTelnetClient = class(TLTelnetClient)
   TLFTPTelnetClient = class(TLTelnetClient)
    protected
    protected
-    procedure React(const Operation, Command: Char); override;
+    function React(const Operation, Command: Char):boolean; override;
   end;
   end;
 
 
   { TLFTPClient }
   { TLFTPClient }
@@ -368,8 +368,9 @@ end;
 
 
 { TLFTPTelnetClient }
 { TLFTPTelnetClient }
 
 
-procedure TLFTPTelnetClient.React(const Operation, Command: Char);
+function TLFTPTelnetClient.React(const Operation, Command: Char):boolean;
 begin
 begin
+  result:=false;
   // don't do a FUCK since they broke Telnet in FTP as per-usual
   // don't do a FUCK since they broke Telnet in FTP as per-usual
 end;
 end;
 
 

+ 64 - 20
utils/fppkg/lnet/ltelnet.pp

@@ -27,7 +27,7 @@ unit lTelnet;
 interface
 interface
 
 
 uses
 uses
-  Classes, lNet, lControlStack;
+  Classes, SysUtils, lNet, lControlStack;
   
   
 const
 const
   // Telnet printer signals
   // Telnet printer signals
@@ -72,9 +72,11 @@ type
   TLSubcommandCallback= function(command: char; const parameters, defaultResponse: string): string;
   TLSubcommandCallback= function(command: char; const parameters, defaultResponse: string): string;
   TLSubcommandEntry= record
   TLSubcommandEntry= record
                        callback: TLSubcommandCallback;
                        callback: TLSubcommandCallback;
-                       defaultResponse: string
+                       defaultResponse: string;
+                       requiredParams: integer
                      end;
                      end;
   TLSubcommandArray= array[#$00..#$ff] of TLSubcommandEntry;
   TLSubcommandArray= array[#$00..#$ff] of TLSubcommandEntry;
+  EInsufficientSubcommandParameters= class(Exception);
 
 
   { TLTelnet }
   { TLTelnet }
 
 
@@ -117,7 +119,7 @@ type
     procedure StackFull;
     procedure StackFull;
     procedure DoubleIAC(var s: string);
     procedure DoubleIAC(var s: string);
     function TelnetParse(const msg: string): Integer;
     function TelnetParse(const msg: string): Integer;
-    procedure React(const Operation, Command: Char); virtual; abstract;
+    function React(const Operation, Command: Char): boolean; virtual; abstract;
     procedure SendCommand(const Command: Char; const Value: Boolean); virtual; abstract;
     procedure SendCommand(const Command: Char; const Value: Boolean); virtual; abstract;
 
 
     procedure OnCs(aSocket: TLSocket);
     procedure OnCs(aSocket: TLSocket);
@@ -136,7 +138,8 @@ type
     procedure SetOption(const Option: Char);
     procedure SetOption(const Option: Char);
     procedure UnSetOption(const Option: Char);
     procedure UnSetOption(const Option: Char);
 
 
-    function RegisterSubcommand(aOption: char; callback: TLSubcommandCallback; const defaultResponse: string= ''): boolean;
+    function RegisterSubcommand(aOption: char; callback: TLSubcommandCallback;
+                const defaultResponse: string= ''; requiredParams: integer= 0): boolean;
 
 
     procedure Disconnect(const Forced: Boolean = True); override;
     procedure Disconnect(const Forced: Boolean = True); override;
     
     
@@ -164,7 +167,7 @@ type
     procedure OnRe(aSocket: TLSocket);
     procedure OnRe(aSocket: TLSocket);
     procedure OnCo(aSocket: TLSocket);
     procedure OnCo(aSocket: TLSocket);
 
 
-    procedure React(const Operation, Command: Char); override;
+    function React(const Operation, Command: Char): boolean; override;
     
     
     procedure SendCommand(const Command: Char; const Value: Boolean); override;
     procedure SendCommand(const Command: Char; const Value: Boolean); override;
    public
    public
@@ -190,7 +193,9 @@ function LTelnetSubcommandCallback(command: char; const parameters, defaultRespo
 implementation
 implementation
 
 
 uses
 uses
-  SysUtils, Math;
+  Math;
+
+const   subcommandEndLength= 2;
 
 
 var
 var
   zz: Char;
   zz: Char;
@@ -306,8 +311,10 @@ begin
     begin
     begin
       FOutput.WriteByte(Byte(FStack[1]));
       FOutput.WriteByte(Byte(FStack[1]));
       FOutput.WriteByte(Byte(FStack[2]));
       FOutput.WriteByte(Byte(FStack[2]));
-    end else React(FStack[1], FStack[2]);
-  FStack.Clear;
+      FStack.Clear
+    end else
+      if React(FStack[1], FStack[2]) then
+        FStack.Clear
 end;
 end;
 
 
 procedure TLTelnet.DoubleIAC(var s: string);
 procedure TLTelnet.DoubleIAC(var s: string);
@@ -394,15 +401,22 @@ end;
 
 
 (* If already set, the callback can be reverted to nil but it can't be changed  *)
 (* If already set, the callback can be reverted to nil but it can't be changed  *)
 (* in a single step. The default response, if specified, is used by the         *)
 (* in a single step. The default response, if specified, is used by the         *)
-(* LTelnetSubcommandCallback() function and is available to others.             *)
+(* LTelnetSubcommandCallback() function and is available to others; the         *)
+(* callback will not be invoked until there is at least the indicated number of *)
+(* parameter bytes available.                                                   *)
 //
 //
-function TLTelnet.RegisterSubcommand(aOption: char; callback: TLSubcommandCallback; const defaultResponse: string= ''): boolean;
+function TLTelnet.RegisterSubcommand(aOption: char; callback: TLSubcommandCallback;
+            const defaultResponse: string= ''; requiredParams: integer= 0): boolean;
 
 
 begin
 begin
   result := (not Assigned(FSubcommandCallbacks[aOption].callback)) or (@callback = nil);
   result := (not Assigned(FSubcommandCallbacks[aOption].callback)) or (@callback = nil);
   if result then begin
   if result then begin
     FSubcommandCallbacks[aOption].callback := callback;
     FSubcommandCallbacks[aOption].callback := callback;
-    FSubcommandCallbacks[aOption].defaultResponse := defaultResponse
+    FSubcommandCallbacks[aOption].defaultResponse := defaultResponse;
+    Inc(requiredParams, subcommandEndLength);
+    if requiredParams < 0 then          (* Assume -subcommandEndLength is a     *)
+      requiredParams := 0;              (* valid parameter.                     *)
+    FSubcommandCallbacks[aOption].requiredParams := requiredParams;
   end
   end
 end { TLTelnet.RegisterSubcommand } ;
 end { TLTelnet.RegisterSubcommand } ;
 
 
@@ -464,7 +478,7 @@ begin
     FOnConnect(aSocket);
     FOnConnect(aSocket);
 end;
 end;
 
 
-procedure TLTelnetClient.React(const Operation, Command: Char);
+function TLTelnetClient.React(const Operation, Command: Char): boolean;
 
 
   procedure Accept(const Operation, Command: Char);
   procedure Accept(const Operation, Command: Char);
   begin
   begin
@@ -487,17 +501,28 @@ procedure TLTelnetClient.React(const Operation, Command: Char);
   end;
   end;
 
 
 (* Retrieve the parameters from the current instance, and pass them explicitly  *)
 (* Retrieve the parameters from the current instance, and pass them explicitly  *)
-(* to the callback.                                                             *)
+(* to the callback. Return false if there are insufficient parameters on the    *)
+(* stack.                                                                       *)
 //
 //
-  procedure subcommand(command: char);
+  function subcommand(command: char): boolean;
 
 
   var   parameters, response: string;
   var   parameters, response: string;
         i: integer;
         i: integer;
 
 
   begin
   begin
-    if FStack.ItemIndex > 5 then begin
-      SetLength(parameters, FStack.ItemIndex - 5);
-      Move(FStack[3], parameters[1], FStack.ItemIndex - 5);
+    FStack.AllowInflation := true;      (* We might need more than the standard *)
+    if FStack.ItemIndex > 65536 then    (* command, but protect against parse   *)
+      {%H- 6018 } exit(true);           (* failure which could be a DoS attack. *)
+    i := FStack.ItemIndex - TL_CSLENGTH; (* Number of parameter bytes available.*)
+    if i < FSubcommandCallbacks[command].requiredParams then
+      exit(false);                      (* Early insufficient-parameters decision *)
+    result := true;
+    if FStack.ItemIndex > TL_CSLENGTH then begin
+      SetLength(parameters, FStack.ItemIndex - TL_CSLENGTH );
+      Move(FStack[3], parameters[1], FStack.ItemIndex - TL_CSLENGTH );
+      if (Length(parameters) >= 2) and (parameters[Length(parameters)] = TS_IAC) and
+                                (parameters[Length(parameters) - 1] <> TS_IAC) then
+        exit(false);                    (* Special case: need at least one more *)
       i := 1;
       i := 1;
       while i <= Length(parameters) - 1 do      (* Undouble IACs                *)
       while i <= Length(parameters) - 1 do      (* Undouble IACs                *)
         if (parameters[i] = TS_IAC) and (parameters[i + 1] = TS_IAC) then
         if (parameters[i] = TS_IAC) and (parameters[i + 1] = TS_IAC) then
@@ -506,13 +531,27 @@ procedure TLTelnetClient.React(const Operation, Command: Char);
           Inc(i)
           Inc(i)
     end else
     end else
       parameters := '';
       parameters := '';
-    response := FSubcommandCallbacks[command].callback(command, parameters, FSubcommandCallbacks[command].defaultResponse);
+    if Length(parameters) < FSubcommandCallbacks[command].requiredParams then
+      exit(false);                      (* Insufficient params after IAC undouble *)
+    if (FSubcommandCallbacks[command].requiredParams >= subcommandEndLength) and
+                                (Length(parameters) >= subcommandEndLength) then
+      SetLength(parameters, Length(parameters) - subcommandEndLength);
+    try
+      response := FSubcommandCallbacks[command].callback(command, parameters,
+                                FSubcommandCallbacks[command].defaultResponse)
+    except
+      on e: EInsufficientSubcommandParameters do
+        Exit(false)                     (* Late insufficient-parameters decision *)
+      else
+        Raise                           (* Application-specific error           *)
+    end;
     DoubleIAC(response);
     DoubleIAC(response);
     AddToBuffer(TS_IAC + TS_SB + command + response + TS_IAC + TS_SE);
     AddToBuffer(TS_IAC + TS_SB + command + response + TS_IAC + TS_SE);
     OnCs(nil)
     OnCs(nil)
   end { subcommand } ;
   end { subcommand } ;
 
 
 begin
 begin
+  result := true;                       (* Stack will normally be cleared       *)
   {$ifdef debug}
   {$ifdef debug}
   Writeln('**GOT** ', TNames[Operation], ' ', TNames[Command]);
   Writeln('**GOT** ', TNames[Operation], ' ', TNames[Command]);
   {$endif}
   {$endif}
@@ -529,7 +568,12 @@ begin
     TS_SB   : if not Assigned(FSubcommandCallbacks[command].callback) then
     TS_SB   : if not Assigned(FSubcommandCallbacks[command].callback) then
                 refuse(TS_WONT, command)
                 refuse(TS_WONT, command)
               else
               else
-                subcommand(command)
+                result := subcommand(command)
+
+(* In the final case above, the stack will not be cleared if sufficient         *)
+(* parameters to keep the subcommand happy have not yet been parsed out of the  *)
+(* message.                                                                     *)
+
   end;
   end;
 end;
 end;
 
 
@@ -559,7 +603,7 @@ end;
 
 
 function TLTelnetClient.Get(out aData; const aSize: Integer; aSocket: TLSocket): Integer;
 function TLTelnetClient.Get(out aData; const aSize: Integer; aSocket: TLSocket): Integer;
 begin
 begin
-  Result := FOutput.Read(aData, aSize);
+  Result := FOutput.Read(aData {%H- 5058 } , aSize);
   if FOutput.Position = FOutput.Size then
   if FOutput.Position = FOutput.Size then
     FOutput.Clear;
     FOutput.Clear;
 end;
 end;

+ 2 - 2
utils/h2pas/h2pas.pas

@@ -4,7 +4,7 @@
 (* global definitions: *)
 (* global definitions: *)
 
 
 program h2pas;
 program h2pas;
-
+{$H+}
 (*
 (*
     Copyright (c) 1998-2000 by Florian Klaempfl
     Copyright (c) 1998-2000 by Florian Klaempfl
 
 
@@ -9392,4 +9392,4 @@ begin
   PTypeList.Free;
   PTypeList.Free;
   freedynlibproc.free;
   freedynlibproc.free;
   loaddynlibproc.free;
   loaddynlibproc.free;
-end.
+end.

+ 1 - 1
utils/h2pas/h2pas.y

@@ -1,6 +1,6 @@
 %{
 %{
 program h2pas;
 program h2pas;
-
+{$H+}
 (*
 (*
     Copyright (c) 1998-2000 by Florian Klaempfl
     Copyright (c) 1998-2000 by Florian Klaempfl
 
 

+ 13 - 17
utils/h2pas/h2plexlib.pas

@@ -1,6 +1,5 @@
-
 unit h2pLexLib;
 unit h2pLexLib;
-
+{$H+}
 (* Standard Lex library unit for TP Lex Version 3.0.
 (* Standard Lex library unit for TP Lex Version 3.0.
    2-11-91 AG *)
    2-11-91 AG *)
 
 
@@ -25,7 +24,8 @@ interface
 
 
 (* Variables:
 (* Variables:
 
 
-   The variable yytext contains the current match, yyleng its length.
+   The variable yytext contains the current match, yyleng(was removed because of
+   $H+) its length.
    The variable yyline contains the current input line, and yylineno and
    The variable yyline contains the current input line, and yylineno and
    yycolno denote the current input position (line, column). These values
    yycolno denote the current input position (line, column). These values
    are often used in giving error diagnostics (however, they will only be
    are often used in giving error diagnostics (however, they will only be
@@ -43,8 +43,6 @@ yyinput, yyoutput : Text;        (* input and output file *)
 yyline,yyprevline : String;      (* current and previous input line *)
 yyline,yyprevline : String;      (* current and previous input line *)
 yylineno, yycolno : Integer;     (* current input position *)
 yylineno, yycolno : Integer;     (* current input position *)
 yytext            : String;      (* matched text (should be considered r/o) *)
 yytext            : String;      (* matched text (should be considered r/o) *)
-yyleng            : Byte         (* length of matched text *)
-  absolute yytext;
 
 
 (* I/O routines:
 (* I/O routines:
 
 
@@ -256,14 +254,14 @@ yysstate, yylstate : Integer;
 yymatches          : Integer;
 yymatches          : Integer;
 yystack            : array [1..max_matches] of Integer;
 yystack            : array [1..max_matches] of Integer;
 yypos              : array [1..max_rules] of Integer;
 yypos              : array [1..max_rules] of Integer;
-yysleng            : Byte;
+yysleng            : Integer;
 
 
 (* Utilities: *)
 (* Utilities: *)
 
 
 procedure echo;
 procedure echo;
   var i : Integer;
   var i : Integer;
   begin
   begin
-    for i := 1 to yyleng do
+    for i := 1 to Length(yytext) do
       put_char(yytext[i])
       put_char(yytext[i])
   end(*echo*);
   end(*echo*);
 
 
@@ -275,16 +273,16 @@ procedure yymore;
 procedure yyless ( n : Integer );
 procedure yyless ( n : Integer );
   var i : Integer;
   var i : Integer;
   begin
   begin
-    for i := yyleng downto n+1 do
+    for i := Length(yytext) downto n+1 do
       unget_char(yytext[i]);
       unget_char(yytext[i]);
-    yyleng := n;
+    SetLength(yytext,n);
   end(*yyless*);
   end(*yyless*);
 
 
 procedure reject;
 procedure reject;
   var i : Integer;
   var i : Integer;
   begin
   begin
     yyreject := true;
     yyreject := true;
-    for i := yyleng+1 to yysleng do
+    for i := Length(yytext)+1 to yysleng do
       yytext := yytext+get_char;
       yytext := yytext+get_char;
     dec(yymatches);
     dec(yymatches);
   end(*reject*);
   end(*reject*);
@@ -333,16 +331,14 @@ procedure yynew;
 
 
 procedure yyscan;
 procedure yyscan;
   begin
   begin
-    if yyleng=255 then fatal('yytext overflow');
     yyactchar := get_char;
     yyactchar := get_char;
-    inc(yyleng);
-    yytext[yyleng] := yyactchar;
+    yytext:=yytext+yyactchar;
   end(*yyscan*);
   end(*yyscan*);
 
 
 procedure yymark ( n : Integer );
 procedure yymark ( n : Integer );
   begin
   begin
     if n>max_rules then fatal('too many rules');
     if n>max_rules then fatal('too many rules');
-    yypos[n] := yyleng;
+    yypos[n] := Length(yytext);
   end(*yymark*);
   end(*yymark*);
 
 
 procedure yymatch ( n : Integer );
 procedure yymatch ( n : Integer );
@@ -359,12 +355,12 @@ function yyfind ( var n : Integer ) : Boolean;
       dec(yymatches);
       dec(yymatches);
     if yymatches>0 then
     if yymatches>0 then
       begin
       begin
-        yysleng := yyleng;
+        yysleng := Length(yytext);
         n       := yystack[yymatches];
         n       := yystack[yymatches];
         yyless(yypos[n]);
         yyless(yypos[n]);
         yypos[n] := 0;
         yypos[n] := 0;
-        if yyleng>0 then
-          yylastchar := yytext[yyleng]
+        if Length(yytext)>0 then
+          yylastchar := yytext[Length(yytext)]
         else
         else
           yylastchar := #0;
           yylastchar := #0;
         yyfind := true;
         yyfind := true;

+ 3 - 1
utils/h2pas/h2poptions.pas

@@ -16,7 +16,9 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
  ****************************************************************************}
  ****************************************************************************}
+
 unit h2poptions;
 unit h2poptions;
+{$H+}
 interface
 interface
 
 
 const
 const
@@ -138,7 +140,7 @@ end;
 
 
 Procedure ProcessOptions;
 Procedure ProcessOptions;
 Var
 Var
-  cp : string;
+  cp : string[255];   {because of cp[3] indexing}
   I : longint;
   I : longint;
 
 
   Function GetNextParam (const Opt,Name : String) : string;
   Function GetNextParam (const Opt,Name : String) : string;

+ 1 - 1
utils/h2pas/h2pyacclib.pas

@@ -34,7 +34,7 @@ $History: YACCLIB.PAS $
 
 
 
 
 {$I-}
 {$I-}
-
+{$H+}
 unit h2pYaccLib;
 unit h2pYaccLib;
 
 
 (* Yacc Library Unit for TP Yacc Version 3.0, 6-17-91 AG *)
 (* Yacc Library Unit for TP Yacc Version 3.0, 6-17-91 AG *)

+ 1 - 0
utils/h2pas/scan.l

@@ -20,6 +20,7 @@
 
 
 
 
 unit scan;
 unit scan;
+{$H+}
 
 
   interface
   interface
 
 

+ 1 - 0
utils/h2pas/scan.pas

@@ -23,6 +23,7 @@
 
 
 
 
 unit scan;
 unit scan;
+{$H+}
 
 
   interface
   interface
 
 

+ 5 - 3
utils/pas2jni/readme.txt

@@ -1,9 +1,11 @@
 pas2jni - JNI bridge generator for Pascal.
 pas2jni - JNI bridge generator for Pascal.
 
 
-Copyright (c) 2013 by Yury Sidorov.
+Copyright (c) 2013-2015 by Yury Sidorov.
 
 
 The pas2jni utility generates a JNI (Java Native Interface) bridge for a Pascal code. Then the Pascal code (including classes and other advanced features) can be easily used in Java programs.
 The pas2jni utility generates a JNI (Java Native Interface) bridge for a Pascal code. Then the Pascal code (including classes and other advanced features) can be easily used in Java programs.
 
 
+The pas2jni wiki page is available here: http://wiki.freepascal.org/pas2jni
+
 For example you can do the following in Java:
 For example you can do the following in Java:
 
 
 import pas.classes.*;
 import pas.classes.*;
@@ -31,7 +33,7 @@ The following Pascal features are supported by pas2jni:
 - pointer type;
 - pointer type;
 - string types;
 - string types;
 - all numeric types;
 - all numeric types;
-- method poiner.
+- method pointer.
 
 
 USUPPORTED features:
 USUPPORTED features:
 - array;
 - array;
@@ -51,7 +53,7 @@ pas2jni myunit -U/path/to/my/units;/path/to/FPC/units/*
 
 
 Here you specify myunit as the main unit and provide path to your compiled units and FPC compiled units. 
 Here you specify myunit as the main unit and provide path to your compiled units and FPC compiled units. 
 
 
-After successfull run of pas2jni you will get the following output files:
+After successful run of pas2jni you will get the following output files:
 - file "myunitjni.pas" - a generated library unit to be compiled to a shared library. It will contain all your Pascal code to be used from Java.
 - file "myunitjni.pas" - a generated library unit to be compiled to a shared library. It will contain all your Pascal code to be used from Java.
 - folder "pas" - generated Java package "pas" to be used in your Java program. Interface to each Pascal unit is placed to a separate Java public class. 
 - folder "pas" - generated Java package "pas" to be used in your Java program. Interface to each Pascal unit is placed to a separate Java public class. 
 
 

+ 16 - 5
utils/tply/README.txt

@@ -16,7 +16,7 @@ available from the TPLY homepage:
 
 
 For information about the Free Pascal Compiler, please refer to:
 For information about the Free Pascal Compiler, please refer to:
 
 
-	http://tfdec1.fys.kuleuven.ac.be/~michael/fpc/fpc.html
+	http://www.freepascal.org/
 
 
 The manual can be found in the files tply.tex (TeX version) and tply.doc
 The manual can be found in the files tply.tex (TeX version) and tply.doc
 (ASCII version) contained in the package. An extended version of the manual
 (ASCII version) contained in the package. An extended version of the manual
@@ -44,7 +44,7 @@ The original version of the TPLY package was written by Albert Graef
 4.0-6.0. Berend de Boer <[email protected]>, the current maintainer of the
 4.0-6.0. Berend de Boer <[email protected]>, the current maintainer of the
 Turbo/Borland Pascal version, adapted TPLY to take advantage of the large
 Turbo/Borland Pascal version, adapted TPLY to take advantage of the large
 memory models in Borland Pascal 7.0 and Delphi. Michael Van Canneyt
 memory models in Borland Pascal 7.0 and Delphi. Michael Van Canneyt
-<[email protected]>, who maintains the Linux version of
+<[email protected]>, who maintains the Linux version of
 the Free Pascal compiler, is the author of the Free Pascal port.
 the Free Pascal compiler, is the author of the Free Pascal port.
 
 
 
 
@@ -77,10 +77,9 @@ to store things :-) The 16-bit DPMI platforms have tables extended as large as
 possible without changing basic Lex or Yacc sources.
 possible without changing basic Lex or Yacc sources.
 
 
 This version was ported to Free Pascal by Michael Van Canneyt
 This version was ported to Free Pascal by Michael Van Canneyt
-<[email protected]> (April 1998).
+<[email protected]> (April 1998).
 
 
-*** Version 4.1		Michael Van Canneyt
-			<[email protected]>
+*** Version 4.1		Michael Van Canneyt <[email protected]>
 			Albert Graef <[email protected]>
 			Albert Graef <[email protected]>
 
 
 May 1998. Merges the Turbo and Free Pascal versions into a single package.
 May 1998. Merges the Turbo and Free Pascal versions into a single package.
@@ -142,6 +141,18 @@ from the lex.pas and yacc.pas programs), the Lex and Yacc code templates
 (*.cod files), and the LexLib and YaccLib library units (compiled from
 (*.cod files), and the LexLib and YaccLib library units (compiled from
 lexlib.pas and yacclib.pas).
 lexlib.pas and yacclib.pas).
 
 
+The plex and pyacc programs will look for the *.cod files in the following locations:
+For unix-like operating systems:
+1. Current directory.
+2. Directory given by FPCDIR
+3. Directory /usr/local/lib/fpc/lexyacc
+4. Directory /usr/lib/fpc/lexyacc
+
+For other operating systems (dos/windows-like) : 
+1. Current directory.
+2. Directory given by FPCDIR 
+3. Directory where the executable is located.
+
 For the Free Pascal/Linux version, a Makefile is provided. To install, issue
 For the Free Pascal/Linux version, a Makefile is provided. To install, issue
 the command `make' (maybe you have to edit the Makefile before this to reflect
 the command `make' (maybe you have to edit the Makefile before this to reflect
 your setup) and then `make install'. Note that in the Linux version the
 your setup) and then `make install'. Note that in the Linux version the

+ 2 - 1
utils/tply/lexbase.pas

@@ -65,7 +65,8 @@ lfilename     : String;
 pasfilename   : String;
 pasfilename   : String;
 lstfilename   : String;
 lstfilename   : String;
 codfilename   : String;
 codfilename   : String;
-codfilepath   : String; { Under linux, binary and conf file
+codfilepath1,
+codfilepath2  : String; { Under linux, binary and conf file
                           are not in the same path}
                           are not in the same path}
 
 
 (* Lex input, output, list and code template file: *)
 (* Lex input, output, list and code template file: *)

+ 22 - 11
utils/tply/plex.pas

@@ -62,7 +62,7 @@ $History: LEX.PAS $
 program Lex;
 program Lex;
 
 
 uses
 uses
-  LexBase, LexTable, LexPos, LexDFA, LexOpt, LexList, LexRules, LexMsgs;
+  LexBase, LexTable, LexPos, LexDFA, LexOpt, LexList, LexRules, LexMsgs, SysUtils;
 
 
 
 
 procedure get_line;
 procedure get_line;
@@ -597,15 +597,14 @@ var i : Integer;
 
 
 begin
 begin
 {$ifdef Unix}
 {$ifdef Unix}
- {$ifdef BSD}
-  codfilepath:='/usr/local/lib/fpc/lexyacc/';
- {$else}
-  codfilepath:='/usr/lib/fpc/lexyacc/';
- {$endif}
+  codfilepath1:='/usr/local/lib/fpc/lexyacc/';
+  codfilepath2:='/usr/lib/fpc/lexyacc/';
 {$else}
 {$else}
-  codfilepath:=path(paramstr(0));
+  codfilepath1:=path(paramstr(0));
+  codfilepath2:='';
 {$endif}
 {$endif}
 
 
+
   (* sign-on: *)
   (* sign-on: *)
 
 
   writeln(sign_on);
   writeln(sign_on);
@@ -662,17 +661,29 @@ begin
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
 
 
-  (* search code template in current directory, then on path where Lex
-     was executed from: *)
+  (* search code template *)
   codfilename := 'yylex.cod';
   codfilename := 'yylex.cod';
   assign(yycod, codfilename);
   assign(yycod, codfilename);
   reset(yycod);
   reset(yycod);
   if ioresult<>0 then
   if ioresult<>0 then
     begin
     begin
-      codfilename := codfilepath+'yylex.cod';
+      codfilename := IncludeTrailingPathDelimiter(GetEnvironmentVariable('FPCDIR'))+'lexyacc'+DirectorySeparator+'yylex.cod';
       assign(yycod, codfilename);
       assign(yycod, codfilename);
       reset(yycod);
       reset(yycod);
-      if ioresult<>0 then fatal(cannot_open_file+codfilename);
+      if ioresult<>0 then
+        begin
+          codfilename := codfilepath1+'yylex.cod';
+          assign(yycod, codfilename);
+          reset(yycod);
+          if (codfilepath2<>'') and (ioresult<>0) then 
+            begin
+              codfilename := codfilepath2+'yylex.cod';
+              assign(yycod, codfilename);
+              reset(yycod);
+              if ioresult<>0 then 
+                fatal(cannot_open_file+codfilename);
+            end;
+        end;
     end;
     end;
 
 
   (* parse source grammar: *)
   (* parse source grammar: *)

+ 96 - 86
utils/tply/pyacc.pas

@@ -36,7 +36,7 @@ Last changes:
     updates)
     updates)
 
 
 $History: YACC.PAS $
 $History: YACC.PAS $
- *
+ * 
  * *****************  Version 2  *****************
  * *****************  Version 2  *****************
  * User: Berend       Date: 96-10-10   Time: 21:16
  * User: Berend       Date: 96-10-10   Time: 21:16
  * Updated in $/Lex and Yacc/tply
  * Updated in $/Lex and Yacc/tply
@@ -110,7 +110,7 @@ uses
     YaccChk source not available anymore PM }
     YaccChk source not available anymore PM }
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
-  YaccLib, YaccBase, YaccMsgs, YaccSem, YaccTabl, YaccPars;
+  YaccLib, YaccBase, YaccMsgs, YaccSem, YaccTabl, YaccPars, SysUtils;
 
 
 const ID = 257;
 const ID = 257;
 const C_ID = 258;
 const C_ID = 258;
@@ -161,28 +161,28 @@ begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
    6 : begin
    6 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
    7 : begin
    7 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
    8 : begin
    8 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
    9 : begin
    9 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   10 : begin
   10 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   11 : begin
   11 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   12 : begin
   12 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   13 : begin
   13 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   14 : begin
   14 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
@@ -191,19 +191,19 @@ begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   16 : begin
   16 : begin
-         error(rcurl_expected);
+         error(rcurl_expected); 
        end;
        end;
   17 : begin
   17 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   18 : begin
   18 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   19 : begin
   19 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   20 : begin
   20 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   21 : begin
   21 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
@@ -212,7 +212,7 @@ begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   23 : begin
   23 : begin
-         error(rbrace_expected);
+         error(rbrace_expected); 
        end;
        end;
   24 : begin
   24 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
@@ -221,7 +221,7 @@ begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   26 : begin
   26 : begin
-         error(rangle_expected);
+         error(rangle_expected); 
        end;
        end;
   27 : begin
   27 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
@@ -229,12 +229,12 @@ begin
   28 : begin
   28 : begin
          sort_types;
          sort_types;
          definitions;
          definitions;
-         next_section;
+         next_section; 
        end;
        end;
   29 : begin
   29 : begin
          next_section;
          next_section;
          generate_parser;
          generate_parser;
-         next_section;
+         next_section; 
        end;
        end;
   30 : begin
   30 : begin
          yyval := yyv[yysp-5];
          yyval := yyv[yysp-5];
@@ -242,48 +242,48 @@ begin
   31 : begin
   31 : begin
        end;
        end;
   32 : begin
   32 : begin
-         copy_rest_of_file;
+         copy_rest_of_file; 
        end;
        end;
   33 : begin
   33 : begin
        end;
        end;
   34 : begin
   34 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   35 : begin
   35 : begin
-         error(error_in_def);
+         error(error_in_def); 
        end;
        end;
   36 : begin
   36 : begin
-         startnt := ntsym(yyv[yysp-0]);
+         startnt := ntsym(yyv[yysp-0]); 
        end;
        end;
   37 : begin
   37 : begin
-         error(ident_expected);
+         error(ident_expected); 
        end;
        end;
   38 : begin
   38 : begin
-         copy_code;
+         copy_code; 
        end;
        end;
   39 : begin
   39 : begin
          yyval := yyv[yysp-2];
          yyval := yyv[yysp-2];
        end;
        end;
   40 : begin
   40 : begin
-         act_prec := 0;
+         act_prec := 0; 
        end;
        end;
   41 : begin
   41 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
        end;
        end;
   42 : begin
   42 : begin
-         act_prec := new_prec_level(left);
+         act_prec := new_prec_level(left); 
        end;
        end;
   43 : begin
   43 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
        end;
        end;
   44 : begin
   44 : begin
-         act_prec := new_prec_level(right);
+         act_prec := new_prec_level(right); 
        end;
        end;
   45 : begin
   45 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
        end;
        end;
   46 : begin
   46 : begin
-         act_prec := new_prec_level(nonassoc);
+         act_prec := new_prec_level(nonassoc); 
        end;
        end;
   47 : begin
   47 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
@@ -295,169 +295,169 @@ begin
          yyval := yyv[yysp-1];
          yyval := yyv[yysp-1];
        end;
        end;
   50 : begin
   50 : begin
-         act_type := 0;
+         act_type := 0; 
        end;
        end;
   51 : begin
   51 : begin
-         act_type := yyv[yysp-1]; add_type(yyv[yysp-1]);
+         act_type := yyv[yysp-1]; add_type(yyv[yysp-1]); 
        end;
        end;
   52 : begin
   52 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   53 : begin
   53 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   54 : begin
   54 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   55 : begin
   55 : begin
-         error(ident_expected);
+         error(ident_expected); 
        end;
        end;
   56 : begin
   56 : begin
-         error(error_in_def);
+         error(error_in_def); 
        end;
        end;
   57 : begin
   57 : begin
-         error(ident_expected);
+         error(ident_expected); 
        end;
        end;
   58 : begin
   58 : begin
          if act_type<>0 then
          if act_type<>0 then
          sym_type^[yyv[yysp-0]] := act_type;
          sym_type^[yyv[yysp-0]] := act_type;
          if act_prec<>0 then
          if act_prec<>0 then
-         sym_prec^[yyv[yysp-0]] := act_prec;
+         sym_prec^[yyv[yysp-0]] := act_prec; 
        end;
        end;
   59 : begin
   59 : begin
          litsym(yyv[yysp-0], 0);
          litsym(yyv[yysp-0], 0);
          if act_type<>0 then
          if act_type<>0 then
          sym_type^[litsym(yyv[yysp-0], 0)] := act_type;
          sym_type^[litsym(yyv[yysp-0], 0)] := act_type;
          if act_prec<>0 then
          if act_prec<>0 then
-         sym_prec^[litsym(yyv[yysp-0], 0)] := act_prec;
+         sym_prec^[litsym(yyv[yysp-0], 0)] := act_prec; 
        end;
        end;
   60 : begin
   60 : begin
          litsym(yyv[yysp-0], 0);
          litsym(yyv[yysp-0], 0);
          if act_type<>0 then
          if act_type<>0 then
          sym_type^[litsym(yyv[yysp-0], 0)] := act_type;
          sym_type^[litsym(yyv[yysp-0], 0)] := act_type;
          if act_prec<>0 then
          if act_prec<>0 then
-         sym_prec^[litsym(yyv[yysp-0], 0)] := act_prec;
+         sym_prec^[litsym(yyv[yysp-0], 0)] := act_prec; 
        end;
        end;
   61 : begin
   61 : begin
          litsym(yyv[yysp-1], 0);
          litsym(yyv[yysp-1], 0);
          if act_type<>0 then
          if act_type<>0 then
          sym_type^[litsym(yyv[yysp-1], yyv[yysp-0])] := act_type;
          sym_type^[litsym(yyv[yysp-1], yyv[yysp-0])] := act_type;
          if act_prec<>0 then
          if act_prec<>0 then
-         sym_prec^[litsym(yyv[yysp-1], 0)]  := act_prec;
+         sym_prec^[litsym(yyv[yysp-1], 0)]  := act_prec; 
        end;
        end;
   62 : begin
   62 : begin
          litsym(yyv[yysp-1], 0);
          litsym(yyv[yysp-1], 0);
          if act_type<>0 then
          if act_type<>0 then
          sym_type^[litsym(yyv[yysp-1], yyv[yysp-0])] := act_type;
          sym_type^[litsym(yyv[yysp-1], yyv[yysp-0])] := act_type;
          if act_prec<>0 then
          if act_prec<>0 then
-         sym_prec^[litsym(yyv[yysp-1], 0)]  := act_prec;
+         sym_prec^[litsym(yyv[yysp-1], 0)]  := act_prec; 
        end;
        end;
   63 : begin
   63 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   64 : begin
   64 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   65 : begin
   65 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   66 : begin
   66 : begin
-         error(ident_expected);
+         error(ident_expected); 
        end;
        end;
   67 : begin
   67 : begin
-         error(error_in_def);
+         error(error_in_def); 
        end;
        end;
   68 : begin
   68 : begin
-         error(ident_expected);
+         error(ident_expected); 
        end;
        end;
   69 : begin
   69 : begin
          if act_type<>0 then
          if act_type<>0 then
-         sym_type^[ntsym(yyv[yysp-0])] := act_type;
+         sym_type^[ntsym(yyv[yysp-0])] := act_type; 
        end;
        end;
   70 : begin
   70 : begin
-         next_section;
+         next_section; 
        end;
        end;
   71 : begin
   71 : begin
          yyval := yyv[yysp-1];
          yyval := yyv[yysp-1];
        end;
        end;
   72 : begin
   72 : begin
-         copy_code;
+         copy_code; 
        end;
        end;
   73 : begin
   73 : begin
-         next_section;
+         next_section; 
        end;
        end;
   74 : begin
   74 : begin
          yyval := yyv[yysp-4];
          yyval := yyv[yysp-4];
        end;
        end;
   75 : begin
   75 : begin
-         yyerrok;
+         yyerrok; 
        end;
        end;
   76 : begin
   76 : begin
-         error(error_in_rule);
+         error(error_in_rule); 
        end;
        end;
   77 : begin
   77 : begin
-         error(error_in_rule);
+         error(error_in_rule); 
        end;
        end;
   78 : begin
   78 : begin
-         start_rule(ntsym(yyv[yysp-0]));
+         start_rule(ntsym(yyv[yysp-0])); 
        end;
        end;
   79 : begin
   79 : begin
-         start_body;
+         start_body; 
        end;
        end;
   80 : begin
   80 : begin
-         end_body;
+         end_body; 
        end;
        end;
   81 : begin
   81 : begin
          yyval := yyv[yysp-0];
          yyval := yyv[yysp-0];
        end;
        end;
   82 : begin
   82 : begin
-         start_body;
+         start_body; 
        end;
        end;
   83 : begin
   83 : begin
-         end_body;
+         end_body; 
        end;
        end;
   84 : begin
   84 : begin
        end;
        end;
   85 : begin
   85 : begin
-         add_symbol(yyv[yysp-0]); yyerrok;
+         add_symbol(yyv[yysp-0]); yyerrok; 
        end;
        end;
   86 : begin
   86 : begin
-         add_symbol(sym(yyv[yysp-0])); yyerrok;
+         add_symbol(sym(yyv[yysp-0])); yyerrok; 
        end;
        end;
   87 : begin
   87 : begin
-         add_symbol(sym(yyv[yysp-0])); yyerrok;
+         add_symbol(sym(yyv[yysp-0])); yyerrok; 
        end;
        end;
   88 : begin
   88 : begin
-         add_action; yyerrok;
+         add_action; yyerrok; 
        end;
        end;
   89 : begin
   89 : begin
-         error(error_in_rule);
+         error(error_in_rule); 
        end;
        end;
   90 : begin
   90 : begin
-         copy_action;
+         copy_action; 
        end;
        end;
   91 : begin
   91 : begin
          yyval := yyv[yysp-2];
          yyval := yyv[yysp-2];
        end;
        end;
   92 : begin
   92 : begin
-         copy_single_action;
+         copy_single_action; 
        end;
        end;
   93 : begin
   93 : begin
        end;
        end;
   94 : begin
   94 : begin
-         add_rule_prec(yyv[yysp-0]);
+         add_rule_prec(yyv[yysp-0]); 
        end;
        end;
   95 : begin
   95 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
        end;
        end;
   96 : begin
   96 : begin
-         add_rule_prec(litsym(yyv[yysp-0], 0));
+         add_rule_prec(litsym(yyv[yysp-0], 0)); 
        end;
        end;
   97 : begin
   97 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
        end;
        end;
   98 : begin
   98 : begin
-         add_rule_prec(litsym(yyv[yysp-0], 0));
+         add_rule_prec(litsym(yyv[yysp-0], 0)); 
        end;
        end;
   99 : begin
   99 : begin
          yyval := yyv[yysp-3];
          yyval := yyv[yysp-3];
@@ -468,7 +468,7 @@ begin
  101 : begin
  101 : begin
        end;
        end;
  102 : begin
  102 : begin
-         add_action;
+         add_action; 
        end;
        end;
   end;
   end;
 end(*yyaction*);
 end(*yyaction*);
@@ -2131,10 +2131,10 @@ function yylex : integer;
             ('0'<=line[cno]) and (line[cno]<='9') or
             ('0'<=line[cno]) and (line[cno]<='9') or
             (line[cno]='_') or
             (line[cno]='_') or
             (line[cno]='.') ) do
             (line[cno]='.') ) do
-        begin
-          idstr := idstr+line[cno];
-          inc(cno)
-        end;
+	begin
+	  idstr := idstr+line[cno];
+	  inc(cno)
+	end;
       yylval := get_key(idstr);
       yylval := get_key(idstr);
       scan;
       scan;
       if not end_of_input and (line[cno]=':') then
       if not end_of_input and (line[cno]=':') then
@@ -2352,9 +2352,9 @@ function yylex : integer;
     else
     else
       case line[cno] of
       case line[cno] of
         'A'..'Z', 'a'..'z', '_' : yylex := scan_ident;
         'A'..'Z', 'a'..'z', '_' : yylex := scan_ident;
-        '''', '"' : yylex := scan_literal;
-        '0'..'9' : yylex := scan_num;
-        '%', '\' : yylex := scan_keyword;
+	'''', '"' : yylex := scan_literal;
+	'0'..'9' : yylex := scan_num;
+	'%', '\' : yylex := scan_keyword;
         '=' :
         '=' :
           if (cno<length(line)) and (line[succ(cno)]='{') then
           if (cno<length(line)) and (line[succ(cno)]='{') then
             begin
             begin
@@ -2363,7 +2363,7 @@ function yylex : integer;
             end
             end
           else
           else
             yylex := scan_char;
             yylex := scan_char;
-        else yylex := scan_char;
+	else yylex := scan_char;
       end;
       end;
     if lno=lno0 then
     if lno=lno0 then
       tokleng := cno-cno0
       tokleng := cno-cno0
@@ -2375,13 +2375,11 @@ var i : Integer;
 
 
 begin
 begin
 {$ifdef Unix}
 {$ifdef Unix}
- {$ifdef BSD}
-  codfilepath:='/usr/local/lib/fpc/lexyacc/';
- {$else}
-  codfilepath:='/usr/lib/fpc/lexyacc/';
- {$endif}
+  codfilepath1:='/usr/local/lib/fpc/lexyacc/';
+  codfilepath2:='/usr/lib/fpc/lexyacc/';
 {$else}
 {$else}
-  codfilepath:=path(paramstr(0));
+  codfilepath1:=path(paramstr(0));
+  codfilepath2:='';
 {$endif}
 {$endif}
 
 
   (* sign-on: *)
   (* sign-on: *)
@@ -2440,17 +2438,29 @@ begin
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
 
 
-  (* search code template in current directory, then on path where Yacc
-     was executed from: *)
+  (* search code template *)
   codfilename := 'yyparse.cod';
   codfilename := 'yyparse.cod';
   assign(yycod, codfilename);
   assign(yycod, codfilename);
   reset(yycod);
   reset(yycod);
   if ioresult<>0 then
   if ioresult<>0 then
     begin
     begin
-      codfilename := codfilepath+'yyparse.cod';
+      codfilename := IncludeTrailingPathDelimiter(GetEnvironmentVariable('FPCDIR'))+'lexyacc'+DirectorySeparator+'yyparse.cod';
       assign(yycod, codfilename);
       assign(yycod, codfilename);
       reset(yycod);
       reset(yycod);
-      if ioresult<>0 then fatal(cannot_open_file+codfilename);
+      if ioresult<>0 then
+        begin
+          codfilename := codfilepath1+'yyparse.cod';
+          assign(yycod, codfilename);
+          reset(yycod);
+          if (codfilepath2<>'') and (ioresult<>0) then 
+            begin
+              codfilename := codfilepath2+'yyparse.cod';
+              assign(yycod, codfilename);
+              reset(yycod);
+              if ioresult<>0 then 
+                fatal(cannot_open_file+codfilename);
+            end;
+        end;
     end;
     end;
 
 
   (* parse source grammar: *)
   (* parse source grammar: *)
@@ -2513,4 +2523,4 @@ begin
 
 
   halt(errors);
   halt(errors);
 
 
-end(*Yacc*).
+end(*Yacc*).

+ 24 - 28
utils/tply/pyacc.y

@@ -55,7 +55,7 @@
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
 
 
-$Revision: 1.3 $
+$Revision: 1.5 $
 $Modtime: 96-08-01 11:24 $
 $Modtime: 96-08-01 11:24 $
 
 
 
 
@@ -129,16 +129,6 @@ $History: YACC.PAS $
 
 
 *)
 *)
 
 
-{$IFDEF MsDos}
-{$M 16384,0,655360}
-{$ENDIF}
-{$IFDEF DPMI}
-{$M 32768}
-{$ENDIF}
-{$IFDEF Windows}
-{$M 32768,0}
-{$ENDIF}
-
 {$X+}
 {$X+}
 {$I-}
 {$I-}
 program Yacc;
 program Yacc;
@@ -146,15 +136,11 @@ program Yacc;
 uses
 uses
 {$IFDEF Debug}
 {$IFDEF Debug}
 {$IFDEF DPMI}
 {$IFDEF DPMI}
-  YaccChk,
-{$ENDIF}
+  { YaccChk, removed as obsolete,
+    YaccChk source not available anymore PM }
 {$ENDIF}
 {$ENDIF}
-{$IFDEF Windows}
-{$IFNDEF Console}
-  WinCrt,
 {$ENDIF}
 {$ENDIF}
-{$ENDIF}
-  YaccLib, YaccBase, YaccMsgs, YaccSem, YaccTabl, YaccPars;
+  YaccLib, YaccBase, YaccMsgs, YaccSem, YaccTabl, YaccPars, SysUtils;
 
 
 %}
 %}
 
 
@@ -725,13 +711,11 @@ var i : Integer;
 
 
 begin
 begin
 {$ifdef Unix}
 {$ifdef Unix}
- {$ifdef BSD}
-  codfilepath:='/usr/local/lib/fpc/lexyacc/';
- {$else}
-  codfilepath:='/usr/lib/fpc/lexyacc/';
- {$endif}
+  codfilepath1:='/usr/local/lib/fpc/lexyacc/';
+  codfilepath2:='/usr/lib/fpc/lexyacc/';
 {$else}
 {$else}
-  codfilepath:=path(paramstr(0));
+  codfilepath1:=path(paramstr(0));
+  codfilepath2:='';
 {$endif}
 {$endif}
 
 
   (* sign-on: *)
   (* sign-on: *)
@@ -790,17 +774,29 @@ begin
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yyout); if ioresult<>0 then fatal(cannot_open_file+pasfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
   rewrite(yylst); if ioresult<>0 then fatal(cannot_open_file+lstfilename);
 
 
-  (* search code template in current directory, then on path where Yacc
-     was executed from: *)
+  (* search code template *)
   codfilename := 'yyparse.cod';
   codfilename := 'yyparse.cod';
   assign(yycod, codfilename);
   assign(yycod, codfilename);
   reset(yycod);
   reset(yycod);
   if ioresult<>0 then
   if ioresult<>0 then
     begin
     begin
-      codfilename := codfilepath+'yyparse.cod';
+      codfilename := IncludeTrailingPathDelimiter(GetEnvironmentVariable('FPCDIR'))+'lexyacc'+DirectorySeparator+'yyparse.cod';
       assign(yycod, codfilename);
       assign(yycod, codfilename);
       reset(yycod);
       reset(yycod);
-      if ioresult<>0 then fatal(cannot_open_file+codfilename);
+      if ioresult<>0 then
+        begin
+          codfilename := codfilepath1+'yyparse.cod';
+          assign(yycod, codfilename);
+          reset(yycod);
+          if (codfilepath2<>'') and (ioresult<>0) then 
+            begin
+              codfilename := codfilepath2+'yyparse.cod';
+              assign(yycod, codfilename);
+              reset(yycod);
+              if ioresult<>0 then 
+                fatal(cannot_open_file+codfilename);
+            end;
+        end;
     end;
     end;
 
 
   (* parse source grammar: *)
   (* parse source grammar: *)

+ 2 - 1
utils/tply/yaccbase.pas

@@ -66,7 +66,8 @@ yfilename     : String;
 pasfilename   : String;
 pasfilename   : String;
 lstfilename   : String;
 lstfilename   : String;
 codfilename   : String;
 codfilename   : String;
-codfilepath   : String; { Under Linux,
+codfilepath1,
+codfilepath2  : String; { Under Linux,
                           binary and conf file are never in 1 directory.}
                           binary and conf file are never in 1 directory.}
 
 
 (* Yacc input, output, list and code template file: *)
 (* Yacc input, output, list and code template file: *)