⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uoptions.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 3 页
字号:



    //Gets the topic of an option.
    function Topic(Index: Cardinal): String; override;
  end;



implementation






{Gets a string representation of the value.
~param Value       the value to get the string of
~param Description description of the value (it's type and so on)
~result a string representation }
function ValueToString(const Value: TOptionValue;
                       const Description: TOptionDescription): String;
const    Bools: array[Boolean] of String = ('False', 'True');
var      i            :Integer;          //counter through all items of the set
begin
 case Description.DataType of
   otString:      Result := Value.StrData;
   otBoolean:     Result := Bools[Value.BoolData];
   otInteger:     Str(Value.IntData, Result);
   otReal:        Str(Value.RealData:1:7, Result);
   otEnumeration: Result := Description.EnumNames[Value.EnumData];
   otSet:         begin
                   Result := '';
                   if SetUsesShortCuts(Description) then
                    begin
                     //for each bit
                     for i := 0 to Description.SetNames.Count - 1 do
                      begin
                       if Value.SetData and (1 shl i) <> 0 then //in the set?
                        Result := Result +                 //add its short cut
                                  Char(Description.SetNames.Objects[i]);
                      end;
                     Result := UpperCase(Result);
                    end
                   else
                    //for each bit
                    for i := 0 to Description.SetNames.Count - 1 do
                     Result := Char(Ord('0') +    //add its value
                                    Ord(Value.SetData and (1 shl i) <> 0)) +
                               Result;
                  end;
 else
  assert(False);
 end;
end;



{Tries to get the value of an option from its string representation.
~param Str         the string representation of an option
~param Value       out: the value of the string
~param Description description of the option
~result if the string is a valid value for the option }
function StringToValue(const Str: String; var Value: TOptionValue;
                       const Description: TOptionDescription): Boolean;
var      Error        :Integer; //index of the error
         Low          :String;  //the value in lower case
         j            :Integer; //counter through the characters of the string
begin
 case Description.DataType of   //parse the string depending on type
   otString:      begin
                   Value.StrData := Str;
                   if (Description.StrMaxLen <> 0) and     //string too long?
                      (Description.StrMaxLen < Length(Str)) then
                    Delete(Value.StrData, Description.StrMaxLen + 1,
                           High(Length(Value.StrData)));     //truncate it
                   Result := True;
                  end;
   otBoolean:     Result := StringToBoolean(Str, Value.BoolData);
   otInteger:     begin
                   Val(Str, Value.IntData, Error);
                   Result := Error = 0;             //is a valid number?
                   if Result and                      //check for the bounds
                      (Description.MinInt <> Description.MaxInt) then
                    if Value.IntData < Description.MinInt then
                     Value.IntData := Description.MinInt
                    else
                     if Value.IntData > Description.MaxInt then
                      Value.IntData := Description.MaxInt
                  end;
   otReal:        begin
                   Val(Str, Value.RealData, Error);
                   Result := Error = 0;             //is a valid number?
                   if Result and                      //check for the bounds
                      (Description.MinReal <> Description.MinReal) then
                    if Value.RealData < Description.MinReal then
                     Value.RealData := Description.MinReal
                    else
                     if Value.RealData > Description.MaxReal then
                      Value.RealData := Description.MaxReal
                  end;
   otEnumeration: begin                //name of an item of the enumeration?
                   Value.EnumData := Description.EnumNames.IndexOf(Str);
                   Result := Value.EnumData <> -1;
                   if not Result then  //not a valid name?
                    begin                       //try to interpret it as the
                     Val(Str, Value.EnumData, Error);    //index of an item
                     Result := (Error = 0) and (Value.EnumData >= 0) and
                               (Value.EnumData < Description.EnumNames.Count);
                    end;
                  end;
   otSet:         begin
                   Low := Trim(Str);
                   //valid short cuts defined for the enumeration?
                   Result := SetUsesShortCuts(Description);
                   if Result then
                    begin
                     Low := LowerCase(Low);
                     Value.SetData := 0;            //set is empty so far
                     for j := 1 to Length(Low) do   //check each character, if
                      begin                          //it is a valid short cut
                       Error := Description.SetNames.IndexOfObject(
                                                              TObject(Low[j]));
                       if Error <> -1 then
                        Value.SetData := Value.SetData or (1 shl Error)
                       else
                        Result := False;
                      end;
                    end;

                   if not Result then               //no short cuts?
                    begin                             //is a bit-mask
                     Result := (Low <> '') and
                               (Length(Low) <= Description.SetNames.Count);
                     if Result then                   //correct length?
                      begin
                       Value.SetData := 0;
                       for j := 1 to Length(Low) do     //check each character
                        begin                             //if it is a binary
                         Result := Result and (Low[j] in ['0', '1']); //digit
                         if Low[j] = '1' then             //"1" means the item
                          Value.SetData := Value.SetData or //is in the set
                                            (1 shl (Length(Low) - j));
                        end;
                      end;
                    end;
                  end;
 else
  Assert(False);
  Result := False;
 end;
end;



{Tries to get a boolean value from its string representation.
~param Str   the string representation of the boolean value
~param Value out: the value of the string
~result if the string is a valid boolean value }
function StringToBoolean(const Str: String; var Value: Boolean): Boolean;
var      IntValue       :Integer;      //the integer value of the string
         Error          :Integer;      //index of the error
         Low            :String;       //the value in lower case
begin
 val(Str, IntValue, Error);            //check if it is a number
 if Error = 0 then                     //is a number?
  begin
   Value := IntValue <> 0;               //0 is false
   Result := True;
  end
 else
  begin
   Low := LowerCase(Str);                //get lower case value
   Value := (Low = 'on') or              //has a "true" meaning?
            (Low = 'true') or
            (Low = 'yes') or
            (Low = 'enable') or
            (Low = 'enabled') or
            (Low = '1');
   Result := Value or (Low = 'off') or   //either true or false
                      (Low = 'false') or
                      (Low = 'no') or
                      (Low = 'disable') or
                      (Low = 'disabled') or
                      (Low = '0');
  end;
end;





type     PByte = ^Byte;             //type to access a set of size 1 byte
         PWORD = ^Word;             //type to access a set of size 2 bytes
         PDWORD = ^Longword;        //type to access a set of size 4 bytes


{Extracts a set to a bit-masked number.
~param TheSet    the set
~param SizeOfSet the size of the set
~param BaseIndex ordinal value of the lowest possible item of the set
~result the bit-masked number representing the set }
function SetToOption(const TheSet; SizeOfSet: Integer;
                     BaseIndex: Integer = 0): TOptionSetType;
begin
 case SizeOfSet of
   1: Result := PByte(@TheSet)^;
   2: Result := PWORD(@TheSet)^;
   4: Result := PDWORD(@TheSet)^;
 else
  raise Exception.Create('Invalid size of set, probably too big!');
 end;
 Result := Result shr BaseIndex;    //adjust set for the base index
end;

{Assigns a bit-masked number to a set.
~param Value     the bit-masked number representing the set
~param TheSet    the set
~param SizeOfSet the size of the set
~param BaseIndex ordinal value of the lowest possible item of the set }
procedure OptionToSet(Value: TOptionSetType; var TheSet; SizeOfSet: Integer;
                      BaseIndex: Integer = 0);
begin
 Value := Value shl BaseIndex;      //adjust set for the base index
 case SizeOfSet of
   1: PByte(@TheSet)^ := Value;
   2: PWORD(@TheSet)^ := Value;
   4: PDWORD(@TheSet)^ := Value;
 else
  raise Exception.Create('Invalid size of set, probably too big!');
 end;
end;


{Checks whether the set uses short cuts.
~param Description the description of the set to check
~result if the set uses short cuts }
function SetUsesShortCuts(const Description: TOptionDescription): Boolean;
var      i               :Integer;      //counter through the set
{$IFOPT C+}
         j               :Integer;      //counter to check for valid short cuts
{$ENDIF}
begin
 assert(Description.DataType = otSet);

 i := Description.SetNames.Count - 1;          //for each item, check if it has
 assert(i >= 0);
 while (i >= 0) and assigned(Description.SetNames.Objects[i]) do  //a short cut
  begin

{$IFOPT C+}
   assert(not (Char(Description.SetNames.Objects[i]) in ['A'..'Z']));
   for j := 0 to i - 1 do
    assert(Description.SetNames.Objects[i] <> Description.SetNames.Objects[j]);
{$ENDIF}

   dec(i);                                       //next option
  end;

 Result := i < 0;                       //all items have a short cut?
 assert(Result or (i = Description.SetNames.Count - 1));
end;




{Clears the description structure.
~param Description the structure to clear }
procedure ClearDescription(var Description: TOptionDescription);
begin
 Description.Name := '';                         //free strings
 Description.Category := '';
 Description.Description := '';
 Description.DefaultValue.StrData := '';
 FillChar(Description, SizeOf(Description), 0);  //clear structure
end;





















   { * * *  ***  * * *  ***   TOptionWrapper   ***  * * *  ***  * * *  }




{Returns the current class if the options are loaded in a hierarchy.
~result the actual class }
function TOptionWrapper.GetStartClass: TClass;
begin
 raise Exception.Create('No hierarchical loading of options supported!');
end;




{Gets the topic of the options. '' is the default and means no topic is
 available.
~result the topic of the options }
function TOptionWrapper.DefaultTopic: String;
begin
 if Assigned(FBaseClass) then
  Result := GetStartClass.ClassName
 else
  Result := '';
end;

{Gets the topic of an option. '' is the default and means no topics used.
~param Index index of the option to get the topic of
~result the topic of the option }
function TOptionWrapper.Topic(Index: Cardinal): String;
begin
 if Index >= Count then
  raise EInvalidOption.Create('Invalid index for option supplied!');

 Result := DefaultTopic;
end;












{Gets the index of an option by its name (and type).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -