Darwin version comparisons: factored out into object

Use numeric instead of string comparisons
This commit is contained in:
Jonas Maebe 2022-09-09 15:00:43 +02:00
parent 657b9a6203
commit b26703feaa
6 changed files with 64 additions and 117 deletions

View File

@ -133,7 +133,6 @@ interface
function DePascalQuote(var s: ansistring): Boolean;
function CompareStr(const 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 }
{ if p=nil then freemem isn't called }
@ -1275,72 +1274,6 @@ implementation
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)
*****************************************************************************}

View File

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

View File

@ -49,7 +49,7 @@ interface
implementation
uses
verbose,cutils,globals,fmodule,systems,finput,
verbose,cutils,globals,fmodule,systems,finput,versioncmp,
aasmtai,cpubase,llvmbase,aasmllvm,
aasmcnst,nllvmtcon,
symbase,symtable,defutil,
@ -295,7 +295,7 @@ implementation
begin
{ Objective-C ABI version }
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
else
objcabiversion:=1;

View File

@ -26,7 +26,7 @@ unit options;
interface
uses
cfileutl,cclasses,
cfileutl,cclasses,versioncmp,
globtype,globals,verbose,systems,cpuinfo,comprsrc;
Type
@ -80,7 +80,7 @@ Type
MacVersionSet: boolean;
IdfVersionSet: boolean;
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;
{$ifdef XTENSA}
function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean;
@ -1095,7 +1095,7 @@ begin
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;
var
@ -1116,12 +1116,14 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
var
temp,
compvarvalue: string[15];
i: longint;
compvarvalue,
versionstr: string[15];
major, minor, patch: cardinal;
i, err: longint;
osx_minor_two_digits: boolean;
begin
minstr:=value;
emptystr:='';
invalidateversion.invalidate;
versionstr:=value;
MacVersionSet:=false;
{ check whether the value is a valid version number }
if value='' then
@ -1138,10 +1140,16 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
if (i>=length(value)) or
(value[i]<>'.') then
exit(false);
val(compvarvalue,major,err);
if err<>0 then
exit(false);
{ minor version number }
temp:=subval(i+1,2,i);
if temp='' then
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;
with 10.10 the format changed and two digits were also supported; on iOS,
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;
compvarvalue:=compvarvalue+temp;
{ optional patch level }
patch:=0;
if i<=length(value) then
begin
if value[i]<>'.' then
@ -1188,19 +1197,23 @@ function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarn
{ must be the end }
if i<=length(value) then
exit(false);
val(temp,patch,err);
if err<>0 then
exit(false);
end
else if not ios and
not osx_minor_two_digits then
begin
compvarvalue:=compvarvalue+'0';
minstr:=minstr+'.0'
versionstr:=versionstr+'.0'
end
else
begin
compvarvalue:=compvarvalue+'00';
{ command line versions still only use one 0 though }
minstr:=minstr+'.0'
versionstr:=versionstr+'.0'
end;
minversion.init(versionstr,major,minor,patch);
set_system_compvar(compvarname,compvarvalue);
MacVersionSet:=true;
result:=true;
@ -1306,7 +1319,7 @@ begin
begin
{$ifdef llvm}
{ 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);
{$endif}
exit;
@ -1325,36 +1338,36 @@ begin
case target_info.system of
system_powerpc_darwin:
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;
system_powerpc64_darwin:
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;
system_i386_darwin,
system_x86_64_darwin:
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;
system_arm_ios,
system_i386_iphonesim:
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;
system_aarch64_ios,
system_x86_64_iphonesim:
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;
system_aarch64_darwin:
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
else
internalerror(2012031001);

View File

@ -173,14 +173,14 @@ implementation
system_x86_64_darwin:
begin
{ 10.8 and later: no crt1.* }
if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then
if MacOSXVersionMin.relationto(10,8,0)>=0 then
exit('');
{ x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }
{ others: crt1.10.5 -> crt1.o }
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');
if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
if MacOSXVersionMin.relationto(10,5,0)>=0 then
exit('crt1.10.5.o');
end;
system_arm_ios:
@ -190,9 +190,9 @@ implementation
iOS 3.1 - 5.x: crt1.3.1.o
pre-iOS 3.1: crt1.o
}
if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then
if iPhoneOSVersionMin.relationto(6,0,0)>=0 then
exit('');
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit('crt1.3.1.o');
end;
system_i386_iphonesim,
@ -202,7 +202,7 @@ implementation
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
8.1 as a cut-off point }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit('');
end;
system_aarch64_ios,
@ -220,7 +220,7 @@ implementation
result:='gcrt1.o';
{ 10.8 and later: tell the linker to use 'start' instead of "_main"
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';
end;
end
@ -236,7 +236,7 @@ implementation
begin
{ < 10.6: bundle1.o
>= 10.6: nothing }
if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
if MacOSXVersionMin.relationto(10,6,0)>=0 then
exit('');
end;
system_arm_ios,
@ -244,14 +244,14 @@ implementation
begin
{ iOS: < 3.1: bundle1.o
>= 3.1: nothing }
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit('');
end;
system_i386_iphonesim,
system_x86_64_iphonesim:
begin
{ see rule for crt1.o }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit('');
end;
system_aarch64_darwin:
@ -273,9 +273,9 @@ implementation
= 10.5: dylib1.10.5.o
< 10.5: dylib1.o
}
if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
if MacOSXVersionMin.relationto(10,6,0)>=0 then
exit('');
if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
if MacOSXVersionMin.relationto(10,5,0)>=0 then
exit('dylib1.10.5.o');
end;
system_arm_ios,
@ -283,14 +283,14 @@ implementation
begin
{ iOS: < 3.1: dylib1.o
>= 3.1: nothing }
if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
if iPhoneOSVersionMin.relationto(3,1,0)>=0 then
exit('');
end;
system_i386_iphonesim,
system_x86_64_iphonesim:
begin
{ see rule for crt1.o }
if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
if iPhoneOSVersionMin.relationto(8,1,0)>0 then
exit('');
end;
system_aarch64_darwin:
@ -348,20 +348,20 @@ implementation
function tlinkerdarwin.GetLinkVersion: TCmdStr;
begin
if MacOSXVersionMin<>'' then
if MacOSXVersionMin.isvalid then
begin
result:='-macosx_version_min '+MacOSXVersionMin;
result:='-macosx_version_min '+MacOSXVersionMin.str;
end
else if iPhoneOSVersionMin<>'' then
else if iPhoneOSVersionMin.isvalid then
begin
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
result:='-iphoneos_version_min '+iPhoneOSVersionMin;
result:='-iphoneos_version_min '+iPhoneOSVersionMin.str;
end
else
begin
result:='';
internalerror(2022090920)
end;
end;

View File

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