Browse Source

Darwin version comparisons: factored out into object

Use numeric instead of string comparisons
Jonas Maebe 2 years ago
parent
commit
b26703feaa
6 changed files with 64 additions and 117 deletions
  1. 0 67
      compiler/cutils.pas
  2. 5 4
      compiler/globals.pas
  3. 2 2
      compiler/llvm/nllvmutil.pas
  4. 35 22
      compiler/options.pas
  5. 20 20
      compiler/systems/t_darwin.pas
  6. 2 2
      compiler/triplet.pas

+ 0 - 67
compiler/cutils.pas

@@ -133,7 +133,6 @@ interface
     function DePascalQuote(var s: ansistring): Boolean;
     function DePascalQuote(var s: ansistring): Boolean;
     function CompareStr(const S1, S2: string): Integer;
     function CompareStr(const S1, S2: string): Integer;
     function CompareText(S1, S2: string): integer;
     function CompareText(S1, S2: string): integer;
-    function CompareVersionStrings(s1,s2: string): longint;
 
 
     { releases the string p and assignes nil to p }
     { releases the string p and assignes nil to p }
     { if p=nil then freemem isn't called          }
     { if p=nil then freemem isn't called          }
@@ -1275,72 +1274,6 @@ implementation
       end;
       end;
 
 
 
 
-    function CompareVersionStrings(s1,s2: string): longint;
-      var
-        start1, start2,
-        i1, i2,
-        num1,num2,
-        res,
-        err        : longint;
-      begin
-        i1:=1;
-        i2:=1;
-        repeat
-          start1:=i1;
-          start2:=i2;
-          while (i1<=length(s1)) and
-                (s1[i1] in ['0'..'9']) do
-             inc(i1);
-          while (i2<=length(s2)) and
-                (s2[i2] in ['0'..'9']) do
-             inc(i2);
-          { one of the strings misses digits -> other is the largest version }
-          if i1=start1 then
-            if i2=start2 then
-              exit(0)
-            else
-              exit(-1)
-          else if i2=start2 then
-            exit(1);
-          { get version number part }
-          val(copy(s1,start1,i1-start1),num1,err);
-          val(copy(s2,start2,i2-start2),num2,err);
-          { different -> done }
-          res:=num1-num2;
-          if res<>0 then
-            exit(res);
-          { if one of the two is at the end while the other isn't, add a '.0' }
-          if (i1>length(s1)) and
-             (i2<=length(s2)) then
-            s1:=s1+'.0';
-          if (i2>length(s2)) and
-             (i1<=length(s1)) then
-             s2:=s2+'.0';
-          { compare non-numerical characters normally }
-          while (i1<=length(s1)) and
-                not(s1[i1] in ['0'..'9']) and
-                (i2<=length(s2)) and
-                not(s2[i2] in ['0'..'9']) do
-            begin
-              res:=ord(s1[i1])-ord(s2[i2]);
-              if res<>0 then
-                exit(res);
-              inc(i1);
-              inc(i2);
-            end;
-          { both should be digits again now, otherwise pick the one with the
-            digits as the largest (it more likely means that the input was
-            ill-formatted though) }
-          if (i1<=length(s1)) and
-             not(s1[i1] in ['0'..'9']) then
-            exit(-1);
-          if (i2<=length(s2)) and
-             not(s2[i2] in ['0'..'9']) then
-            exit(1);
-        until false;
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                                Ansistring (PChar+Length)
                                Ansistring (PChar+Length)
 *****************************************************************************}
 *****************************************************************************}

+ 5 - 4
compiler/globals.pas

@@ -47,7 +47,7 @@ interface
 {$if defined(LLVM) or defined(GENERIC_CPU)}
 {$if defined(LLVM) or defined(GENERIC_CPU)}
       llvminfo,
       llvminfo,
 {$endif LLVM or GENERIC_CPU}
 {$endif LLVM or GENERIC_CPU}
-      globtype,version,systems;
+      globtype,version,versioncmp,systems;
 
 
     const
     const
        delphimodeswitches =
        delphimodeswitches =
@@ -352,8 +352,9 @@ interface
        GenerateImportSection,
        GenerateImportSection,
        GenerateImportSectionSetExplicitly,
        GenerateImportSectionSetExplicitly,
        RelocSection : boolean;
        RelocSection : boolean;
+
        MacOSXVersionMin,
        MacOSXVersionMin,
-       iPhoneOSVersionMin: string[15];
+       iPhoneOSVersionMin: tversion;
        RelocSectionSetExplicitly : boolean;
        RelocSectionSetExplicitly : boolean;
 
 
        current_tokenpos,                  { position of the last token }
        current_tokenpos,                  { position of the last token }
@@ -1706,8 +1707,8 @@ implementation
         GenerateImportSection:=false;
         GenerateImportSection:=false;
         RelocSection:=false;
         RelocSection:=false;
         RelocSectionSetExplicitly:=false;
         RelocSectionSetExplicitly:=false;
-        MacOSXVersionMin:='';
-        iPhoneOSVersionMin:='';
+        MacOSXVersionMin.invalidate;
+        iPhoneOSVersionMin.invalidate;
         { memory sizes, will be overridden by parameter or default for target
         { memory sizes, will be overridden by parameter or default for target
           in options or init_parser }
           in options or init_parser }
         stacksize:=0;
         stacksize:=0;

+ 2 - 2
compiler/llvm/nllvmutil.pas

@@ -49,7 +49,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      verbose,cutils,globals,fmodule,systems,finput,
+      verbose,cutils,globals,fmodule,systems,finput,versioncmp,
       aasmtai,cpubase,llvmbase,aasmllvm,
       aasmtai,cpubase,llvmbase,aasmllvm,
       aasmcnst,nllvmtcon,
       aasmcnst,nllvmtcon,
       symbase,symtable,defutil,
       symbase,symtable,defutil,
@@ -295,7 +295,7 @@ implementation
         begin
         begin
           { Objective-C ABI version }
           { Objective-C ABI version }
           if not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_x86_64_darwin]) or
           if not(target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_x86_64_darwin]) or
