Kaynağa Gözat

Add new support functions StringJoin, StringSplit, and StringSplitEx. Todo: doc.

Martijn Laan 10 ay önce
ebeveyn
işleme
6f13b4782b

+ 2 - 0
Projects/Src/Compiler.ScriptFunc.pas

@@ -105,6 +105,8 @@ begin
   RegisterRealEnum('TSetupProcessorArchitecture', TypeInfo(TSetupProcessorArchitecture));
   RegisterRealEnum('TSetupProcessorArchitecture', TypeInfo(TSetupProcessorArchitecture));
   RegisterRealEnum('TDotNetVersion', TypeInfo(TDotNetVersion));
   RegisterRealEnum('TDotNetVersion', TypeInfo(TDotNetVersion));
 
 
+  RegisterType('TSplitType', '(stAll, stExcludeEmpty, stExcludeLastEmpty)'); //must be compatible with System.SysUtils.TStringSplitOptions
+
   RegisterType('TExecWait', '(ewNoWait, ewWaitUntilTerminated, ewWaitUntilIdle)');
   RegisterType('TExecWait', '(ewNoWait, ewWaitUntilTerminated, ewWaitUntilIdle)');
 
 
   RegisterType('TExecOutput',
   RegisterType('TExecOutput',

+ 4 - 3
Projects/Src/IDE.ScintStylerInnoSetup.pas

@@ -451,16 +451,17 @@ const
     { ScriptFunc's real enums, values done via PascalRealEnumValues instead of PascalEnumValues}
     { ScriptFunc's real enums, values done via PascalRealEnumValues instead of PascalEnumValues}
     'TMsgBoxType', 'TSetupMessageID', 'TSetupStep', 'TUninstallStep',
     'TMsgBoxType', 'TSetupMessageID', 'TSetupStep', 'TUninstallStep',
     'TSetupProcessorArchitecture', 'TDotNetVersion',
     'TSetupProcessorArchitecture', 'TDotNetVersion',
-    { ScriptFunc's non real enums and other types }
+    { ScriptFunc's non real enums and other types - also see PascalEnumValues below }
     'TArrayOfString', 'TArrayOfChar', 'TArrayOfBoolean', 'TArrayOfInteger', 'DWORD',
     'TArrayOfString', 'TArrayOfChar', 'TArrayOfBoolean', 'TArrayOfInteger', 'DWORD',
     'UINT', 'BOOL', 'DWORD_PTR', 'UINT_PTR', 'INT_PTR', 'TFileTime',
     'UINT', 'BOOL', 'DWORD_PTR', 'UINT_PTR', 'INT_PTR', 'TFileTime',
-    'TExecWait', 'TExecOutput', 'TFindRec', 'TWindowsVersion',
+    'TSplitType', 'TExecWait', 'TExecOutput', 'TFindRec', 'TWindowsVersion',
     'TOnDownloadProgress', 'TOnExtractionProgress', 'TOnLog'
     'TOnDownloadProgress', 'TOnExtractionProgress', 'TOnLog'
     { ScriptClasses: see PascalTypes_Isxclasses in isxclasses_wordlists_generated }
     { ScriptClasses: see PascalTypes_Isxclasses in isxclasses_wordlists_generated }
   ];
   ];
 
 
   PascalEnumValues: array of AnsiString = [
   PascalEnumValues: array of AnsiString = [
-    { ScriptFunc's values of non real enums }
+    { ScriptFunc's values of non real enums - also see PascalTypes above }
+    'stAll', 'stExcludeEmpty', 'stExcludeLastEmpty',
     'ewNoWait', 'ewWaitUntilTerminated', 'ewWaitUntilIdle'
     'ewNoWait', 'ewWaitUntilTerminated', 'ewWaitUntilIdle'
     { ScriptClasses: see PascalEnumValues_Isxclasses in isxclasses_wordlists_generated }
     { ScriptClasses: see PascalEnumValues_Isxclasses in isxclasses_wordlists_generated }
   ];
   ];

+ 26 - 1
Projects/Src/Setup.ScriptFunc.pas

@@ -20,7 +20,7 @@ implementation
 
 
 uses
 uses
   Windows, Shared.ScriptFunc,
   Windows, Shared.ScriptFunc,
-  Forms, uPSUtils, SysUtils, Classes, Graphics, Controls, TypInfo, ActiveX,
+  Forms, uPSUtils, SysUtils, Classes, Graphics, Controls, TypInfo, ActiveX, Generics.Collections,
   PathFunc, BrowseFunc, MD5, SHA1, SHA256, ASMInline, BitmapImage,
   PathFunc, BrowseFunc, MD5, SHA1, SHA256, ASMInline, BitmapImage,
   Shared.Struct, Setup.ScriptDlg, Setup.MainForm, Setup.MainFunc, Shared.CommonFunc.Vcl,
   Shared.Struct, Setup.ScriptDlg, Setup.MainForm, Setup.MainFunc, Shared.CommonFunc.Vcl,
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
@@ -1885,6 +1885,7 @@ var
   ErrorCode: Cardinal;
   ErrorCode: Cardinal;
   N, I: Integer;
   N, I: Integer;
   AscendingTrySizes: array of Integer;
   AscendingTrySizes: array of Integer;
+  Values, Separators: array of String;
 begin
 begin
   PStart := Stack.Count-1;
   PStart := Stack.Count-1;
   Result := True;
   Result := True;
@@ -2051,6 +2052,30 @@ begin
     Extract7ZipArchive(Stack.GetString(PStart), Stack.GetString(PStart-1), Stack.GetBool(PStart-2), OnExtractionProgress);
     Extract7ZipArchive(Stack.GetString(PStart), Stack.GetString(PStart-1), Stack.GetBool(PStart-2), OnExtractionProgress);
   end else if Proc.Name = 'DEBUGGING' then begin
   end else if Proc.Name = 'DEBUGGING' then begin
     Stack.SetBool(PStart, Debugging);
     Stack.SetBool(PStart, Debugging);
+  end else if Proc.Name = 'STRINGJOIN' then begin
+    Arr := NewTPSVariantIFC(Stack[PStart-2], True);
+    N := PSDynArrayGetLength(Pointer(Arr.Dta^), Arr.aType);
+    SetLength(Values, N);
+    for I := 0 to N-1 do
+      Values[I] := VNGetString(PSGetArrayField(Arr, I));
+    Stack.SetString(PStart, String.Join(Stack.GetString(PStart-1), Values));
+  end else if (Proc.Name = 'STRINGSPLIT') or (Proc.Name = 'STRINGSPLITEX') then begin
+    Arr := NewTPSVariantIFC(Stack[PStart-2], True);
+    N := PSDynArrayGetLength(Pointer(Arr.Dta^), Arr.aType);
+    SetLength(Separators, N);
+    for I := 0 to N-1 do
+      Separators[I] := VNGetString(PSGetArrayField(Arr, I));
+    var Parts: TArray<String>;
+    if Proc.Name = 'STRINGSPLITEX' then begin
+      var Quote := Stack.GetString(PStart-3)[1];
+      Parts := Stack.GetString(PStart-1).Split(Separators, Quote, Quote, TStringSplitOptions(Stack.GetInt(PStart-4)))
+    end else
+      Parts := Stack.GetString(PStart-1).Split(Separators, TStringSplitOptions(Stack.GetInt(PStart-3)));
+    Arr := NewTPSVariantIFC(Stack[PStart], True);
+    N := Length(Parts);
+    PSDynArraySetLength(Pointer(Arr.Dta^), Arr.aType, N);
+    for I := 0 to N-1 do
+      VNSetString(PSGetArrayField(Arr, I), Parts[I]);
   end else
   end else
     Result := False;
     Result := False;
 end;
 end;

+ 4 - 1
Projects/Src/Shared.ScriptFunc.pas

@@ -541,7 +541,10 @@ initialization
     'function IsMsiProductInstalled(const UpgradeCode: String; const PackedMinVersion: Int64): Boolean;',
     'function IsMsiProductInstalled(const UpgradeCode: String; const PackedMinVersion: Int64): Boolean;',
     'function InitializeBitmapImageFromIcon(const BitmapImage: TBitmapImage; const IconFilename: String; const BkColor: TColor; const AscendingTrySizes: TArrayOfInteger): Boolean;',
     'function InitializeBitmapImageFromIcon(const BitmapImage: TBitmapImage; const IconFilename: String; const BkColor: TColor; const AscendingTrySizes: TArrayOfInteger): Boolean;',
     'procedure Extract7ZipArchive(const ArchiveFileName, DestDir: String; const FullPaths: Boolean; const OnExtractionProgress: TOnExtractionProgress);',
     'procedure Extract7ZipArchive(const ArchiveFileName, DestDir: String; const FullPaths: Boolean; const OnExtractionProgress: TOnExtractionProgress);',
-    'function Debugging: Boolean;'
+    'function Debugging: Boolean;',
+    'function StringJoin(const Separator: String; const Values: TArrayOfString): String;',
+    'function StringSplit(const S: String; const Separators: TArrayOfString; const Typ: TSplitType): TArrayOfString;',
+    'function StringSplitEx(const S: String; const Separators: TArrayOfString; const Quote: Char; const Typ: TSplitType): TArrayOfString;'
   ];
   ];
 
 
   {$IFDEF COMPIL32PROJ}
   {$IFDEF COMPIL32PROJ}

+ 1 - 0
whatsnew.htm

@@ -97,6 +97,7 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
   <ul>
   <ul>
     <li>Added new <tt>Extract7ZipArchive</tt> support function to extract a 7-Zip archive, based on the &quot;7z ANSI-C Decoder&quot; from the LZMA SDK by Igor Pavlov. See the new <a href="https://jrsoftware.org/ishelp/index.php?topic=isxfunc_extract7ziparchive">help topic</a> for information about its limitations.<br />Added new <tt>CreateExtractionPage</tt> support function to easily show the extraction progress to the user.</li>
     <li>Added new <tt>Extract7ZipArchive</tt> support function to extract a 7-Zip archive, based on the &quot;7z ANSI-C Decoder&quot; from the LZMA SDK by Igor Pavlov. See the new <a href="https://jrsoftware.org/ishelp/index.php?topic=isxfunc_extract7ziparchive">help topic</a> for information about its limitations.<br />Added new <tt>CreateExtractionPage</tt> support function to easily show the extraction progress to the user.</li>
     <li>Added new <tt>ExecAndCaptureOutput</tt> support function to execute a program or batch file and capture its <i>stdout</i> and <i>stderr</i> outputs separately.</li>
     <li>Added new <tt>ExecAndCaptureOutput</tt> support function to execute a program or batch file and capture its <i>stdout</i> and <i>stderr</i> outputs separately.</li>
+    <li>Added new <tt>StringJoin</tt>, <tt>StringSplit</tt>, and <tt>StringSplitEx</tt> support functions.</li>
     <li>Output logging now raises an exception if there was an error setting up output redirection (which should be very rare). The <i>PowerShell.iss</i> example script has been updated to catch the exception.</li>
     <li>Output logging now raises an exception if there was an error setting up output redirection (which should be very rare). The <i>PowerShell.iss</i> example script has been updated to catch the exception.</li>
     <li><tt>TInputDirWizardPage</tt>: Added new <tt>NewFolderName</tt> property to update the initial value passed to <tt>CreateInputDirPage</tt>.</li>
     <li><tt>TInputDirWizardPage</tt>: Added new <tt>NewFolderName</tt> property to update the initial value passed to <tt>CreateInputDirPage</tt>.</li>
     <li>Documented support functions <tt>VarArrayGet</tt> and <tt>VarArraySet</tt> which were already available but not documented.</li>
     <li>Documented support functions <tt>VarArrayGet</tt> and <tt>VarArraySet</tt> which were already available but not documented.</li>