I'm using an Inno Setup #define directive to define all of the information about a software package in my installer and then other directives to extract portions of that string. So for example, using the following, PartNumber(Package1)
will return 05414.
#define Package1 "05414 - My Package"
#define PartNumber(str Package) Copy(Package, 1, 5)
I'm using this approach in scripts and code and it works fine. However, I've got a situation where it would be convenient to programmatically generate the string and I'm having trouble getting it to work. For example, I'd like to do something like the following.
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber:= ExpandConstant(Format('{#PartNumber(%s)}', [Package]));
end;
procedure Bar();
begin
Foo(ExpandConstant('{#Package1)}'));
end;
The Package
argument to Foo
is correct, but I get a compiler error saying
[ISPP] No argument for format '%'".
It seems that it doesn't like the #
in the string on the PartNumber
line. Even including a #
in a normal string gives an "unterminated preprocessor directive" error, so I think it's interpreting the #
as a precision specifier or something.
Is there a way to make it treat #
as part of the text so that I can programmatically expand this constant? If not, if there some other way I can achieve this?
This cannot work.
The PartNumber
is a preprocessor function/macro. It's evaluated on compile time. It does not exist on run time.
You can, of course, implement an equivalent Pascal Script function:
function PartNumberPascal(Package: string): string;
begin
Result := Copy(Package, 1, 5);
end;
procedure Foo(Package: String);
var
PartNumber: String;
begin
PartNumber := PartNumberPascal(Package);
end;
What probably confuses you, is this call:
Foo(ExpandConstant('{#Package1}'));
It may give you an impression that the ExpandConstant
function expands the Package1
preprocessor define.
It does not!
The {#...}
syntax (contrary to the {...}
) is not a constant. It's an inline preprocessor directive call, where, when no directive is explicitly specified, the emit
is implied. So the {#Package1}
is the same as {#emit Package1}
. And as every preprocessor construct, it's evaluated on compile time.
If you add SaveToFile
preprocessor function call to the end of the script:
procedure Bar();
begin
Foo(ExpandConstant('{#Package1}'));
end;
#expr SaveToFile(AddBackslash(SourcePath) + "Preprocessed.iss")
And after compilation, check, what the Preprocessed.iss
is like. You will see:
procedure Bar();
begin
Foo(ExpandConstant('05414 - My Package'));
end;
The Package1
is expanded to its value. But the ExpandConstant
is still there, and hence it's totally useless! (there are no constants in the '05414 - My Package'
)
This would have the same effect:
procedure Bar();
begin
Foo('{#Package1}');
end;