-             (CompareVersionStrings(MacOSXVersionMin,'10.5')>=0) then
+             (MacOSXVersionMin.relationto(10,5,0)>=0) then
             objcabiversion:=2
             objcabiversion:=2
           else
           else
             objcabiversion:=1;
             objcabiversion:=1;

+ 35 - 22
compiler/options.pas

@@ -26,7 +26,7 @@ unit options;
 interface
 interface
 
 
 uses
 uses
-  cfileutl,cclasses,
+  cfileutl,cclasses,versioncmp,
   globtype,globals,verbose,systems,cpuinfo,comprsrc;
   globtype,globals,verbose,systems,cpuinfo,comprsrc;
 
 
 Type
 Type
@@ -80,7 +80,7 @@ Type
     MacVersionSet: boolean;
     MacVersionSet: boolean;
     IdfVersionSet: boolean;
     IdfVersionSet: boolean;
     processorstr: TCmdStr;
     processorstr: TCmdStr;
-    function ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
+    function ParseMacVersionMin(out minversion, invalidateversion: tversion; const compvarname, value: string; ios: boolean): boolean;
     procedure MaybeSetDefaultMacVersionMacro;
     procedure MaybeSetDefaultMacVersionMacro;
 {$ifdef XTENSA}
 {$ifdef XTENSA}
     function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean;
     function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean;
@@ -1095,7 +1095,7 @@ begin
 end;
 end;
 
 
 
 
-function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
+function toption.ParseMacVersionMin(out minversion, invalidateversion: tversion; const compvarname, value: string; ios: boolean): boolean;
 
 
   function subval(start,maxlen: longint; out stop: longint): string;
   function subval(start,maxlen: longint; out stop: longint): string;
     var
     var
@@ -1116,12 +1116,14 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
 
 
   var
   var
     temp,
     temp,
-    compvarvalue: string[15];
-    i: longint;
+    compvarvalue,
+    versionstr: string[15];
+    major, minor, patch: cardinal;
+    i, err: longint;
     osx_minor_two_digits: boolean;
     osx_minor_two_digits: boolean;
   begin
   begin
