Browse Source

--- Merging r29567 into '.':
U packages/rtl-unicode/fpmake.pp
--- Merging r29568 into '.':
U utils/unicode/fpmake.pp
--- Merging r29571 into '.':
U rtl/os2/sysucode.inc
--- Merging r29572 into '.':
U rtl/os2/system.pas
U rtl/os2/sysos.inc
G rtl/os2/sysucode.inc
--- Merging r29573 into '.':
U compiler/systems/t_os2.pas
--- Merging r29618 into '.':
G utils/unicode/fpmake.pp
--- Merging r29620 into '.':
U installer/install.dat
--- Merging r29623 into '.':
U rtl/objpas/fpwidestring.pp
--- Merging r29625 into '.':
G rtl/os2/sysucode.inc
--- Merging r29629 into '.':
G rtl/os2/sysucode.inc
--- Merging r29630 into '.':
U packages/fcl-db/src/dbase/dbf_wos2.inc
--- Merging r29631 into '.':
G packages/fcl-db/src/dbase/dbf_wos2.inc
--- Merging r29632 into '.':
U packages/fcl-db/src/dbase/dbf_common.inc
U packages/fcl-db/src/dbase/dbf_common.pas

# revisions: 29567,29568,29571,29572,29573,29618,29620,29623,29625,29629,29630,29631,29632

git-svn-id: branches/fixes_3_0@29634 -

marco 10 years ago
parent
commit
c0fce5c7a6

+ 7 - 0
compiler/systems/t_os2.pas

@@ -473,6 +473,7 @@ var
   BaseFilename: TPathStr;
   BaseFilename: TPathStr;
   RsrcStr : string;
   RsrcStr : string;
   OutName: TPathStr;
   OutName: TPathStr;
+  StackSizeKB: cardinal;
 begin
 begin
   if not(cs_link_nolink in current_settings.globalswitches) then
   if not(cs_link_nolink in current_settings.globalswitches) then
    Message1(exec_i_linking,current_module.exefilename);
    Message1(exec_i_linking,current_module.exefilename);
@@ -513,6 +514,12 @@ begin
         { Is this really required? Not anymore according to my EMX docs }
         { Is this really required? Not anymore according to my EMX docs }
         Replace(cmdstr,'$HEAPMB',tostr((1048575) shr 20));
         Replace(cmdstr,'$HEAPMB',tostr((1048575) shr 20));
         {Size of the stack when an EMX program runs in OS/2.}
         {Size of the stack when an EMX program runs in OS/2.}
+        StackSizeKB := (StackSize + 1023) shr 10;
+        (* Ensure a value which might work and is accepted by EMXBIND *)
+        if StackSizeKB < 64 then
+         StackSizeKB := 64
+        else if StackSizeKB > (512 shl 10) then
+         StackSizeKB := 512 shl 10;
         Replace(cmdstr,'$STACKKB',tostr((stacksize+1023) shr 10));
         Replace(cmdstr,'$STACKKB',tostr((stacksize+1023) shr 10));
         {When an EMX program runs in DOS, the heap and stack share the
         {When an EMX program runs in DOS, the heap and stack share the
          same memory pool. The heap grows upwards, the stack grows downwards.}
          same memory pool. The heap grows upwards, the stack grows downwards.}

+ 8 - 0
installer/install.dat

@@ -278,6 +278,8 @@ package=units-rtl-extra.i386-win32.zip,RTL-additional units not needed for boots
 package=units-rtl-objpas.i386-win32.zip,RTL-Object Pascal units (e.g. Delphi compatibility)
 package=units-rtl-objpas.i386-win32.zip,RTL-Object Pascal units (e.g. Delphi compatibility)
 # Win32-2 38
 # Win32-2 38
 package=units-rtl-unicode.i386-win32.zip,RTL-miscellaneous Unicode support units
 package=units-rtl-unicode.i386-win32.zip,RTL-miscellaneous Unicode support units
+# Win32-2 39
+package=utils-unicode.i386-win32.zip,Transformation of Unicode consortium data for FPC
 
 
 #
 #
 # OS/2 packages
 # OS/2 packages
@@ -362,6 +364,8 @@ package=utils-rmwaitos2.zip[rmwos2.zip],Remove (delete) file(s) with optional re
 package=utils-lexyaccos2.zip[tplyos2.zip],Compiler generator for TP and compatibles
 package=utils-lexyaccos2.zip[tplyos2.zip],Compiler generator for TP and compatibles
 # OS/2 35
 # OS/2 35
 package=utils-fpcmos2.zip[fpcmos2.zip],Generate Makefiles out of Makefile.fpc files
 package=utils-fpcmos2.zip[fpcmos2.zip],Generate Makefiles out of Makefile.fpc files
+# OS/2 36
+package=utils-unicodeos2.zip[ucodeos2.zip],Transformation of Unicode consortium data for FPC
 
 
 #
 #
 # OS/2 packages 2nd part
 # OS/2 packages 2nd part
@@ -522,6 +526,8 @@ package=utils-rmwaitemx.zip[rmwemx.zip],Remove (delete) file(s) with optional re
 package=utils-lexyaccemx.zip[tplyemx.zip],Compiler generator for TP and compatibles
 package=utils-lexyaccemx.zip[tplyemx.zip],Compiler generator for TP and compatibles
 # EMX 36
 # EMX 36
 package=utils-fpcmemx.zip[fpcmemx.zip],Generate Makefiles out of Makefile.fpc files
 package=utils-fpcmemx.zip[fpcmemx.zip],Generate Makefiles out of Makefile.fpc files
+# EMX 37
+package=utils-unicodeemx.zip[ucodeemx.zip],Transformation of Unicode consortium data for FPC
 
 
 #
 #
 # EMX packages 2nd part
 # EMX packages 2nd part
@@ -681,6 +687,8 @@ package=utils-pas2ut.source.zip[p2utsrc.zip],Pascal source to FPC Unit test gene
 package=utils-rmwait.source.zip[rmwsrc.zip],Remove (delete) file(s) with optional retries
 package=utils-rmwait.source.zip[rmwsrc.zip],Remove (delete) file(s) with optional retries
 # Source 32
 # Source 32
 package=utils-lexyacc.source.zip[tplysrc.zip],Compiler generator for TP and compatibles
 package=utils-lexyacc.source.zip[tplysrc.zip],Compiler generator for TP and compatibles
+# Source 33
+package=utils-unicode.source.zip[ucodesrc.zip],Transformation of Unicode consortium data for FPC
 
 
 #
 #
 # Source packages 2nd part
 # Source packages 2nd part

+ 22 - 2
packages/fcl-db/src/dbase/dbf_common.inc

@@ -247,13 +247,33 @@
 //--- Conclude supported features in non-Windows platforms ---
 //--- Conclude supported features in non-Windows platforms ---
 //----------------------------------------------------------
 //----------------------------------------------------------
 
 
