Search code examples
inno-setuppascalscript

Why do I get "Variable Expected" compiler error?


I'm trying to get the drive letter of the install path in Inno Setup without the colon and if the drive letter is C, it will return a null string.

Calling the function:

{code:GetDriveLetter|{drive:{src}}

Function:

function GetDriveLetter(DriveLetter: string): string;
var
  len: Integer;
begin
  len := CompareText(UpperCase(DriveLetter), 'C');
  if len = 0 then
  begin
    Result := '';
  end
  else
  begin
    Result := Delete(UpperCase(DriveLetter), 2, 1);
  end;
end;

I'm getting the compiler error:

Variable Expected

on this line:

Result := Delete(UpperCase(DriveLetter), 2, 1);

What's the problem with that line? How can I fix this function?


Solution

  • The Variable Expected compiler error you got because Delete is a procedure into which you are expected to pass a declared string type variable (which is then internally modified). And you are not passing a variable but an intermediate result of the UpperCase function call. So to fix this error you can either declare a variable, or use the predeclared Result one, e.g.:

    var
      S: string;
    begin
      S := UpperCase('a');
      Delete(S, 2, 1);
    end;
    

    Except that I would point out a few things. Delete is a procedure, and as such doesn't return any value, so even if you'd pass there a declared variable, you'd fail on a non-existing result assignment. The CompareText function is already a case insensitive comparison, so there's no need for upper-casing the input. And except that I would not compare the whole input (which is e.g. C: as returned by the drive: constant), but only the first character (but it depends on how safe you want to make your function). For only the first character comparison I would write something like this:

    [Code]
    function GetDriveLetter(Drive: string): string;
    begin
      // we will upper case the first letter of the Drive parameter (if that parameter is
      // empty, we'll get an empty result)
      Result := UpperCase(Copy(Drive, 1, 1));
      // now check if the previous operation succeeded and we have in our Result variable
      // exactly 1 char and if we have, check if that char is the one for which we want to
      // return an empty string; if that is so, return an empty string
      if (Length(Result) = 1) and (Result[1] = 'C') then
        Result := '';
    end;