📄 ucommandparameters.pas
字号:
TDelphiDocFile = (
//a project file with the lists of files to parse
ddfProject,
//a file containing already parsed data
ddfParsedData,
//a project file with the list of log files of GUIs to
//generate a help about
ddfGUIHelpProject,
//a file containing several layouts for diagrams of
//parsed data
ddfDiagrams);
//description of a file type to associate it with this program
TDelphiDocFileType = record
Extension: String; //the file extension (with the dot)
RegType: String; //identification of the file type to register with
Description: String; //visible discription to the file type
OpenCaption: String; //caption of menu item to open with this program
Parameter: String; //parameters to use to open with this program
Icon: Integer; //number of icon within the program to show for the files
end;
const
//description of the file types used in this program to associate them with
//it
DelphiDocFiles: array[TDelphiDocFile] of TDelphiDocFileType =
((Extension: '.' + DDPDefaultExtension;
RegType: 'DelphiDocProject';
Description: 'DelphiDoc Project File';
OpenCaption: 'Load &Project';
Parameter: '-p';
Icon: 1),
(Extension: '.' + DDDDefaultExtension;
RegType: 'DelphiDocParsedData';
Description: 'DelphiDoc''s parsed Data';
OpenCaption: 'Load &Parsed Data';
Parameter: '-P';
Icon: 2),
(Extension: '.' + DDGHDefaultExtension;
RegType: 'DelphiDocGUIHelp';
Description: 'DelphiDoc GUI Help project file';
OpenCaption: 'Load GUI Help &Project File';
Parameter: '-H';
Icon: 4),
(Extension: '.' + DDDLDefaultExtension;
RegType: 'DelphiDocDiagramLayouts';
Description: 'DelphiDoc Diagram Layouts';
OpenCaption: 'Start &DelphiDoc';
Parameter: '';
Icon: 3));
//name of the key to store the previous file type in, used to restore the
//previous association
SavePreviousTypeKeyName = 'PrevType';
//Checks whether the file is associated with this program.
function GetFileExtRegisterState(Kind: TDelphiDocFile;
var Status: String): Boolean;
//Registers the file association with this program.
procedure RegisterExtension(Kind: TDelphiDocFile);
//Unregisters the file association with this program.
procedure UnregisterExtension(Kind: TDelphiDocFile);
{$ENDIF}
//directory with the documentation of DelphiDoc
//~see DocumentationMainFile
const DocumentationSubDir = 'Documentation';
//the main/index file with the documentation in
//~[link DocumentationSubDir]
DocumentationMainFile = 'index.html';
//Shows DelphiDoc's homepage.
procedure ShowDelphiDocProjectPage(HelpContext: THelpContext;
const SubURI: String = '');
//Shows DelphiDoc's documentation.
procedure ShowDocumentation(HelpContext: THelpContext; DocFile: String = '');
implementation
uses
{$IFDEF VER120}
FileCtrl,
{$ENDIF}
{$IFNDEF LINUX}
Windows, Forms, Controls, Dialogs, Registry, ShellApi, ShlObj,
{$ELSE}
QDialogs,
{$ENDIF}
General,
UFilePaths;
{Returns a string containing the syntax of the possible parameters of the
program.
~result a short overview of the parameters }
function GenerateParameterView: String;
{Returns a view of each single parameter.
~param Entry the entry to return a overview for
~result the view of the parameter}
function GetParams(const Entry: TParameterEntry): String;
//the strings to express the parameters of options
const ParamValue: array[Boolean] of String = ('VALUE', 'NAME=VALUE');
var i :Integer; //counter through short options
begin
Result := '';
for i := 1 to Length(Entry.ShortChars) do //for each short option character
begin
Result := Result + ' -' + Entry.ShortChars[i]; //add its entry
if [peoHasParameter, peoParameterOnlyForLongOption] * Entry.Options =
[peoHasParameter] then //has a value?
Result := Result + ' ' + //show it
ParamValue[peoParameterNameValue in Entry.Options];
end;
if Entry.LongName <> '' then //long option available?
begin
Result := Result + ' --' + Entry.LongName; //show it
if peoHasParameter in Entry.Options then //has a value?
begin
if peoParameterOptional in Entry.Options then //if optional
Result := Result + '['; //mark this
Result := Result + '=' + //show value
ParamValue[peoParameterNameValue in Entry.Options];
if peoParameterOptional in Entry.Options then
Result := Result + ']';
end;
end;
end;
var OptionFilter :TParameterEntryOption; //filter for parameters
Param :TParameter; //counter through parameters
begin
//start with the name of the program
Result := ExtractFileName(ParamStr(0));
//get filter for kind of program
if IsConsole then
OptionFilter := peoNotAtCommandLineVersion
else
OptionFilter := peoNotInGUIVersion;
//add all options
for Param := Low(ParameterEntries) to High(ParameterEntries) do
if not (OptionFilter in ParameterEntries[Param].Options) then
Result := Result + GetParams(ParameterEntries[Param]);
end;
{ * * * *** * * * *** TParameterOptions *** * * * *** * * * }
{Create the object to process the command line parameters. }
constructor TParameterOptions.Create;
begin
inherited Create; //create the object
FParameters := TStringList.Create; //create list for parameters
GetCommandLineParameters(FParameters); //and get all
end;
{Frees the object. }
destructor TParameterOptions.Destroy;
begin
FParameters.Free; //free the parameters
inherited Destroy; //free the object
end;
{Shows a help text about the available program options.
~param Error an error message, if a wrong option has been given, else '' }
class procedure TParameterOptions.ShowParametersHelp(Error: String);
//the type of the dialog to show the help text
const MsgType: array[Boolean] of TMsgDlgType = (mtInformation, mtError);
var ErrorMsg :Boolean; //if is is shown because of an error
begin
ErrorMsg := Error <> ''; //error message?
if Error <> '' then
Error := Error + LineDelimiter; //show help in next line after error message
// Error := Error + HelpText;
Error := Error +
'This program, JADD - Just Another DelphiDoc, copyright 2002-2008 by' +
' Gerold Veith, is licensed under the GNU GPL version 3!' + LineDelimiter +
'For a complete documentation of the possible parameters please take a look' +
' into the documentation at ' + DocumentationSubDir +
'/manual.html#Parameters' + LineDelimiter + LineDelimiter +
'Usage: ' + GenerateParameterView;
if IsConsole then //is a console application?
WriteLn(Error) //just write the help to stdout
else //show dialog with the help text
MessageDlg(Error, MsgType[ErrorMsg], [mbOK], 0);
end;
//~param ParamFunc the function to be called for each parsed parameter
{Handles all parameters by calling ~[link ParamFunc].
~result the last return value of ParamFunc, i.e. False if it aborted/paused
parsing the parameters or True if the last parameter has been read
~exception EParameterException when a parameter or its value is invalid or
unknown }
function TParameterOptions.ReadParameters: Boolean;
{Shows an error message in case parameters are invalid.
~param Msg the message to be shown
~param Args arguments needed to create the message }
procedure ErrorFmt(Msg: String; const Args: array of const);
begin
//abort handling the parameters
raise EParameterException.CreateFmt(Msg, Args);
// Result := False; //abort handling the parameters
// ShowParametersHelp(Format(Msg, Args)); //just show the help text
end;
{Handles the next short parameter. }
procedure HandleShortParameter;
var ShortChar :Char; //short single character of option
Option :TParameter; //option represented by parameter
ParamValue :String; //value of the parameter, if available
begin
ShortChar := FShortParameters[1]; //extract next option
Delete(FShortParameters, 1, 1);
Option := High(ParameterEntries); //search the option by the character
while (Option > Low(ParameterEntries)) and
(Pos(ShortChar, ParameterEntries[Option].ShortChars) = 0) do
Dec(Option);
//no option found represented by the character?
if Pos(ShortChar, ParameterEntries[Option].ShortChars) = 0 then
ErrorFmt('Unknown short parameter "%s"!', [ShortChar])
else
begin
//the option needs a parameter?
if [peoHasParameter, peoParameterOnlyForLongOption] *
ParameterEntries[Option].Options = [peoHasParameter] then
begin
if FParameters.Count = 0 then //no other parameters available?
ErrorFmt('No value for short parameter "%s" specified!', [ShortChar])
else
begin
ParamValue := FParameters[0]; //get the parameter
FParameters.Delete(0);
//if it should be a "Name=Value" pair, check this
if (peoParameterNameValue in ParameterEntries[Option].Options) and
(Pos('=', ParamValue) in [0, 1]) then
ErrorFmt('The value for short parameter "%s" needs to be a "Name=Value" pair, but it isn''t: "%s"',
[ShortChar, ParamValue])
else //handle the parameter
Result := ParamFunc(Option, ShortChar, ParamValue, True);
end;
end //if peoHasParameter in ParameterEntries[Option].Options
else //handle the parameter
Result := ParamFunc(Option, ShortChar, '', False);
end; //else Pos(ShortChar, ParameterEntries[Option].ShortChars) = 0
end;
{Handles the long parameter.
~param ParamName the name of the parameter (and maybe its value) }
procedure HandleLongParameter(ParamName: String);
var Index :Integer; //index of the end of the parameter
HasParamValue :Boolean; //whether a value has been specified
ParamValue :String; //value of the parameter, if available
Option :TParameter; //option represented by parameter
//to make sure there is no other matching option
DoubleCheck :TParameter;
begin
Index := Pos('=', ParamName); //search end of the name
HasParamValue := Index <> 0; //has a value?
if HasParamValue then
begin //extract the value
ParamValue := Copy(ParamName, Index + 1, High(Length(ParamValue)));
Delete(ParamName, Index, High(Length(ParamValue)));
end
else
ParamValue := ''; //no value for parameter read
//search the option represented by the parameter name
Option := High(ParameterEntries);
while (Option > Low(ParameterEntries)) and
not StartsTextWith(ParamName,
ParameterEntries[Option].LongName) do
Dec(Option);
if not StartsTextWith(ParamName, //no matching option found?
ParameterEntries[Option].LongName) then
ErrorFmt('Unknown long parameter "%s"!', [ParamName])
else
begin
if Option = Low(ParameterEntries) then //is the last (first) option?
DoubleCheck := Succ(Option) //select any other option
else
begin
//check whether the parameter name is an abbreviation that matches
//more than one option
DoubleCheck := Pred(Option);
while (DoubleCheck > Low(ParameterEntries)) and
not StartsTextWith(ParamName,
ParameterEntries[DoubleCheck].LongName) do
Dec(DoubleCheck);
end;
if StartsTextWith(ParamName, //matches another option?
ParameterEntries[DoubleCheck].LongName) then
ErrorFmt('Abbreviation of long parameter "%s" is not unique, there are at least two matching parameters: "%s" and "%s"!',
[ParamName, ParameterEntries[Option].LongName,
ParameterEntries[DoubleCheck].LongName])
else
begin
//whether the parameter has a value matches whether the option
if (HasParamValue = //needs one
(peoHasParameter in ParameterEntries[Option].Options)) or
(not HasParamValue and
(peoParameterOptional in //or it is optional?
ParameterEntries[Option].Options)) then
begin
//if the value of the parameter should be a "Name=Value" pair,
if HasParamValue and
(peoParameterNameValue in
ParameterEntries[Option].Options) and
(pos('=', ParamValue) in [0, 1]) then //check this
ErrorFmt('The value for long parameter "%s" needs to be a "Name=Value" pair, but it isn''t: "%s"',
[ParamName, ParamValue])
else //handle the parameter
Result := ParamFunc(Option, #0, ParamValue, HasParamValue);
end
else
if HasParamValue then
ErrorFmt('The long parameter "%s" does not expect a value, yet it got the value "%s"!',
[ParamName, ParamValue])
else
ErrorFmt('The long parameter "%s" needs a value but none has been specified!',
[ParamName]);
end; //else StartsTextWith(Param, ParameterEntries[Doubl].LongName)
end; //else not StartsTextWith(Param, ParameterEntries[Opt].LongName)
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -