Componentes.Terceros.jcl/official/1.100/experts/debug/dialog/JclOtaTemplates.pas

323 lines
12 KiB
ObjectPascal

{****************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License }
{ Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may }
{ obtain a copy of the License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, }
{ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License }
{ for the specific language governing rights and limitations under the }
{ License. }
{ }
{ The Original Code is JclOtaTemplates.pas. }
{ }
{ The Initial Developer of the Original Code is Florent Ouchet }
{ <outchy att users dott sourceforge dott net> }
{ Portions created by Florent Ouchet are Copyright (C) of Florent Ouchet. }
{ }
{ Contributors: }
{ }
{****************************************************************************}
{ }
{ Last modified: $Date: $ }
{ }
{****************************************************************************}
unit JclOtaTemplates;
interface
{$I jcl.inc}
uses
Classes, JclBorlandTools;
type
TJclOtaTemplateParams = class(TPersistent)
protected
FLanguage: TJclBorPersonality;
public
function GetBoolValue(const Name: string): Boolean; virtual;
function IsDefined(const Name: string): Boolean; virtual;
function GetStrValue(const Name: string): string; virtual;
function GetIntValue(const Name: string): Integer; virtual;
function GetStringsValue(const Name: string): TStrings; virtual;
property Language: TJclBorPersonality read FLanguage write FLanguage;
end;
const
ModulePattern = '%MODULENAME%';
FormPattern = '%FORMNAME%';
AncestorPattern = '%ANCESTORNAME%';
function GetFinalFormContent(const Content, FormIdent,
AncestorIdent: string): string;
function GetFinalHeaderContent(const Content, ModuleIdent, FormIdent,
AncestorIdent: string): string;
function GetFinalSourceContent(const Content, ModuleIdent, FormIdent,
AncestorIdent: string): string;
function ApplyTemplate(const Template: string;
const Params: TJclOtaTemplateParams): string;
implementation
uses
SysUtils,
{$IFDEF HAS_UNIT_VARIANTS}
// Variants,
{$ENDIF HAS_UNIT_VARIANTS}
TypInfo,
JclStrings, JclSysUtils;
function GetFinalFormContent(const Content, FormIdent,
AncestorIdent: string): string;
begin
Result := StringReplace(Content, FormPattern, FormIdent, [rfReplaceAll, rfIgnoreCase]);
Result := StringReplace(Result, AncestorPattern, AncestorIdent, [rfReplaceAll, rfIgnoreCase]);
end;
function GetFinalHeaderContent(const Content, ModuleIdent, FormIdent,
AncestorIdent: string): string;
begin
Result := StringReplace(Content, FormPattern, FormIdent, [rfReplaceAll, rfIgnoreCase]);
Result := StringReplace(Result, AncestorPattern, AncestorIdent, [rfReplaceAll, rfIgnoreCase]);
Result := StringReplace(Result, ModulePattern, ModuleIdent, [rfReplaceAll, rfIgnoreCase]);
end;
function GetFinalSourceContent(const Content, ModuleIdent, FormIdent,
AncestorIdent: string): string;
begin
Result := StringReplace(Content, FormPattern, FormIdent, [rfReplaceAll, rfIgnoreCase]);
Result := StringReplace(Result, AncestorPattern, AncestorIdent, [rfReplaceAll, rfIgnoreCase]);
Result := StringReplace(Result, ModulePattern, ModuleIdent, [rfReplaceAll, rfIgnoreCase]);
end;
function ApplyTemplate(const Template: string;
const Params: TJclOtaTemplateParams): string;
procedure CopyStr(var Dest: string; var IndexDest: Integer;
var DestCharCount: Integer; const Src: string; IndexSrc: Integer;
CharCount: Integer);
begin
if (Length(Src) - IndexSrc + 1) < CharCount then
CharCount := Length(Src) - IndexSrc + 1;
while (DestCharCount - IndexDest + 1) < CharCount do
begin
DestCharCount := 2 * DestCharCount;
SetLength(Dest, DestCharCount);
end;
if CharCount > 0 then
begin
Move(Src[IndexSrc], Dest[IndexDest], CharCount);
Inc(IndexDest, CharCount);
end;
end;
function SkipBlanks(const Str: string; const Index: Integer;
Count: Integer): Integer;
begin
Result := Index;
while (Result <= Count) and (Str[Result] in AnsiWhiteSpace) do
Inc(Result);
end;
function GetIdentifier(const Str: string; var Index: Integer;
Count: Integer): string;
var
IndexStart: Integer;
begin
IndexStart := Index;
while (Index <= Count) and (Str[Index] in ['0'..'9', 'A'..'Z', 'a'..'z', '_', '%']) do
Inc(Index);
Result := Copy(Str, IndexStart, Index - IndexStart);
end;
var
IndexInput, IndexOutput, TokenPos, CharCountIn, CharCountOut,
IfCount, StrIndex, RepeatCount: Integer;
Identifier, Command, Symbol, StrValue, RepeatPattern, RepeatValue: string;
StrList: TStrings;
begin
CharCountIn := Length(Template);
CharCountOut := 2*CharCountIn;
SetLength(Result, CharCountOut);
IndexInput := 1;
IndexOutput := 1;
IfCount := 0;
while IndexInput < CharCountIn do
begin
TokenPos := CharPos(Template, '%', IndexInput);
if TokenPos = 0 then
begin
CopyStr(Result, IndexOutput, CharCountOut, Template, IndexInput, CharCountIn - IndexInput + 1);
SetLength(Result, IndexOutput - 1);
Exit;
end
else
begin
if IfCount = 0 then
CopyStr(Result, IndexOutput, CharCountOut, Template, IndexInput, TokenPos - IndexInput);
Identifier := GetIdentifier(Template, TokenPos, CharCountIn);
Command := StrUpper(Identifier);
if Command = '%IF' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if (IfCount > 0) or not Params.IsDefined(Symbol) then
begin
Inc(IfCount);
end;
end
else if Command = '%IFNOT' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if (IfCount > 0) or Params.IsDefined(Symbol) then
Inc(IfCount);
end
else if Command = '%ELSE' then
begin
if IfCount = 1 then
IfCount := 0
else if IfCount = 0 then
IfCount := 1;
end
else if Command = '%ENDIF' then
begin
if IfCount > 0 then
Dec(IfCount);
end
else if Command = '%STRVALUE' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if IfCount = 0 then
begin
StrValue := Params.GetStrValue(Symbol);
case Params.Language of
bpDelphi32:
begin
StrValue := StringReplace(StrValue, AnsiSingleQuote, AnsiSingleQuote + AnsiSingleQuote, [rfReplaceAll]);
StrValue := AnsiSingleQuote + StrValue + AnsiSingleQuote;
end;
bpBCBuilder32:
begin
StrValue := StringReplace(StrValue, AnsiDoubleQuote, AnsiBackslash + AnsiDoubleQuote, [rfReplaceAll]);
StrValue := AnsiDoubleQuote + StrValue + AnsiDoubleQuote;
end;
end;
CopyStr(Result, IndexOutput, CharCountOut, StrValue, 1, Length(StrValue));
end;
end
else if Command = '%INTVALUE' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if IfCount = 0 then
begin
StrValue := IntToStr(Params.GetIntValue(Symbol));
CopyStr(Result, IndexOutput, CharCountOut, StrValue, 1, Length(StrValue));
end;
end
else if Command = '%BOOLVALUE' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if IfCount = 0 then
begin
StrValue := BooleanToStr(Params.GetBoolValue(Symbol));
CopyStr(Result, IndexOutput, CharCountOut, StrValue, 1, Length(StrValue));
end;
end
else if Command = '%REPEATLINE' then
begin
TokenPos := SkipBlanks(Template, TokenPos, CharCountIn);
Symbol := GetIdentifier(Template, TokenPos, CharCountIn);
if IfCount = 0 then
begin
RepeatCount := Params.GetIntValue(Symbol);
StrIndex := TokenPos;
while (StrIndex <= CharCountIn) and not (Template[StrIndex] in [AnsiLineFeed, AnsiCarriageReturn]) do
Inc(StrIndex);
RepeatPattern := Copy(Template, TokenPos, StrIndex - TokenPos);
TokenPos := StrIndex;
while RepeatCount > 0 do
begin
StrValue := RepeatPattern;
StrIndex := Pos('%', StrValue);
while StrIndex > 0 do
begin
Inc(StrIndex);
Symbol := GetIdentifier(StrValue, StrIndex, Length(StrValue));
StrList := Params.GetStringsValue(Symbol);
if Assigned(StrList) then
RepeatValue := StrList.Strings[RepeatCount - 1]
else
RepeatValue := '';
StrReplace(StrValue, '%' + Symbol, RepeatValue, [rfReplaceAll, rfIgnoreCase]);
StrIndex := Pos('%', StrValue);
end;
CopyStr(Result, IndexOutput, CharCountOut, StrValue, 1, Length(StrValue));
CopyStr(Result, IndexOutput, CharCountOut, AnsiLineBreak, 1, Length(AnsiLineBreak));
Dec(RepeatCount);
end;
end;
end
else if IfCount = 0 then
CopyStr(Result, IndexOutput, CharCountOut, Identifier, 1, Length(Identifier));
IndexInput := TokenPos;
end;
end;
end;
//=== { TJclOtaTemplateParams } ==============================================
function TJclOtaTemplateParams.GetBoolValue(const Name: string): Boolean;
var
VariantValue: Variant;
begin
VariantValue := GetPropValue(Self, Name);
Result := Boolean(VariantValue);
end;
function TJclOtaTemplateParams.GetIntValue(const Name: string): Integer;
var
VariantValue: Variant;
begin
VariantValue := GetPropValue(Self, Name);
Result := Integer(VariantValue);
end;
function TJclOtaTemplateParams.GetStringsValue(const Name: string): TStrings;
var
Instance: TObject;
begin
Instance := TObject(GetOrdProp(Self, Name));
if Instance is TStrings then
Result := TStrings(Instance)
else
Result := nil;
end;
function TJclOtaTemplateParams.GetStrValue(const Name: string): string;
var
VariantValue: Variant;
begin
VariantValue := GetPropValue(Self, Name, True);
Result := string(VariantValue);
end;
function TJclOtaTemplateParams.IsDefined(const Name: string): Boolean;
begin
Result := GetBoolValue(Name);
end;
end.