-{$ifndef WINDOWS}
+{$IFDEF WINDOWS}
+    {$DEFINE SUPPORT_DRIVES_AND_UNC}
+{$ELSE WINDOWS}
+ {$IFDEF LINUX}
+  {$IFNDEF UNIX}
+   {$DEFINE UNIX}
+  {$ENDIF UNIX}
+ {$ENDIF LINUX}
+
+ {$IFDEF OS2}
+    {$DEFINE SUPPORT_DRIVES_AND_UNC}
+ {$ENDIF OS2}
+ {$IFDEF GO32V2}
+    {$DEFINE SUPPORT_DRIVES_AND_UNC}
+ {$ENDIF GO32V2}
+ {$IFDEF WATCOM}
+    {$DEFINE SUPPORT_DRIVES_AND_UNC}
+ {$ENDIF WATCOM}
+ {$IFDEF MSDOS}
+    {$DEFINE SUPPORT_DRIVES_AND_UNC}
+ {$ENDIF MSDOS}
 
 
     {$define SUPPORT_PATHDELIM}
     {$define SUPPORT_PATHDELIM}
     {$define SUPPORT_INCLUDETRAILPATHDELIM}
     {$define SUPPORT_INCLUDETRAILPATHDELIM}
     {$define SUPPORT_INCLUDETRAILBACKSLASH}
     {$define SUPPORT_INCLUDETRAILBACKSLASH}
 
 
-{$endif}
+{$ENDIF WINDOWS}
 
 
 {$ifndef ENDIAN_LITTLE}
 {$ifndef ENDIAN_LITTLE}
 {$ifndef ENDIAN_BIG}
 {$ifndef ENDIAN_BIG}

+ 10 - 2
packages/fcl-db/src/dbase/dbf_common.pas

@@ -67,7 +67,11 @@ const
 {$ifdef WINDOWS}
 {$ifdef WINDOWS}
   PathDelim = '\';
   PathDelim = '\';
 {$else}
 {$else}
+ {$IFDEF UNIX}
   PathDelim = '/';
   PathDelim = '/';
+ {$ELSE UNIX}
+  PathDelim = '\';
+ {$ENDIF UNIX}
 {$endif}
 {$endif}
 {$endif}
 {$endif}
 
 
@@ -145,13 +149,13 @@ end;
 
 
 function IsFullFilePath(const Path: string): Boolean; // full means not relative
 function IsFullFilePath(const Path: string): Boolean; // full means not relative
 begin
 begin
