“Type mismatch” error on “set of char” in Pascal Script of the Inno Setup Unicode version

爷,独闯天下 提交于 2019-12-08 08:12:56

问题


I have an working Pascal scripts for Inno Setup, but recently we ran into an issue with Unicode characters. And after changing the Inno Setup to Unicode version we got errors in existing scripts. And this error is too generic - "Type mismatch" for certain line. Since our main script is composed of lots of other scripts that are included I'm not sure if that line is the correct, and it points to this function below, and line with Set of Char. After looking the Inno Setup documentation I found that Unicode version is bit more strict about some things, and also there was some changes around ANSI string handling (and probably Char as well).

function IsValidName(Name: String):String;
var
  Valid_Ch: Set of Char;
  Location: Integer;
begin
    Valid_Ch := ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-'];
    Result := '';
    for Location := 1 to Length(Name) do
    begin
        if Name[Location] in Valid_Ch then
        begin
            Result := Result + Name[Location];
        end
        else
        begin
            Result := Result + '_';
        end;
    end;    
end;

This all looks fine to me, but this is my first touch with Pascal. I would be thankful if someone more experienced could help me about this. Thanks!


回答1:


In Pascal (Script) the set can contain 256 (2^8) values only. In Unicode Inno Setup the Char is 2-byte, hence it can contain a way more than 256 different values. So you cannot use it with set anymore.

You have these options:

  • In your case, as the set is in fact constant, you can use a constant set in the if expression. Interestingly, that works even in Unicode version (possibly there's some hack built in that allows this exception).

    function IsValidName(Name: string): string;
    var
      Location: Integer;
    begin
      Result := Name;
      for Location := 1 to Length(Name) do
      begin
        if not (Name[Location] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-']) then
        begin
          Result[Location] := '_';
        end;
      end;    
    end;
    

Had you needed the set to be variable (not your case):

  • Use Byte and cast between Char and Byte and explicitly replace all characters with Ord() > 255
  • Or use a string instead of the set. For an example, see below.

    function IsValidName(Name: string): string;
    var
      Valid_Ch: string;
      Location: Integer;
    begin
      Valid_Ch := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-';
      Result := Name;
      for Location := 1 to Length(Result) do
      begin
        if Pos(Result[Location], Valid_Ch) = 0 then
        begin
          Result[Location] := '_';
        end;
      end;    
    end;
    

Also note that appending the string char-by-char can be pretty inefficient. Replace the characters in-place instead (as shown in both examples above).



来源:https://stackoverflow.com/questions/36620723/type-mismatch-error-on-set-of-char-in-pascal-script-of-the-inno-setup-unicod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!