-    minstr:=value;
-    emptystr:='';
+    invalidateversion.invalidate;
+    versionstr:=value;
     MacVersionSet:=false;
     MacVersionSet:=false;
     { check whether the value is a valid version number }
     { check whether the value is a valid version number }
     if value='' then
     if value='' then
@@ -1138,10 +1140,16 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
     if (i>=length(value)) or
     if (i>=length(value)) or
        (value[i]<>'.') then
        (value[i]<>'.') then
       exit(false);
       exit(false);
+    val(compvarvalue,major,err);
+    if err<>0 then
+      exit(false);
     { minor version number }
     { minor version number }
     temp:=subval(i+1,2,i);
     temp:=subval(i+1,2,i);
     if temp='' then
     if temp='' then
       exit(false);
       exit(false);
+    val(temp,minor,err);
+    if err<>0 then
+      exit(false);
     { on Mac OS X, the minor version number was originally limited to 1 digit;
     { on Mac OS X, the minor version number was originally limited to 1 digit;
       with 10.10 the format changed and two digits were also supported; on iOS,
       with 10.10 the format changed and two digits were also supported; on iOS,
       the minor version number always takes up two digits }
       the minor version number always takes up two digits }
@@ -1158,6 +1166,7 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
       temp:='0'+temp;
       temp:='0'+temp;
     compvarvalue:=compvarvalue+temp;
     compvarvalue:=compvarvalue+temp;
     { optional patch level }
     { optional patch level }
+    patch:=0;
     if i<=length(value) then
     if i<=length(value) then
       begin
       begin
         if value[i]<>'.' then
         if value[i]<>'.' then
@@ -1188,19 +1197,23 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
         { must be the end }
         { must be the end }
         if i<=length(value) then
         if i<=length(value) then
           exit(false);
           exit(false);
+        val(temp,patch,err);
+        if err<>0 then
+          exit(false);
       end
       end
     else if not ios and
     else if not ios and
        not osx_minor_two_digits then
        not osx_minor_two_digits then
       begin
       begin
         compvarvalue:=compvarvalue+'0';
         compvarvalue:=compvarvalue+'0';
-        minstr:=minstr+'.0'
+        versionstr:=versionstr+'.0'
       end
       end
     else
     else
       begin
       begin
         compvarvalue:=compvarvalue+'00';
         compvarvalue:=compvarvalue+'00';
         { command line versions still only use one 0 though }
         { command line versions still only use one 0 though }
-        minstr:=minstr+'.0'
+        versionstr:=versionstr+'.0'
       end;
       end;
+    minversion.init(versionstr,major,minor,patch);
     set_system_compvar(compvarname,compvarvalue);
     set_system_compvar(compvarname,compvarvalue);
     MacVersionSet:=true;
     MacVersionSet:=true;
     result:=true;
     result:=true;
@@ -1306,7 +1319,7 @@ begin
           begin
           begin
 {$ifdef llvm}
 {$ifdef llvm}
              { We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 }
              { We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 }
-            if CompareVersionStrings(MacOSXVersionMin,'10.6')<=0 then
+            if MacOSXVersionMin.relationto(10,6,0)<0 then
               Message1(option_invalid_macosx_deployment_target,envstr);
               Message1(option_invalid_macosx_deployment_target,envstr);
 {$endif}
 {$endif}
             exit;
             exit;
@@ -1325,36 +1338,36 @@ begin
   case target_info.system of
   case target_info.system of
     system_powerpc_darwin:
     system_powerpc_darwin:
       begin
       begin
-        set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1030');
-        MacOSXVersionMin:='10.3.0';
+        if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.3.0',false) then
+          internalerror(2022090910);
       end;
       end;
     system_powerpc64_darwin:
     system_powerpc64_darwin:
       begin
       begin
-        set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1040');
-        MacOSXVersionMin:='10.4.0';
+        if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.4.0',false) then
+          internalerror(2022090911);
       end;
       end;
     system_i386_darwin,
     system_i386_darwin,
     system_x86_64_darwin:
     system_x86_64_darwin:
       begin
       begin