-{$ifdef WINDOWS}
+{$ifdef SUPPORT_DRIVES_AND_UNC}
   Result := Length(Path) > 1;
   Result := Length(Path) > 1;
   if Result then
   if Result then
     // check for 'x:' or '\\' at start of path
     // check for 'x:' or '\\' at start of path
     Result := ((Path[2]=':') and (upcase(Path[1]) in ['A'..'Z']))
     Result := ((Path[2]=':') and (upcase(Path[1]) in ['A'..'Z']))
       or ((Path[1]='\') and (Path[2]='\'));
       or ((Path[1]='\') and (Path[2]='\'));
-{$else}  // Linux
+{$else}  // Linux / Unix
   Result := Length(Path) > 0;
   Result := Length(Path) > 0;
   if Result then
   if Result then
     Result := Path[1]='/';
     Result := Path[1]='/';
@@ -236,7 +240,11 @@ begin
 {$ifdef WINDOWS}
 {$ifdef WINDOWS}
   Result := IncludeTrailingBackslash(Path);
   Result := IncludeTrailingBackslash(Path);
 {$else}
 {$else}
+ {$IFDEF UNIX}
   Result := IncludeTrailingSlash(Path);
   Result := IncludeTrailingSlash(Path);
+ {$ELSE UNIX}
+  Result := IncludeTrailingBackslash(Path);
+ {$ENDIF UNIX}
 {$endif}
 {$endif}
 end;
 end;
 
 

+ 580 - 20
packages/fcl-db/src/dbase/dbf_wos2.inc

@@ -150,6 +150,460 @@ const
    EAGAIN = ESysEAGAIN;
    EAGAIN = ESysEAGAIN;
 *)
 *)
 {$PACKRECORDS 1}
 {$PACKRECORDS 1}
+type
+  Str3 = string [3];
+
+  TLocaleRec = packed record
+   case boolean of
+    false:
+     (LangCode: Str3;
+      SubLangCode: Str3;
+      SubLangID: byte;
+      LangID: byte);
+    true:
+     (LangNum: dword;
+      SubLangNum: dword;
+      LCID: word)
+  end;
+
+
+const
+  MaxLocale = 108;
+  MinRealLocale = 4;
+  LocaleMap: array [1..MaxLocale] of TLocaleRec = (
+  (LangCode: #0;
+   SubLangCode: #0;
+   SubLangID: SUBLANG_DEFAULT; { user default }
+   LangID: LANG_NEUTRAL),
+  (LangCode: #0;
+   SubLangCode: #0;
+   SubLangID: SUBLANG_SYS_DEFAULT; { system default }
+   LangID: LANG_NEUTRAL),
+  (LangCode: 'UNI';
+   SubLangCode: 'V';
+   SubLangID: SUBLANG_NEUTRAL; { language neutral }
+   LangID: LANG_NEUTRAL),
+  (LangCode: 'AR';
+   SubLangCode: '_SA';
+   SubLangID: SUBLANG_ARABIC_SAUDI_ARABIA; { Arabic (Saudi Arabia) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_IQ';
+   SubLangID: SUBLANG_ARABIC_IRAQ; { Arabic (Iraq) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_EG';
+   SubLangID: SUBLANG_ARABIC_EGYPT; { Arabic (Egypt) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_LY';
+   SubLangID: SUBLANG_ARABIC_LIBYA; { Arabic (Libya) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_DZ';
+   SubLangID: SUBLANG_ARABIC_ALGERIA; { Arabic (Algeria) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_MA';
+   SubLangID: SUBLANG_ARABIC_MOROCCO; { Arabic (Morocco) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_TN';
+   SubLangID: SUBLANG_ARABIC_TUNISIA; { Arabic (Tunisia) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_OM';
+   SubLangID: SUBLANG_ARABIC_OMAN; { Arabic (Oman) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_YE';
+   SubLangID: SUBLANG_ARABIC_YEMEN; { Arabic (Yemen) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_SY';
+   SubLangID: SUBLANG_ARABIC_SYRIA; { Arabic (Syria) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_JO';
+   SubLangID: SUBLANG_ARABIC_JORDAN; { Arabic (Jordan) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_LB';
+   SubLangID: SUBLANG_ARABIC_LEBANON; { Arabic (Lebanon) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_KW';
+   SubLangID: SUBLANG_ARABIC_KUWAIT; { Arabic (Kuwait) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_AE';
+   SubLangID: SUBLANG_ARABIC_UAE; { Arabic (U.A.E) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_BH';
+   SubLangID: SUBLANG_ARABIC_BAHRAIN; { Arabic (Bahrain) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'AR';
+   SubLangCode: '_QA';
+   SubLangID: SUBLANG_ARABIC_QATAR; { Arabic (Qatar) }
+   LangID: LANG_ARABIC),
+  (LangCode: 'BG';
+   SubLangCode: '_BG';
+   SubLangID: 0;
+   LangID: LANG_BULGARIAN),
+  (LangCode: 'CA';
+   SubLangCode: '_ES';
+   SubLangID: 0;
+   LangID: LANG_CATALAN),
+  (LangCode: 'ZH';
+   SubLangCode: '_TW';
+   SubLangID: SUBLANG_CHINESE_TRADITIONAL; { Chinese (Taiwan) }
+   LangID: LANG_CHINESE),
+  (LangCode: 'ZH';
+   SubLangCode: '_CN';
+   SubLangID: SUBLANG_CHINESE_SIMPLIFIED; { Chinese (PR China) }
+   LangID: LANG_CHINESE),
+  (LangCode: 'ZH';
+   SubLangCode: '_HK';
+   SubLangID: SUBLANG_CHINESE_HONGKONG; { Chinese (Hong Kong) }
+   LangID: LANG_CHINESE),
+  (LangCode: 'ZH';
+   SubLangCode: '_SG';
+   SubLangID: SUBLANG_CHINESE_SINGAPORE; { Chinese (Singapore) }
+   LangID: LANG_CHINESE),
+  (LangCode: 'CS';
+   SubLangCode: '_CZ';
+   SubLangID: 0;
+   LangID: LANG_CZECH),
+  (LangCode: 'DA';
+   SubLangCode: '_DK';
+   SubLangID: 0;
+   LangID: LANG_DANISH),
+  (LangCode: 'DE';
+   SubLangCode: '_DE';
+   SubLangID: SUBLANG_GERMAN; { German }
+   LangID: LANG_GERMAN),
+  (LangCode: 'DE';
+   SubLangCode: '_CH';
+   SubLangID: SUBLANG_GERMAN_SWISS; { German (Swiss) }
+   LangID: LANG_GERMAN),
+  (LangCode: 'DE';
+   SubLangCode: '_AT';
+   SubLangID: SUBLANG_GERMAN_AUSTRIAN; { German (Austrian) }
+   LangID: LANG_GERMAN),
+  (LangCode: 'DE';
+   SubLangCode: '_LU';
+   SubLangID: SUBLANG_GERMAN_LUXEMBOURG; { German (Luxembourg) }
+   LangID: LANG_GERMAN),
+  (LangCode: 'DE';
+   SubLangCode: '_LI';
+   SubLangID: SUBLANG_GERMAN_LIECHTENSTEIN; { German (Liechtenstein) }
+   LangID: LANG_GERMAN),
+  (LangCode: 'EL';
+   SubLangCode: '_GR';
+   SubLangID: 0;
+   LangID: LANG_GREEK),
+  (LangCode: 'EN';
+   SubLangCode: '_US';
+   SubLangID: SUBLANG_ENGLISH_US; { English (USA) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_GB';
+   SubLangID: SUBLANG_ENGLISH_UK; { English (UK) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_AU';
+   SubLangID: SUBLANG_ENGLISH_AUS; { English (Australian) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_CA';
+   SubLangID: SUBLANG_ENGLISH_CAN; { English (Canadian) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_NZ';
+   SubLangID: SUBLANG_ENGLISH_NZ; { English (New Zealand) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_IE';
+   SubLangID: SUBLANG_ENGLISH_EIRE; { English (Irish) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_ZA';
+   SubLangID: SUBLANG_ENGLISH_SOUTH_AFRICA; { English (South Africa) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_JM';
+   SubLangID: SUBLANG_ENGLISH_JAMAICA; { English (Jamaica) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN_';
+   SubLangCode: '029';
+   SubLangID: SUBLANG_ENGLISH_CARIBBEAN; { English (Caribbean) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_BZ';
+   SubLangID: SUBLANG_ENGLISH_BELIZE; { English (Belize) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'EN';
+   SubLangCode: '_TT';
+   SubLangID: SUBLANG_ENGLISH_TRINIDAD; { English (Trinidad) }
+   LangID: LANG_ENGLISH),
+  (LangCode: 'ES';
+   SubLangCode: '_ES';
+   SubLangID: SUBLANG_SPANISH; { Spanish (Castilian) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_MX';
+   SubLangID: SUBLANG_SPANISH_MEXICAN; { Spanish (Mexican) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_EM';
+   SubLangID: SUBLANG_SPANISH_MODERN; { Spanish (Modern) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_GT';
+   SubLangID: SUBLANG_SPANISH_GUATEMALA; { Spanish (Guatemala) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_CR';
+   SubLangID: SUBLANG_SPANISH_COSTA_RICA; { Spanish (Costa Rica) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_PA';
+   SubLangID: SUBLANG_SPANISH_PANAMA; { Spanish (Panama) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_DO';
+   SubLangID: SUBLANG_SPANISH_DOMINICAN_REPUBLIC; { Spanish (Dominican Republic) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_VE';
+   SubLangID: SUBLANG_SPANISH_VENEZUELA; { Spanish (Venezuela) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_CO';
+   SubLangID: SUBLANG_SPANISH_COLOMBIA; { Spanish (Colombia) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_PE';
+   SubLangID: SUBLANG_SPANISH_PERU; { Spanish (Peru) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_AR';
+   SubLangID: SUBLANG_SPANISH_ARGENTINA; { Spanish (Argentina) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_EC';
+   SubLangID: SUBLANG_SPANISH_ECUADOR; { Spanish (Ecuador) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_CL';
+   SubLangID: SUBLANG_SPANISH_CHILE; { Spanish (Chile) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_UY';
+   SubLangID: SUBLANG_SPANISH_URUGUAY; { Spanish (Uruguay) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_PY';
+   SubLangID: SUBLANG_SPANISH_PARAGUAY; { Spanish (Paraguay) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_BO';
+   SubLangID: SUBLANG_SPANISH_BOLIVIA; { Spanish (Bolivia) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_SV';
+   SubLangID: SUBLANG_SPANISH_EL_SALVADOR; { Spanish (El Salvador) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_HN';
+   SubLangID: SUBLANG_SPANISH_HONDURAS; { Spanish (Honduras) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_NI';
+   SubLangID: SUBLANG_SPANISH_NICARAGUA; { Spanish (Nicaragua) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'ES';
+   SubLangCode: '_PR';
+   SubLangID: SUBLANG_SPANISH_PUERTO_RICO; { Spanish (Puerto Rico) }
+   LangID: LANG_SPANISH),
+  (LangCode: 'FI';
+   SubLangCode: '_FI';
+   SubLangID: 0;
+   LangID: LANG_FINNISH),
+  (LangCode: 'FR';
+   SubLangCode: '_FR';
+   SubLangID: SUBLANG_FRENCH; { French }
+   LangID: LANG_FRENCH),
+  (LangCode: 'FR';
+   SubLangCode: '_BE';
+   SubLangID: SUBLANG_FRENCH_BELGIAN; { French (Belgian) }
+   LangID: LANG_FRENCH),
+  (LangCode: 'FR';
+   SubLangCode: '_CA';
+   SubLangID: SUBLANG_FRENCH_CANADIAN; { French (Canadian) }
+   LangID: LANG_FRENCH),
+  (LangCode: 'FR';
+   SubLangCode: '_CH';
+   SubLangID: SUBLANG_FRENCH_SWISS; { French (Swiss) }
+   LangID: LANG_FRENCH),
+  (LangCode: 'FR';
+   SubLangCode: '_LU';
+   SubLangID: SUBLANG_FRENCH_LUXEMBOURG; { French (Luxembourg) }
+   LangID: LANG_FRENCH),
+  (LangCode: 'HE';
+   SubLangCode: '_IL';
+   SubLangID: 0;
+   LangID: LANG_HEBREW),
+  (LangCode: 'HU';
+   SubLangCode: '_HU';
+   SubLangID: 0;
+   LangID: LANG_HUNGARIAN),
+  (LangCode: 'IS';
+   SubLangCode: '_IS';
+   SubLangID: 0;
+   LangID: LANG_ICELANDIC),
+  (LangCode: 'IT';
+   SubLangCode: '_IT';
+   SubLangID: SUBLANG_ITALIAN; { Italian }
+   LangID: LANG_ITALIAN),
+  (LangCode: 'IT';
+   SubLangCode: '_CH';
+   SubLangID: SUBLANG_ITALIAN_SWISS; { Italian (Swiss) }
+   LangID: LANG_ITALIAN),
+  (LangCode: 'JA';
+   SubLangCode: '_JP';
+   SubLangID: 0;
+   LangID: LANG_JAPANESE),
+  (LangCode: 'KO';
+   SubLangCode: '_KR';
+   SubLangID: SUBLANG_KOREAN; { Korean (Extended Wansung) }
+   LangID: LANG_KOREAN),
+  (LangCode: 'KO';
+   SubLangCode: '_';
+   SubLangID: SUBLANG_KOREAN_JOHAB; { Korean (Johab) }
+   LangID: LANG_KOREAN),
+  (LangCode: 'NL';
+   SubLangCode: '_NL';
+   SubLangID: SUBLANG_DUTCH; { Dutch }
+   LangID: LANG_DUTCH),
+  (LangCode: 'NL';
+   SubLangCode: '_BE';
+   SubLangID: SUBLANG_DUTCH_BELGIAN; { Dutch (Belgian) }
+   LangID: LANG_DUTCH),
+  (LangCode: 'NB';
+   SubLangCode: '_NO';
+   SubLangID: SUBLANG_NORWEGIAN_BOKMAL; { Norwegian (Bokmal) }
+   LangID: LANG_NORWEGIAN),
+  (LangCode: 'NN';
+   SubLangCode: '_NO';
+   SubLangID: SUBLANG_NORWEGIAN_NYNORSK; { Norwegian (Nynorsk) }
+   LangID: LANG_NORWEGIAN),
+  (LangCode: 'PL';
+   SubLangCode: '_PL';
+   SubLangID: 0;
+   LangID: LANG_POLISH),
+  (LangCode: 'PT';
+   SubLangCode: '_PT';
+   SubLangID: SUBLANG_PORTUGUESE; { Portuguese }
+   LangID: LANG_PORTUGUESE),
+  (LangCode: 'PT';
+   SubLangCode: '_BR';
+   SubLangID: SUBLANG_PORTUGUESE_BRAZILIAN; { Portuguese (Brazilian) }
+   LangID: LANG_PORTUGUESE),
+  (LangCode: 'RO';
+   SubLangCode: '_RO';
+   SubLangID: 0;
+   LangID: LANG_ROMANIAN),
+  (LangCode: 'RU';
+   SubLangCode: '_RU';
+   SubLangID: 0;
+   LangID: LANG_RUSSIAN),
+  (LangCode: 'SR';
+   SubLangCode: '_RS';
+   SubLangID: SUBLANG_SERBIAN_LATIN; { Serbian (Latin) }
+   LangID: LANG_SERBIAN),
+  (LangCode: 'SR';
+   SubLangCode: '_RS';
+   SubLangID: SUBLANG_SERBIAN_CYRILLIC; { Serbian (Cyrillic) }
+   LangID: LANG_SERBIAN),
+  (LangCode: 'HR';
+   SubLangCode: '_HR';
+   SubLangID: 0;
+   LangID: LANG_CROATIAN),
+  (LangCode: 'SK';
+   SubLangCode: '_SK';
+   SubLangID: 0;
+   LangID: LANG_SLOVAK),
+  (LangCode: 'SQ';
+   SubLangCode: '_AL';
+   SubLangID: 0;
+   LangID: LANG_ALBANIAN),
+  (LangCode: 'SV';
+   SubLangCode: '_SE';
+   SubLangID: SUBLANG_SWEDISH; { Swedish }
+   LangID: LANG_SWEDISH),
+  (LangCode: 'SV';
+   SubLangCode: '_FI';
+   SubLangID: SUBLANG_SWEDISH_FINLAND; { Swedish (Finland) }
+   LangID: LANG_SWEDISH),
+  (LangCode: 'TH';
+   SubLangCode: '_TH';
+   SubLangID: 0;
+   LangID: LANG_THAI),
+  (LangCode: 'TR';
+   SubLangCode: '_TR';
+   SubLangID: 0;
+   LangID: LANG_TURKISH),
+  (LangCode: 'ID';
+   SubLangCode: '_ID';
+   SubLangID: 0;
+   LangID: LANG_INDONESIAN),
+  (LangCode: 'UK';
+   SubLangCode: '_UA';
+   SubLangID: 0;
+   LangID: LANG_UKRAINIAN),
+  (LangCode: 'BE';
+   SubLangCode: '_BY';
+   SubLangID: 0;
+   LangID: LANG_BELARUSIAN),
+  (LangCode: 'SL';
+   SubLangCode: '_SI';
+   SubLangID: 0;
+   LangID: LANG_SLOVENIAN),
+  (LangCode: 'ET';
+   SubLangCode: '_EE';
+   SubLangID: 0;
+   LangID: LANG_ESTONIAN),
+  (LangCode: 'LV';
+   SubLangCode: '_LV';
+   SubLangID: 0;
+   LangID: LANG_LATVIAN),
+  (LangCode: 'LT';
+   SubLangCode: '_LT';
+   SubLangID: 0;
+   LangID: LANG_LITHUANIAN),
+  (LangCode: 'FA';
+   SubLangCode: '_IR';
+   SubLangID: 0;
+   LangID: LANG_FARSI),
+  (LangCode: 'VI';
+   SubLangCode: '_VN';
+   SubLangID: 0;
+   LangID: LANG_VIETNAMESE),
+  (LangCode: 'EU';
+   SubLangCode: '_ES';
+   SubLangID: 0;
+   LangID: LANG_BASQUE),
+  (LangCode: 'AF';
+   SubLangCode: '_ZA';
+   SubLangID: 0;
+   LangID: LANG_AFRIKAANS),
+  (LangCode: 'FO';
+   SubLangCode: '_FO';
+   SubLangID: 0;
+   LangID: LANG_FAEROESE));
+
 const
 const
   LastErr: cardinal = 0;
   LastErr: cardinal = 0;
 
 
@@ -173,7 +627,7 @@ begin
   TQRecC (FLock.Offset).C1 := dwFileOffsetLow;
   TQRecC (FLock.Offset).C1 := dwFileOffsetLow;
   TQRecC (FLock.Range).C2 := nNumberOfBytesToLockHigh;
   TQRecC (FLock.Range).C2 := nNumberOfBytesToLockHigh;
   TQRecC (FLock.Range).C1 := nNumberOfBytesToLockLow;
   TQRecC (FLock.Range).C1 := nNumberOfBytesToLockLow;
-  RC := DosSetFileLocksL (hFile, FLock, FUnlock, 50, 0);
+  RC := DosSetFileLocksL (hFile, FUnlock, FLock, 50, 0);
   if RC <> 0 then
   if RC <> 0 then
    begin
    begin
     LastErr := RC;
     LastErr := RC;
@@ -194,7 +648,7 @@ begin
   TQRecC (FUnlock.Offset).C1 := dwFileOffsetLow;
   TQRecC (FUnlock.Offset).C1 := dwFileOffsetLow;
   TQRecC (FUnlock.Range).C2 := nNumberOfBytesToUnlockHigh;
   TQRecC (FUnlock.Range).C2 := nNumberOfBytesToUnlockHigh;
   TQRecC (FUnlock.Range).C1 := nNumberOfBytesToUnlockLow;
   TQRecC (FUnlock.Range).C1 := nNumberOfBytesToUnlockLow;
-  RC := DosSetFileLocksL (hFile, FLock, FUnlock, 50, 0);
+  RC := DosSetFileLocksL (hFile, FUnlock, FLock, 50, 0);
   if RC <> 0 then
   if RC <> 0 then
    begin
    begin
     LastErr := RC;
     LastErr := RC;
@@ -244,54 +698,160 @@ end;
 
 
 function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer;
 function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer;
 var
 var
-  TempA: AnsiString;
-  TempW: WideString;
+  TempA: RawByteString;
+  TempW: UnicodeString;
 begin
 begin
-{$WARNING To be rewritten using the UnicodeStringManager functionality!}
-  TempA := String(lpMultiByteStr^);
+  TempA := String (lpMultiByteStr);
+  SetCodePage (TempA, CodePage, false);
   TempW := TempA;
   TempW := TempA;
   Result := Length(TempW);
   Result := Length(TempW);
-  System.Move(TempW, lpWideCharStr^, Result);
+  if cchWideChar <= Result then
+   begin
+    System.Move (TempW, lpWideCharStr^, Pred (cchWideChar) * SizeOf (WideChar));
+    lpWideCharStr [Pred (cchWideChar)] := #0;
+   end
+  else
+   begin
+    System.Move (TempW, lpWideCharStr^, Result * SizeOf (WideChar));
+    lpWideCharStr [Pred (Result)] := #0;
+   end;
 end;
 end;
 
 
 function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer;
 function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer;
 var
 var
-  TempA: AnsiString;
-  TempW: WideString;
+  TempA: RawByteString;
+  TempW: UnicodeString;
 begin
 begin
-{$WARNING To be rewritten using the UnicodeStringManager functionality!}
-  TempW := WideString(lpWideCharStr^);
+  SetLength (TempW, cchWideChar);
+  System.Move (lpWideCharStr^, TempW, cchWideChar * SizeOf (WideChar));
+  TempA := '';
+  SetCodePage (TempA, CodePage, false);
   TempA := TempW;
   TempA := TempW;
-  Result := Length(TempA);
-  System.Move(TempA, lpMultiByteStr^, Result);
+  Result := Length (TempA);
+  if Result >= cchMultiByte then
+   begin
+    System.Move (TempA, lpMultiByteStr^, Pred (cchMultiByte));
+    lpMultiByteStr [Pred (cchMultiByte)] := #0;
+   end
+  else
+   begin
+    System.Move (TempA, lpMultiByteStr^, Result);
+    lpMultiByteStr [Pred (Result)] := #0;
+   end;
 end;
 end;
 
 
 function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer;
 function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer;
 begin
 begin
-{$WARNING To be rewritten using the UnicodeStringManager functionality!}
+{$WARNING To be rewritten using the UnicodeStringManager and LIBUNI.DLL functionality!}
   Result := StrLComp(lpString1, lpString2, cchCount1) + 2;
   Result := StrLComp(lpString1, lpString2, cchCount1) + 2;
   if Result > 2 then Result := 3;
   if Result > 2 then Result := 3;
   if Result < 2 then Result := 1;
   if Result < 2 then Result := 1;
 end;
 end;
 
 
 function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL;
 function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL;
+
+type
+  TCodePagesProc = function (CodePageString: PChar): Cardinal; stdcall;
+
+var
+  CP: word;
+  CP2: TSystemCodepage;
+  S: AnsiString;
+  CPProc: TCodePagesProc;
+
+ function TestCPNum: boolean;
+ var
+  UConvObj: TUConvObject;
+ begin
+  CP2 := OS2CPToRtlCP (CP, 0, UConvObj);
+  if UConvObj <> nil then
+   begin
+    Str (CP2, S);
+    TestCPNum := true;
+   end
+  else
+   TestCPNum := false;
+ end;
+
 begin
 begin
-{$WARNING To be rewritten using the LIBUNI.DLL functionality!}
+  CPProc := TCodePagesProc (lpCodepageEnumProc);
+  if not (UniAPI) then
+   begin
+    Str (DefaultSystemCodepage, S);
+    CPProc (PChar (S));
+   end
+  else
+   begin
+    for CP := 1 to 1386 do
+(* Skip higher numbers which are not supported under OS/2 anyway *)
+(* and testing them would take considerable amount of time.      *)
+     if TestCPNum then
+      CPProc (PChar (S));
+    CP := 4946;
+    if TestCPNum then
+(* This one might be recognized... *)
+     CPProc (PChar (S));
+    CP := 28709;
+    if TestCPNum then
+(* ...and this one as well. *)
+     CPProc (PChar (S));
+   end;
   Result := True;
   Result := True;
 end;
 end;
 
 
 function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL;
 function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL;
+type
+  TLocaleProc = function (LocaleString: PChar): Integer; stdcall;
+var
+  S: AnsiString;
+  Loc: PtrInt;
+  LocObj: TLocaleObject;
 begin
 begin
-{$WARNING To be rewritten using the LIBUNI.DLL functionality!}
-(* http://compgroups.net/comp.os.os2.programmer.misc/how-to-obtain-current-locale-lang/2524034 *)
+  if UniAPI then
+   begin
+    for Loc := MinRealLocale to High (LocaleMap) do
+     begin
+      S := LocaleMap [Loc].LangCode + LocaleMap [Loc].SubLangCode;
+      if Sys_UniCreateLocaleObject (2, PChar (S), LocObj) = 0 then
+       begin
+        S := HexStr (Pointer (PtrUInt (LocaleMap [Loc].LCID)));
+        TLocaleProc (lpLocaleEnumProc) (PChar (S));
+        Sys_UniFreeLocaleObject (LocObj);
+       end;
+     end;
+   end
+  else
+   begin
+    Str (GetUserDefaultLCID, S);
+    TLocaleProc (lpLocaleEnumProc) (PChar (S));
+   end;
   Result := True;
   Result := True;
 end;
 end;
 
 
 function GetUserDefaultLCID: LCID;
 function GetUserDefaultLCID: LCID;
+var
+  Loc: PtrInt;
+  Lang: AnsiString;
+  Res2: word;
 begin
 begin
-{$WARNING To be rewritten using the LIBUNI.DLL functionality!}
-(* http://compgroups.net/comp.os.os2.programmer.misc/how-to-obtain-current-locale-lang/2524034 *)
-  Result := LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10);
+  Result := 0;
+  Lang := UpCase (GetEnvironmentVariable ('LANG'));
+  if Lang <> '' then
+   begin
+    Res2 := 0;
+    for Loc := MinRealLocale to High (LocaleMap) do
+     begin
+      if Lang = LocaleMap [Loc].LangCode + LocaleMap [Loc].SubLangCode then
+       Result := LocaleMap [Loc].LCID
+      else
+       if (Res2 = 0) and (Lang = LocaleMap [Loc].LangCode) then
+        Res2 := LocaleMap [Loc].LangID;
+     end;
+    if (Result = 0) and (Res2 <> 0) then
+     Result := Res2;
+   end;
+  if Result = 0 then
+   Result := LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10);
 end;
 end;
 
 
 function GetLastError: Integer;
 function GetLastError: Integer;

+ 1 - 1
packages/rtl-unicode/fpmake.pp

@@ -12,7 +12,7 @@ Const
   // in workable state atm.
   // in workable state atm.
   UnixLikes = AllUnixOSes -[QNX];
   UnixLikes = AllUnixOSes -[QNX];
 
 
-  CollationOSes = [aix,darwin,freebsd,linux,netbsd,openbsd,solaris,win32,win64,dragonfly];
+  CollationOSes = [aix,darwin,emx,freebsd,linux,netbsd,openbsd,os2,solaris,win32,win64,dragonfly];
   CPUnits       = [aix,amiga,aros,android,beos,darwin,iphonesim,emx,gba,freebsd,go32v2,haiku,linux,morphos,netbsd,netware,netwlibc,openbsd,os2,solaris,watcom,wii,win32,win64,wince,dragonfly];
   CPUnits       = [aix,amiga,aros,android,beos,darwin,iphonesim,emx,gba,freebsd,go32v2,haiku,linux,morphos,netbsd,netware,netwlibc,openbsd,os2,solaris,watcom,wii,win32,win64,wince,dragonfly];
   utf8bidiOSes  = [netware,netwlibc];
   utf8bidiOSes  = [netware,netwlibc];
   freebidiOSes  = [netware,netwlibc];  
   freebidiOSes  = [netware,netwlibc];  

+ 14 - 6
rtl/objpas/fpwidestring.pp

@@ -785,18 +785,26 @@ begin
   DefaultUnicodeCodePage:=CP_UTF16;
   DefaultUnicodeCodePage:=CP_UTF16;
 {$ifdef MSWINDOWS}
 {$ifdef MSWINDOWS}
   DefaultSystemCodePage:=GetACP();
   DefaultSystemCodePage:=GetACP();
-{$endif MSWINDOWS}
-{$ifdef UNIX}
+{$ELSE MSWINDOWS}
+ {$ifdef UNIX}
   DefaultSystemCodePage:=GetSystemCodepage;
   DefaultSystemCodePage:=GetSystemCodepage;
   if (DefaultSystemCodePage = CP_NONE) then
   if (DefaultSystemCodePage = CP_NONE) then
     DefaultSystemCodePage:=CP_UTF8;
     DefaultSystemCodePage:=CP_UTF8;
-{$ifdef FPCRTL_FILESYSTEM_UTF8}
+  {$ifdef FPCRTL_FILESYSTEM_UTF8}
   DefaultFileSystemCodePage:=CP_UTF8;
   DefaultFileSystemCodePage:=CP_UTF8;
-{$else}
+  {$else}
   DefaultFileSystemCodePage:=DefaultSystemCodepage;
   DefaultFileSystemCodePage:=DefaultSystemCodepage;
-{$endif}
+  {$endif}
   DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage;
   DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage;
-{$endif UNIX}
+ {$ELSE UNIX}
+  if Assigned (WideStringManager.GetStandardCodePageProc) then
+   DefaultSystemCodePage := WideStringManager.GetStandardCodePageProc (scpAnsi)
+  else
+   DefaultSystemCodePage := CP_NONE;
+  DefaultFileSystemCodePage := DefaultSystemCodePage;
+  DefaultRTLFileSystemCodePage := DefaultSystemCodePage;
+ {$endif UNIX}
+{$endif MSWINDOWS}
 end;
 end;
 
 
 
 

+ 41 - 4
rtl/os2/sysos.inc

@@ -1,10 +1,9 @@
 {
 {
     This file is part of the Free Pascal run time library.
     This file is part of the Free Pascal run time library.
-    Copyright (c) 2001 by Free Pascal development team
+    Copyright (c) 2001-2015 by Free Pascal development team
 
 
-    This file implements all the base types and limits required
-    for a minimal POSIX compliant subset required to port the compiler
-    to a new OS.
+    This file contains a subset of OS/2 base types and imported OS/2 API
+    functions necessary for implementation of unit system.
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -449,3 +448,41 @@ external 'NLS' index 6;
 function DosQueryCollate (Size: cardinal; var Country: TCountryCode;
 function DosQueryCollate (Size: cardinal; var Country: TCountryCode;
                      Buf: PByteArray; var TableLen: cardinal): cardinal; cdecl;
                      Buf: PByteArray; var TableLen: cardinal): cardinal; cdecl;
 external 'NLS' index 8;
 external 'NLS' index 8;
+
+type
+ TTimeFmt = (Clock12, Clock24);
+
+ TCountryInfo = record
+  Country, CodePage: cardinal;     {Country and codepage requested.}
+  DateFormat: cardinal;            {1=ddmmyy 2=yymmdd 3=mmddyy}
+  CurrencyUnit: array [0..4] of char;
+  ThousandSeparator: char;         {Thousands separator.}
+  Zero1: byte;                     {Always zero.}
+  DecimalSeparator: char;          {Decimals separator,}
+  Zero2: byte;
+  DateSeparator: char;             {Date separator.}
+  Zero3: byte;
+  TimeSeparator: char;             {Time separator.}
+  Zero4: byte;
+  CurrencyFormat,                  {Bit field:
+                                    Bit 0: 0=indicator before value
+                                           1=indicator after value
+                                    Bit 1: 1=insert space after indicator.
+                                    Bit 2: 1=Ignore bit 0&1, replace
+                                             decimal separator with
+                                             indicator.}
+  DecimalPlace: byte;              {Number of decimal places used in
+                                    currency indication.}
+  TimeFormat: TTimeFmt;            {12/24 hour.}
+  Reserve1: array [0..1] of word;
+  DataSeparator: char;             {Data list separator}
+  Zero5: byte;
+  Reserve2: array [0..4] of word;
+ end;
+
+const
+ CurrentCountry: TCountryCode = (Country: 0; CodePage: 0);
+
+function DosQueryCtryInfo (Size: cardinal; var Country: TCountryCode;
+             var Res: TCountryInfo; var ActualSize: cardinal): cardinal; cdecl;
+external 'NLS' index 5;

+ 4 - 0
rtl/os2/system.pas

@@ -200,6 +200,9 @@ type
   TUniFreeLocaleObject = function (Locale_Object: TLocaleObject): longint;
   TUniFreeLocaleObject = function (Locale_Object: TLocaleObject): longint;
                                                                          cdecl;
                                                                          cdecl;
 
 
+  TUniMapCtryToLocale = function (CountryCode: cardinal; LocaleName: PWideChar;
+                                             BufSize: longint): longint; cdecl;
+
 
 
 const
 const
   DosCallsHandle: THandle = THandle (-1);
   DosCallsHandle: THandle = THandle (-1);
@@ -224,6 +227,7 @@ var
   Sys_UniStrColl: TUniStrColl;
   Sys_UniStrColl: TUniStrColl;
   Sys_UniCreateLocaleObject: TUniCreateLocaleObject;
   Sys_UniCreateLocaleObject: TUniCreateLocaleObject;
   Sys_UniFreeLocaleObject: TUniFreeLocaleObject;
   Sys_UniFreeLocaleObject: TUniFreeLocaleObject;
+  Sys_UniMapCtryToLocale: TUniMapCtryToLocale;
 
 
 {$ENDIF OS2UNICODE}
 {$ENDIF OS2UNICODE}
 
 

+ 83 - 15
rtl/os2/sysucode.inc

@@ -150,6 +150,7 @@ const
   Uni_System_Locales = 1;
   Uni_System_Locales = 1;
   Uni_User_Locales = 2;
   Uni_User_Locales = 2;
   WNull: WideChar = #0;
   WNull: WideChar = #0;
+  WUniv: array [0..4] of WideChar = 'UNIV'#0;
 
 
 
 
 
 
@@ -186,7 +187,7 @@ const
   EmptyCC: TCountryCode = (Country: 0; Codepage: 0); (* Empty = current *)
   EmptyCC: TCountryCode = (Country: 0; Codepage: 0); (* Empty = current *)
   (* 819 = IBM codepage number for ISO 8859-1 used in FPC default *)
   (* 819 = IBM codepage number for ISO 8859-1 used in FPC default *)
   (* dummy translation between UnicodeString and AnsiString.      *)
   (* dummy translation between UnicodeString and AnsiString.      *)
-  IsoCC: TCountryCode = (Country: 1; Codepage: 819); (* Empty = current *)
+  IsoCC: TCountryCode = (Country: 1; Codepage: 819); (* US with ISO 8859-1 *)
   (* The following two arrays are initialized on startup in case that *)
   (* The following two arrays are initialized on startup in case that *)
   (* Dummy* routines must be used. First for current codepage...      *)
   (* Dummy* routines must be used. First for current codepage...      *)
   DBCSLeadRangesEnd: byte = 0;
   DBCSLeadRangesEnd: byte = 0;
@@ -447,7 +448,7 @@ begin
     Dec (SrcLen);
     Dec (SrcLen);
     Inc (InBuf, SrcLen);
     Inc (InBuf, SrcLen);
     Dec (InBytesLeft, SrcLen);
     Dec (InBytesLeft, SrcLen);
-    DummyUniUConvToUcs := Uls_BufferFull; { According to IBM documentation Uls_Invalid and not Uls_BufferFull as returned by UniUConvFromUcs?! }
+    DummyUniUConvToUcs := Uls_BufferFull; { According to IBM documentation Uls_Invalid and not Uls_BufferFull is returned by UniUConvFromUcs?! }
    end
    end
   else
   else
    begin
    begin
@@ -461,6 +462,19 @@ begin
 end;
 end;
 
 
 
 
+function DummyUniMapCtryToLocale (CountryCode: cardinal; LocaleName: PWideChar;
+                                             BufSize: longint): longint; cdecl;
+begin
+  if BufSize = 0 then
+   DummyUniMapCtryToLocale := Uls_Invalid
+  else
+   begin
+    LocaleName^ := #0;
+    DummyUniMapCtryToLocale := Uls_Unsupported;
+   end;
+end;
+
+
 procedure InitDBCSLeadRanges;
 procedure InitDBCSLeadRanges;
 var
 var
   RC: cardinal;
   RC: cardinal;
@@ -702,6 +716,8 @@ var
   RC: cardinal;
   RC: cardinal;
   CPArr: TCPArray;
   CPArr: TCPArray;
   ReturnedSize: cardinal;
   ReturnedSize: cardinal;
+  WA: array [0..9] of WideChar; (* Even just 6 WideChars should be enough *)
+  CI: TCountryInfo;
 begin
 begin
   if InInitDefaultCP <> -1 then
   if InInitDefaultCP <> -1 then
    begin
    begin
@@ -748,11 +764,52 @@ begin
     RCI := Sys_UniFreeLocaleObject (DefLocObj);
     RCI := Sys_UniFreeLocaleObject (DefLocObj);
     if RCI <> 0 then
     if RCI <> 0 then
      OSErrorWatch (cardinal (RCI));
      OSErrorWatch (cardinal (RCI));
+    DefLocObj := nil;
    end;
    end;
-  RCI := Sys_UniCreateLocaleObject (Uni_UCS_String_Pointer, @WNull, DefLocObj);
-  if RCI <> 0 then
-   OSErrorWatch (cardinal (RCI));
-  if not (UniAPI) then
+  if UniAPI then (* Do not bother with the locale object otherwise *)
+   begin
+    RCI := Sys_UniCreateLocaleObject (Uni_UCS_String_Pointer, @WNull, DefLocObj);
+    if RCI <> 0 then
+     begin
+      OSErrorWatch (cardinal (RCI));
+      DefLocObj := nil;
+(* The locale dependent routines like comparison require a valid locale *)
+(* setting, but the locale set using environment variable LANG is not *)
+(* recognized by OS/2 -> let's try to derive the locale from country *)
+      RC := DosQueryCtryInfo (SizeOf (CI), EmptyCC, CI, ReturnedSize);
+      if RC = 0 then
+       begin
+        RCI := Sys_UniMapCtryToLocale (CI.Country, @WA [0],
+                                            SizeOf (WA) div SizeOf (WideChar));
+        if RCI = 0 then
+         begin
+          RCI := Sys_UniCreateLocaleObject (Uni_UCS_String_Pointer, @WA [0],
+                                                                    DefLocObj);
+          if RCI <> 0 then
+           begin
+            OSErrorWatch (cardinal (RCI));
+            DefLocObj := nil;
+           end;
+         end
+        else
+         OSErrorWatch (cardinal (RCI));
+       end
+      else
+       OSErrorWatch (RC);
+      if DefLocObj = nil then
+(* Still no success -> let's use the "Universal" locale as a fallback. *)
+       begin
+        RCI := Sys_UniCreateLocaleObject (Uni_UCS_String_Pointer, @WUniv [0],
+                                                                    DefLocObj);
+        if RCI <> 0 then
+         begin
+          OSErrorWatch (cardinal (RCI));
+          DefLocObj := nil;
+         end;
+       end;
+     end;
+   end
+  else (* not UniAPI *)
    ReInitDummyAnsiSupport;
    ReInitDummyAnsiSupport;
   InInitDefaultCP := -1;
   InInitDefaultCP := -1;
 end;
 end;
@@ -841,6 +898,7 @@ begin
         RCI := Sys_UniFreeUConvObject (TempCpRec.UConvObj);
         RCI := Sys_UniFreeUConvObject (TempCpRec.UConvObj);
         if RCI <> 0 then
         if RCI <> 0 then
          OSErrorWatch (cardinal (RCI));
          OSErrorWatch (cardinal (RCI));
+        TempCpRec.UConvObj := nil;
        end;
        end;
       if UConvObjectForCP (CP, UConvObj) = Uls_Success then
       if UConvObjectForCP (CP, UConvObj) = Uls_Success then
        begin
        begin
@@ -1164,8 +1222,9 @@ var
   I: cardinal;
   I: cardinal;
 begin
 begin
   SetLength (Result, Length (S));
   SetLength (Result, Length (S));
-  for I := 0 to Pred (Length (S)) do
-   PWideChar (Result) [I] := Sys_UniToUpper (S [Succ (I)]);
+  if Length (S) > 0 then
+   for I := 0 to Pred (Length (S)) do
+    PWideChar (Result) [I] := Sys_UniToUpper (S [Succ (I)]);
 end;
 end;
 
 
 
 
@@ -1174,8 +1233,9 @@ var
   I: cardinal;
   I: cardinal;
 begin
 begin
   SetLength (Result, Length (S));
   SetLength (Result, Length (S));
-  for I := 0 to Pred (Length (S)) do
-   PWideChar (Result) [I] := Sys_UniToLower (S [Succ (I)]);
+  if Length (S) > 0 then
+   for I := 0 to Pred (Length (S)) do
+    PWideChar (Result) [I] := Sys_UniToLower (S [Succ (I)]);
 end;
 end;
 
 
 
 
@@ -1185,9 +1245,10 @@ var
 begin
 begin
   Result := S;
   Result := S;
   UniqueString (Result);
   UniqueString (Result);
-  for I := 1 to Length (S) do
-   if Result [I] = WNull then
-    Result [I] := ' ';
+  if Length (S) > 0 then
+   for I := 1 to Length (S) do
+    if Result [I] = WNull then
+     Result [I] := ' ';
 end;
 end;
 
 
 
 
@@ -1589,8 +1650,14 @@ begin
                         if RC = 0 then
                         if RC = 0 then
                          begin
                          begin
                           Sys_UniFreeLocaleObject := TUniFreeLocaleObject (P);
                           Sys_UniFreeLocaleObject := TUniFreeLocaleObject (P);
-
-                          UniAPI := true;
+                          RC := DosQueryProcAddr (LibUniHandle,
+                                                OrdUniMapCtryToLocale, nil, P);
+                          if RC = 0 then
+                           begin
+                            Sys_UniMapCtryToLocale := TUniMapCtryToLocale (P);
+
+                            UniAPI := true;
+                           end;
                          end;
                          end;
                        end;
                        end;
                      end;
                      end;
@@ -1617,6 +1684,7 @@ begin
     Sys_UniStrColl := @DummyUniStrColl;
     Sys_UniStrColl := @DummyUniStrColl;
     Sys_UniCreateLocaleObject := @DummyUniCreateLocaleObject;
     Sys_UniCreateLocaleObject := @DummyUniCreateLocaleObject;
     Sys_UniFreeLocaleObject := @DummyUniFreeLocaleObject;
     Sys_UniFreeLocaleObject := @DummyUniFreeLocaleObject;
+    Sys_UniMapCtryToLocale := @DummyUniMapCtryToLocale;
     InitDummyAnsiSupport;
     InitDummyAnsiSupport;
    end;
    end;
 
 

+ 2 - 6
utils/unicode/fpmake.pp

@@ -15,7 +15,7 @@ begin
   With Installer do
   With Installer do
     begin
     begin
     P:=AddPackage('utils-unicode');
     P:=AddPackage('utils-unicode');
-    P.ShortName:='unicode';
+    P.ShortName:='ucode';
 
 
     P.Author := 'Inoussa OUEDRAOGO';
     P.Author := 'Inoussa OUEDRAOGO';
     P.License := 'LGPL with modification';
     P.License := 'LGPL with modification';
@@ -30,7 +30,7 @@ begin
     P.Dependencies.Add('fcl-base');
     P.Dependencies.Add('fcl-base');
     P.Dependencies.Add('fcl-xml');
     P.Dependencies.Add('fcl-xml');
 
 
-    P.OSes:=[win32, win64, linux, darwin];
+    P.OSes:=[win32, win64, linux, darwin, os2, emx];
 
 
     T := P.Targets.AddImplicitUnit('helper.pas');
     T := P.Targets.AddImplicitUnit('helper.pas');
     T.ResourceStrings := true;
     T.ResourceStrings := true;
@@ -66,7 +66,3 @@ begin
   Installer.Run;
   Installer.Run;
 end.
 end.
 {$endif ALLPACKAGES}
 {$endif ALLPACKAGES}
-
-
-
-