My light version of a Command-line parsing with Delphi attribute ; it's a Primož Gabrijelčič 's idea, found in ITDevCon 2013 Pdf. (no source so I writed it!)

My light version of a Command-line parsing with Delphi attribute ; it's a Primož Gabrijelčič 's idea, found in ITDevCon 2013 Pdf. (no source so I writed it!)

interface

uses rtti;

type
  ParamNameAttribute = class(TCustomAttribute)
  protected
    FName:string;
    FDefaultValue:TValue;
  public
    constructor Create(const AName:string);overload;
    constructor Create(const AName:string; const ADefaultValue:string);overload;
    constructor Create(const AName:string; const ADefaultValue:boolean);overload;
    constructor Create(const AName:string; const ADefaultValue:Integer);overload;

    property Name:string         read FName;
    property DefaultValue:TValue read FDefaultValue;
  end;

  TCmdLine = class(TObject)
  public
    constructor Create;
  end;

implementation

uses sysutils;

{ ParamNameAttribute }

constructor ParamNameAttribute.Create(const AName: string);
begin
  FName := AName;
end;

constructor ParamNameAttribute.Create(const AName, ADefaultValue: string);
begin
  Create(AName);
  FDefaultValue := ADefaultValue;
end;

constructor ParamNameAttribute.Create(const AName: string;
  const ADefaultValue: boolean);
begin
  Create(AName);
  FDefaultValue := ADefaultValue;
end;

constructor ParamNameAttribute.Create(const AName: string;
  const ADefaultValue: Integer);
begin
  Create(AName);
  FDefaultValue := ADefaultValue;
end;

{ TCmdLine }

// the core
constructor TCmdLine.Create;
var
  ctx:TRttiContext;
  t:TRttiType;
  field:TRttiField;
  attr:TCustomAttribute;
  param:ParamNameAttribute;
  value:string;
  bfound:boolean;
begin
  ctx := TRttiContext.Create;
  try
    t := ctx.GetType(Self.ClassType);
    for field in t.GetFields do
      for attr in field.GetAttributes do
        if attr is ParamNameAttribute then
        begin
          param := ParamNameAttribute(attr);
          value := '';
          bfound := FindCmdLineSwitch(param.Name, value, true, [clstValueAppended]);
          if bfound then
          begin
            if field.FieldType.Handle = typeinfo(boolean)  then
              field.SetValue(Self, true)
            else
              field.SetValue(Self, value);
          end
          else
          if not param.DefaultValue.IsEmpty  then
            field.SetValue(Self, param.DefaultValue);
        end;
  finally
    ctx.Free;
  end;
end;

It's simple and very useful :

example :

  TMyCmdLine = class(TCmdLine)
  protected
    [ParamName('importdir','c:\tmp\')]
    FImportFolder: string;
    [ParamName('logsoapdetails')]
    FLogDetails: boolean;
    [ParamName('user', 'guest')]
    FUsername: string;
    [ParamName('debug')]
    FDebug:boolean;
  public
    property ImportFolder:string read FImportFolder;
    property LogDetails:boolean  read FLogDetails;
    property Username:string     read FUsername;
    property Debug:boolean       read FDebug;
  end;

and use : 

Cmd := TMyCmdLine.Create;

Cmd.Username...
if Cmd.Debug then ....

#attribute   #delphi

Comments

  1. Boian Mitov Your definition of code is flawed. If you declare what you want that is the code. Maybe not the kind of code as if I write for i := 0 to count-1 do whatever() but it still is code. And thus it needs to be tested because maybe I declared the wrong thing that does not do what the spec was. And until we have a programming language where the definition of the spec equals the code/declaration it will be a while if that ever happens.

    ReplyDelete
  2. Stefan Glienke
    Correct, however such code is subject to different form of testing, and actually is easier to test, so it is a win, win ;-) . That is what we have been working on for the last 2 years, and we are well on the way to this goal :-) . I have reduced the development expense 3 fold already, sped up development by factor of 10, and reduced testing expenses by ~3 fold :-) Not bad! :-) . Now we do things different than Michel, but some of the approaches are similar.

    ReplyDelete

Post a Comment