-        set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1080');
-        MacOSXVersionMin:='10.8.0';
+        if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.8.0',false) then
+          internalerror(2022090912);
       end;
       end;
     system_arm_ios,
     system_arm_ios,
     system_i386_iphonesim:
     system_i386_iphonesim:
       begin
       begin
-        set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000');
-        iPhoneOSVersionMin:='9.0.0';
+        if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
+          internalerror(2022090913);
       end;
       end;
     system_aarch64_ios,
     system_aarch64_ios,
     system_x86_64_iphonesim:
     system_x86_64_iphonesim:
       begin
       begin
-        set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','90000');
-        iPhoneOSVersionMin:='9.0.0';
+        if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
+          internalerror(2022090914);
       end;
       end;
     system_aarch64_darwin:
     system_aarch64_darwin:
       begin
       begin
-        set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','110000');
-        MacOSXVersionMin:='11.0.0';
+        if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','11.00.0',false) then
+          internalerror(2022090915);
       end
       end
     else
     else
       internalerror(2012031001);
       internalerror(2012031001);

+ 20 - 20
compiler/systems/t_darwin.pas

@@ -173,14 +173,14 @@ implementation
                   system_x86_64_darwin:
                   system_x86_64_darwin:
                     begin
                     begin
                       { 10.8 and later: no crt1.* }
                       { 10.8 and later: no crt1.* }
-                      if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then
+                      if MacOSXVersionMin.relationto(10,8,0)>=0 then
                         exit('');
                         exit('');
                       { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }
                       { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }
                       { others: crt1.10.5 -> crt1.o }
                       { others: crt1.10.5 -> crt1.o }
                       if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and
                       if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and
-                         (CompareVersionStrings(MacOSXVersionMin,'10.6')>=0) then
+                         (MacOSXVersionMin.relationto(10,6,0)>=0) then
                         exit('crt1.10.6.o');
                         exit('crt1.10.6.o');
-                      if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
+                      if MacOSXVersionMin.relationto(10,5,0)>=0 then
                         exit('crt1.10.5.o');
                         exit('crt1.10.5.o');
                     end;
                     end;
                   system_arm_ios:
                   system_arm_ios:
@@ -190,9 +190,9 @@ implementation
                           iOS 3.1 - 5.x: crt1.3.1.o
                           iOS 3.1 - 5.x: crt1.3.1.o
                           pre-iOS 3.1: crt1.o
                           pre-iOS 3.1: crt1.o
                       }
                       }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then
+                      if iPhoneOSVersionMin.relationto(6,0,0)>=0 then
                         exit('');
                         exit('');
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
+                      if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
                         exit('crt1.3.1.o');
                         exit('crt1.3.1.o');
                     end;
                     end;
                   system_i386_iphonesim,
                   system_i386_iphonesim,
@@ -202,7 +202,7 @@ implementation
                         What those recent versions could be, is anyone's guess. It
                         What those recent versions could be, is anyone's guess. It
                         still seems to work with 8.1 and no longer with 8.3, so use
                         still seems to work with 8.1 and no longer with 8.3, so use
                         8.1 as a cut-off point }
                         8.1 as a cut-off point }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
+                      if iPhoneOSVersionMin.relationto(8,1,0)>0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_aarch64_ios,
                   system_aarch64_ios,
@@ -220,7 +220,7 @@ implementation
                 result:='gcrt1.o';
                 result:='gcrt1.o';
                 { 10.8 and later: tell the linker to use 'start' instead of "_main"
                 { 10.8 and later: tell the linker to use 'start' instead of "_main"
                   as entry point }
                   as entry point }
-                if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then
+                if MacOSXVersionMin.relationto(10,8,0)>=0 then
                   Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main';
                   Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main';
               end;
               end;
           end
           end
@@ -236,7 +236,7 @@ implementation
                     begin
                     begin
                       { < 10.6: bundle1.o
                       { < 10.6: bundle1.o
                         >= 10.6: nothing }
                         >= 10.6: nothing }
-                      if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
+                      if MacOSXVersionMin.relationto(10,6,0)>=0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_arm_ios,
                   system_arm_ios,
