323 lines
12 KiB
ObjectPascal
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.
|