@@ -244,14 +244,14 @@ implementation
                     begin
                     begin
                       { iOS: < 3.1: bundle1.o
                       { iOS: < 3.1: bundle1.o
                              >= 3.1: nothing }
                              >= 3.1: nothing }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
+                      if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_i386_iphonesim,
                   system_i386_iphonesim,
                   system_x86_64_iphonesim:
                   system_x86_64_iphonesim:
                     begin
                     begin
                       { see rule for crt1.o }
                       { see rule for crt1.o }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
+                      if iPhoneOSVersionMin.relationto(8,1,0)>0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_aarch64_darwin:
                   system_aarch64_darwin:
@@ -273,9 +273,9 @@ implementation
                         = 10.5: dylib1.10.5.o
                         = 10.5: dylib1.10.5.o
                         < 10.5: dylib1.o
                         < 10.5: dylib1.o
                       }
                       }
-                      if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
+                      if MacOSXVersionMin.relationto(10,6,0)>=0 then
                         exit('');
                         exit('');
-                      if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
+                      if MacOSXVersionMin.relationto(10,5,0)>=0 then
                         exit('dylib1.10.5.o');
                         exit('dylib1.10.5.o');
                     end;
                     end;
                   system_arm_ios,
                   system_arm_ios,
@@ -283,14 +283,14 @@ implementation
                     begin
                     begin
                       { iOS: < 3.1: dylib1.o
                       { iOS: < 3.1: dylib1.o
                              >= 3.1: nothing }
                              >= 3.1: nothing }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
+                      if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_i386_iphonesim,
                   system_i386_iphonesim,
                   system_x86_64_iphonesim:
                   system_x86_64_iphonesim:
                     begin
                     begin
                       { see rule for crt1.o }
                       { see rule for crt1.o }
-                      if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
+                      if iPhoneOSVersionMin.relationto(8,1,0)>0 then
                         exit('');
                         exit('');
                     end;
                     end;
                   system_aarch64_darwin:
                   system_aarch64_darwin:
@@ -348,20 +348,20 @@ implementation
 
 
     function tlinkerdarwin.GetLinkVersion: TCmdStr;
     function tlinkerdarwin.GetLinkVersion: TCmdStr;
       begin
       begin
-        if MacOSXVersionMin<>'' then
+        if MacOSXVersionMin.isvalid then
           begin
           begin
-            result:='-macosx_version_min '+MacOSXVersionMin;
+            result:='-macosx_version_min '+MacOSXVersionMin.str;
           end
           end
-        else if iPhoneOSVersionMin<>'' then
+        else if iPhoneOSVersionMin.isvalid then
           begin
           begin
             if target_info.system in [system_i386_iphonesim,system_x86_64_iphonesim] then
             if target_info.system in [system_i386_iphonesim,system_x86_64_iphonesim] then
-              result:='-ios_simulator_version_min '+iPhoneOSVersionMin
+              result:='-ios_simulator_version_min '+iPhoneOSVersionMin.str
             else
             else
-              result:='-iphoneos_version_min '+iPhoneOSVersionMin;
+              result:='-iphoneos_version_min '+iPhoneOSVersionMin.str;
           end
           end
         else
         else
           begin
           begin
-            result:='';
+            internalerror(2022090920)
           end;
           end;
       end;
       end;
 
 

+ 2 - 2
compiler/triplet.pas

@@ -45,9 +45,9 @@ uses
         begin
         begin
           result:=result+'-apple';
           result:=result+'-apple';
           if target_info.system in systems_macosx then
           if target_info.system in systems_macosx then
-            result:=result+'-macosx'+MacOSXVersionMin
+            result:=result+'-macosx'+MacOSXVersionMin.str
           else
           else
-            result:=result+'-ios'+iPhoneOSVersionMin;
+            result:=result+'-ios'+iPhoneOSVersionMin.str;
         end
         end
       else if target_info.system in (systems_linux+systems_android) then
       else if target_info.system in (systems_linux+systems_android) then
         result:=result+'-unknown-linux'
         result:=result+'-unknown-linux'