MODULE WMBuilderTransformer;
IMPORT
KernelLog,
Modules, Streams, Commands, Options, Strings, Files, XML, XMLObjects, Repositories, UTF8Strings, Texts, TextUtilities,
WMRectangles, WMGraphics, WMProperties, WMComponents;
CONST
TAB = 09X;
VariableDeclarationIndent = 2;
CreateFormIndent = 3;
HandlersWiringIndent = 3;
HandlersIndent = 2;
DefaultBaseName = "TemplateMultiInstanceBase.txt";
DefaultSkeletonName = "TemplateMultiInstance.txt";
FileSuffixBase = "Base";
FileExtension = ".Mod";
TYPE
Identifier = ARRAY 64 OF CHAR;
ComponentIdentifier = RECORD
name : Identifier;
component : ANY;
END;
IdentifierArray = POINTER TO ARRAY OF ComponentIdentifier;
VariableDeclaration = OBJECT
VAR
moduleName, typeName : Modules.Name;
identifiers : IdentifierArray;
nofIdentifiers : LONGINT;
next : VariableDeclaration;
PROCEDURE &Init(CONST moduleName, typeName : Modules.Name);
BEGIN
SELF.moduleName := moduleName;
SELF.typeName := typeName;
NEW(identifiers, 8);
nofIdentifiers := 0;
next := NIL;
END Init;
PROCEDURE AddIdentifier(CONST ident : Identifier);
BEGIN
IF (nofIdentifiers >= LEN(identifiers)) THEN Resize; END;
identifiers[nofIdentifiers].name := ident;
INC(nofIdentifiers);
END AddIdentifier;
PROCEDURE ToStream(w : Streams.Writer);
VAR i : LONGINT;
BEGIN
Indent(w, VariableDeclarationIndent);
FOR i := 0 TO nofIdentifiers - 1 DO
w.String(identifiers[i].name); w.String("-");
IF (i # nofIdentifiers - 1) THEN w.String(", "); END;
END;
w.String(" : "); w.String(moduleName); w.String("."); w.String(typeName); w.String(";");
w.Char(CHR(Texts.NewLineChar));
END ToStream;
PROCEDURE Resize;
VAR newArray : IdentifierArray; i : LONGINT;
BEGIN
NEW(newArray, 2 * LEN(identifiers));
FOR i := 0 TO LEN(identifiers)-1 DO
newArray[i] := identifiers[i];
END;
identifiers := newArray;
END Resize;
END VariableDeclaration;
TYPE
VariableDeclarations = OBJECT
VAR
variables : VariableDeclaration;
PROCEDURE &Init;
BEGIN
variables := NIL;
END Init;
PROCEDURE Add(CONST identifier : Identifier; CONST moduleName, typeName : Modules.Name; component : ANY);
VAR vd : VariableDeclaration;
BEGIN
vd := FindByType(moduleName, typeName);
IF (vd = NIL) THEN
NEW(vd, moduleName, typeName);
vd.next := variables;
variables := vd;
END;
vd.AddIdentifier(identifier);
END Add;
PROCEDURE FindByType(CONST moduleName, typeName : Modules.Name) : VariableDeclaration;
VAR vd : VariableDeclaration;
BEGIN
vd := variables;
WHILE (vd # NIL) & ((vd.moduleName # moduleName) OR (vd.typeName # typeName)) DO vd := vd.next; END;
RETURN vd;
END FindByType;
PROCEDURE ToStream(w : Streams.Writer);
VAR v : VariableDeclaration;
BEGIN
IF (variables # NIL) THEN
v := variables;
WHILE (v # NIL) DO
v.ToStream(w);
v := v.next;
END;
END;
END ToStream;
END VariableDeclarations;
TYPE
ImportList = OBJECT
VAR
imports : ARRAY 128 OF Modules.Name;
nofImports : LONGINT;
PROCEDURE &Init;
VAR i : LONGINT;
BEGIN
FOR i := 0 TO LEN(imports)-1 DO imports[i] := ""; END;
nofImports := 0;
END Init;
PROCEDURE IndexOf(CONST import : Modules.Name) : LONGINT;
VAR i : LONGINT;
BEGIN
i := 0;
WHILE (i < nofImports) & (imports[i] # import) DO INC(i); END;
IF (i >= nofImports) THEN i := -1; END;
RETURN i;
END IndexOf;
PROCEDURE Add(CONST moduleName : Modules.Name);
BEGIN
IF IndexOf(moduleName) = -1 THEN
imports[nofImports] := moduleName;
INC(nofImports);
END;
END Add;
PROCEDURE ToStream(w : Streams.Writer);
VAR i : LONGINT;
BEGIN
ASSERT(w # NIL);
FOR i := 0 TO nofImports - 1 DO
w.String(", "); w.String(imports[i]);
END;
END ToStream;
END ImportList;
TYPE
Names = OBJECT
VAR
names : IdentifierArray;
nofNames : LONGINT;
PROCEDURE &Init;
BEGIN
NEW(names, 128);
nofNames := 0;
END Init;
PROCEDURE Add(CONST name : ARRAY OF CHAR; component : ANY);
BEGIN
IF (nofNames >= LEN(names)) THEN Resize; END;
COPY(name, names[nofNames].name);
names[nofNames].component := component;
INC(nofNames);
END Add;
PROCEDURE IndexOf(CONST identifier : ARRAY OF CHAR) : LONGINT;
VAR index : LONGINT;
BEGIN
index := 0;
WHILE (index < nofNames) & (names[index].name # identifier) DO INC(index); END;
IF (index >= nofNames) THEN
index := -1;
END;
RETURN index;
END IndexOf;
PROCEDURE GetNameOf(component : ANY; VAR name : ARRAY OF CHAR);
VAR index : LONGINT;
BEGIN
IF (component # NIL) THEN
index := 0;
WHILE (index < nofNames) & (names[index].component # component) DO INC(index); END;
IF (index < nofNames) THEN
COPY(names[index].name, name);
ELSE
name := "NotFound";
END;
ELSE
name := "NoName";
END;
END GetNameOf;
PROCEDURE GenerateIdentifier(caption : ARRAY OF CHAR; CONST moduleName, typeName : ARRAY OF CHAR; component : ANY) : Identifier;
VAR
temp, suffixStr, identifier : Identifier; suffix : LONGINT;
PROCEDURE AppendInteger(VAR string : ARRAY OF CHAR; integer : LONGINT);
VAR nbr : ARRAY 8 OF CHAR;
BEGIN
Strings.IntToStr(integer, nbr);
Strings.Append(string, nbr);
END AppendInteger;
PROCEDURE IsAlpha(ch : CHAR) : BOOLEAN;
BEGIN
RETURN (('a' <= ch) & (ch <= 'z')) OR (('A' <= ch) & (ch <= 'Z'));
END IsAlpha;
PROCEDURE IsNum(ch : CHAR) : BOOLEAN;
BEGIN
RETURN ('0' <= ch) & (ch <= '9');
END IsNum;
PROCEDURE RemoveReservedCharacters(VAR string : ARRAY OF CHAR);
VAR i, j: LONGINT;
BEGIN
i := 0; j := 0;
WHILE (i < LEN(string)) & (string[i] # 0X) DO
IF IsAlpha(string[i]) OR ((j > 0) & IsNum(string[i]) OR (string[i] = "_") OR (string[i] = "-")) THEN
string[j] := string[i]; INC(j);
END;
INC(i);
END;
string[j] := 0X;
END RemoveReservedCharacters;
BEGIN
RemoveReservedCharacters(caption);
IF (caption # "") THEN
COPY(caption, identifier);
TypeToSuffix(moduleName, typeName, suffixStr);
Strings.Append(identifier, suffixStr);
ELSIF (typeName # "") THEN
COPY(typeName, identifier);
ELSE
identifier := "unknown";
END;
identifier[0] := Strings.LOW(identifier[0]);
IF IndexOf(identifier) >= 0 THEN
suffix := 0;
REPEAT
COPY(identifier, temp);
AppendInteger(temp, suffix);
INC(suffix);
UNTIL IndexOf(temp) < 0;
COPY(temp, identifier);
END;
Add(identifier, component);
RETURN identifier;
END GenerateIdentifier;
PROCEDURE Resize;
VAR newArray : IdentifierArray; i : LONGINT;
BEGIN
NEW(newArray, 2 * LEN(names));
FOR i := 0 TO LEN(names)-1 DO
newArray[i] := names[i];
END;
names := newArray;
END Resize;
END Names;
TYPE
Transformer = OBJECT
VAR
names : Names;
declarations : VariableDeclarations;
importList : ImportList;
variableDecl : Strings.Buffer;
variableDeclWriter : Streams.Writer;
createForm : Strings.Buffer;
createFormWriter : Streams.Writer;
handlersWiring : Strings.Buffer;
handlersWiringWriter : Streams.Writer;
handlers : Strings.Buffer;
handlersWriter : Streams.Writer;
imports : Strings.Buffer;
importsWriter : Streams.Writer;
createFormReturnIdent : Identifier;
PROCEDURE &Init;
BEGIN
NEW(names);
NEW(declarations);
NEW(importList);
NEW(variableDecl, 1024); variableDeclWriter := variableDecl.GetWriter();
NEW(createForm, 1024); createFormWriter := createForm.GetWriter();
NEW(handlersWiring, 1024); handlersWiringWriter := handlersWiring.GetWriter();
NEW(handlers, 1024); handlersWriter := handlers.GetWriter();
NEW(imports, 1024); importsWriter := imports.GetWriter();
END Init;
PROCEDURE Transform(component, parent : WMComponents.Component; VAR res : LONGINT);
VAR
thisIdent : Identifier;
enum : XMLObjects.Enumerator;
ptr : ANY;
PROCEDURE WriteHandlersDeclaration(component : WMComponents.Component) : BOOLEAN;
VAR w : Streams.Writer; identifier : Identifier; typeString : ARRAY 128 OF CHAR; written : BOOLEAN;
BEGIN
ASSERT(component # NIL);
w := handlersWiringWriter;
names.GetNameOf(component, identifier);
written := FALSE;
GetTypeAsString(component, typeString);
IF (typeString = "WMStandardComponents.Button") THEN
written := TRUE;
Indent(w, HandlersWiringIndent);
w.String(identifier); w.String("."); w.String("onClick.Add(");
w.String("Handle");
identifier[0] := Strings.UP(identifier[0]);
w.String(identifier);
w.String(");");
w.Char(CHR(Texts.NewLineChar));
END;
RETURN written;
END WriteHandlersDeclaration;
PROCEDURE WriteHandlers(component : WMComponents.Component);
VAR w : Streams.Writer; identifier : Identifier;
BEGIN
ASSERT(component # NIL);
IF WriteHandlersDeclaration(component) THEN
w := handlersWriter;
Indent(w, HandlersIndent);
names.GetNameOf(component, identifier);
identifier[0] := Strings.UP(identifier[0]);
w.String("PROCEDURE Handle"); w.String(identifier); w.String("(sender, data : ANY);"); w.Char(CHR(Texts.NewLineChar));
Indent(w, HandlersIndent); w.String("BEGIN"); w.Char(CHR(Texts.NewLineChar));
Indent(w, HandlersIndent + 1); w.Char(CHR(Texts.NewLineChar));
Indent(w, HandlersIndent); w.String("END "); w.String("Handle"); w.String(identifier); w.String(";"); w.Char(CHR(Texts.NewLineChar));
w.Char(CHR(Texts.NewLineChar));
END;
END WriteHandlers;
PROCEDURE WriteProperties(w : Streams.Writer; CONST identifier : Identifier; component : WMComponents.Component);
VAR
pa : WMProperties.PropertyArray; name : Strings.String; i : LONGINT;
pname : ARRAY 64 OF CHAR;
helper : Streams.StringWriter;
PROCEDURE WriteStringProperty(property : WMProperties.Property);
BEGIN
w.String('.SetAOC("'); property.ToStream(w); w.String('");');
END WriteStringProperty;
PROCEDURE WriteColorProperty(property : WMProperties.Property);
VAR color : ARRAY 64 OF CHAR;
BEGIN
helper.Reset;
property.ToStream(helper);
helper.Get(color);
w.String(".Set(");
IF (("a" <= color[0]) & (color[0] <= "z")) OR (("A" <= color[0]) & (color[0] <= "Z")) THEN w.String("0"); END;
w.String(color);
w.String("H);");
END WriteColorProperty;
PROCEDURE WriteBooleanProperty(property : WMProperties.Property);
VAR value : ARRAY 8 OF CHAR;
BEGIN
helper.Reset;
property.ToStream(helper);
helper.Get(value);
Strings.UpperCase(value);
w.String(".Set("); w.String(value); w.String(");");
END WriteBooleanProperty;
PROCEDURE WriteReferenceProperty(property : WMProperties.Property);
BEGIN
w.String('.SetAsString("'); property.ToStream(w); w.String('");');
END WriteReferenceProperty;
PROCEDURE WriteFontProperty(property : WMProperties.Property);
VAR f : WMGraphics.Font;
BEGIN
f := property(WMProperties.FontProperty).Get();
w.String('.SetFont("'); w.String(f.name); w.String('", '); w.Int(f.size, 0); w.String(", "); w.Set(f.style);
w.String(");");
END WriteFontProperty;
PROCEDURE WriteRectangleProperty(property : WMProperties.Property);
VAR r : WMRectangles.Rectangle;
BEGIN
r := property(WMProperties.RectangleProperty).Get();
importList.Add("WMRectangles");
w.String(".Set(WMRectangles.MakeRect(");
w.Int(r.l, 0); w.String(", "); w.Int(r.t, 0); w.String(", ");
w.Int(r.r, 0); w.String(", "); w.Int(r.b, 0); w.String("));");
END WriteRectangleProperty;
PROCEDURE WriteAlignmentAndBounds(CONST identifier : Identifier; vc : WMComponents.VisualComponent; forceBounds : BOOLEAN);
VAR alignment : LONGINT; r : WMRectangles.Rectangle;
BEGIN
alignment := vc.alignment.Get();
IF ~vc.alignment.GetIsDefault() THEN
Indent(w, CreateFormIndent); w.String(identifier); w.String(".alignment.Set("); AlignmentToStream(alignment, w); w.String(");");
w.Char(CHR(Texts.NewLineChar));
END;
IF forceBounds OR (~vc.bounds.GetIsDefault() & (alignment # WMComponents.AlignClient)) THEN
Indent(w, CreateFormIndent); w.String(identifier); w.String(".bounds");
IF (alignment = WMComponents.AlignLeft) OR (alignment = WMComponents.AlignRight) THEN
w.String(".SetWidth("); w.Int(vc.bounds.GetWidth(), 0);
ELSIF (alignment = WMComponents.AlignTop) OR (alignment = WMComponents.AlignBottom) THEN
w.String(".SetHeight("); w.Int(vc.bounds.GetHeight(), 0);
ELSE
w.String(".Set(WMRectangles.MakeRect(");
importList.Add("WMRectangles");
r := vc.bounds.Get();
w.Int(r.l, 0); w.String(", "); w.Int(r.t, 0); w.String(", ");
w.Int(r.r, 0); w.String(", "); w.Int(r.b, 0); w.String(")");
END;
w.String(");");
w.Char(CHR(Texts.NewLineChar));
END;
END WriteAlignmentAndBounds;
BEGIN
ASSERT(w # NIL);
ASSERT(component # NIL);
IF (component IS WMComponents.VisualComponent) THEN
WriteAlignmentAndBounds(identifier, component(WMComponents.VisualComponent), identifier = createFormReturnIdent);
END;
pa := component.properties.Enumerate();
IF (pa # NIL) THEN
NEW(helper, 1024);
FOR i := 0 TO LEN(pa) - 1 DO
IF ~pa[i].GetIsDefault() & (pa[i].GetName() # NIL) THEN
name := pa[i].GetName();
IF (name^ # "Alignment") & (name^ # "Bounds") THEN
Indent(w, CreateFormIndent);
GetPropertyNameAsString(pa[i], pname);
w.String(identifier); w.String("."); w.String(pname);
IF (pa[i] IS WMProperties.StringProperty) THEN WriteStringProperty(pa[i]);
ELSIF (pa[i] IS WMProperties.ColorProperty) THEN WriteColorProperty(pa[i]);
ELSIF (pa[i] IS WMProperties.BooleanProperty) THEN WriteBooleanProperty(pa[i]);
ELSIF (pa[i] IS WMProperties.ReferenceProperty) THEN WriteReferenceProperty(pa[i]);
ELSIF (pa[i] IS WMProperties.FontProperty) THEN WriteFontProperty(pa[i]);
ELSIF (pa[i] IS WMProperties.RectangleProperty) THEN WriteRectangleProperty(pa[i]);
ELSE
w.String(".Set("); pa[i].ToStream(w); w.String(");");
END;
w.Char(CHR(Texts.NewLineChar));
END;
END;
END;
END;
w.Char(CHR(Texts.NewLineChar));
END WriteProperties;
PROCEDURE WriteCreateForm(CONST identifier : Identifier; component, parent : WMComponents.Component);
VAR w : Streams.Writer; parentIdent : Identifier; p : ANY;
BEGIN
ASSERT(component # NIL);
w := createFormWriter;
Indent(w, CreateFormIndent); w.String("NEW("); w.String(identifier); w.String(");"); w.Char(CHR(Texts.NewLineChar));
IF (parent # NIL) THEN
WHILE (parent # NIL) & (parent IS WMComponents.Component) & (parent(WMComponents.Component).internal) DO
p := parent.GetParent();
IF (p # NIL) & (p IS WMComponents.Component) THEN parent := p (WMComponents.Component); ELSE parent := NIL; END;
END;
IF (parent # NIL) THEN
names.GetNameOf(parent, parentIdent);
Indent(w, CreateFormIndent); w.String(parentIdent); w.String("."); w.String("AddContent(");
w.String(identifier); w.String(");"); w.Char(CHR(Texts.NewLineChar));
END;
ELSE
createFormReturnIdent := identifier;
END;
WriteProperties(w, identifier, component);
END WriteCreateForm;
PROCEDURE ProcessComponent(component, parent : WMComponents.Component; VAR ident : Identifier);
VAR td : Modules.TypeDesc; identifier, caption : Identifier; moduleName : Modules.Name;
BEGIN
ASSERT(component # NIL);
IF ~component(WMComponents.Component).internal THEN
td := Modules.TypeOf(component);
IF (td # NIL) THEN
IF (td.mod # NIL) THEN
COPY(td.mod.name, moduleName);
ELSE
moduleName := "";
END;
caption := "";
IF ~component(WMComponents.Component).properties.GetPropertyValue("Caption", caption) THEN caption := ""; END;
identifier := names.GenerateIdentifier(caption, moduleName, td.name, component);
ident := identifier;
IF (moduleName # "") THEN importList.Add(moduleName); END;
declarations.Add(identifier, moduleName, td.name, component);
WriteCreateForm(identifier, component, parent);
WriteHandlers(component);
ELSE
KernelLog.String("Warning: No type descriptor for component object found!"); KernelLog.Ln;
END;
END;
END ProcessComponent;
BEGIN
ASSERT(component # NIL);
ProcessComponent(component, parent, thisIdent);
enum := component.GetContents();
WHILE enum.HasMoreElements() DO
ptr := enum.GetNext();
IF (ptr # NIL) & (ptr IS WMComponents.Component) THEN
Transform(ptr(WMComponents.Component), component, res);
END;
END;
END Transform;
PROCEDURE GenerateCode(CONST targetName, templateName, skeletonName, moduleName : ARRAY OF CHAR; VAR res : LONGINT);
VAR base, skeleton : Texts.Text; format : LONGINT; fileName : Files.FileName;
BEGIN
NEW(base); TextUtilities.LoadAuto(base, templateName, format, res);
IF (res = 0) THEN
NEW(skeleton); TextUtilities.LoadAuto(skeleton, skeletonName, format, res);
IF (res = 0) THEN
Indent(createFormWriter, CreateFormIndent);
createFormWriter.String("RETURN "); createFormWriter.String(createFormReturnIdent); createFormWriter.String(";");
COPY(moduleName, fileName); Strings.Append(fileName, FileSuffixBase);
ApplyBase(base, fileName, res);
IF (res = 0) THEN
COPY(targetName, fileName); Strings.Append(fileName, FileSuffixBase); Strings.Append(fileName, FileExtension);
TextUtilities.StoreOberonText(base, fileName, res);
IF (res = 0) THEN
ApplySkeleton(skeleton, moduleName, res);
IF (res = 0) THEN
COPY(targetName, fileName); Strings.Append(fileName, FileExtension);
TextUtilities.StoreOberonText(skeleton, fileName, res);
END;
END;
END;
END;
END;
END GenerateCode;
PROCEDURE ApplyBase(text : Texts.Text; CONST moduleName : ARRAY OF CHAR; VAR res : LONGINT);
VAR error : BOOLEAN;
BEGIN
ASSERT(text # NIL);
ReplaceString("[MODULENAME]", moduleName, text, error);
importList.ToStream(importsWriter);
Replace("[IMPORTS]", imports, text, error);
declarations.ToStream(variableDeclWriter);
Replace("[VARIABLES]", variableDecl, text, error);
Replace("[CREATEFORM]", createForm, text, error);
END ApplyBase;
PROCEDURE ApplySkeleton(text : Texts.Text; CONST moduleName : ARRAY OF CHAR; VAR res : LONGINT);
VAR error : BOOLEAN; name : ARRAY 64 OF CHAR;
BEGIN
ASSERT(text # NIL);
ReplaceString("[MODULENAME]", moduleName, text, error);
COPY(moduleName, name); Strings.Append(name, FileSuffixBase);
ReplaceString("[BASEMODULENAME]", name, text, error);
Replace("[HANDLERSWIRING]", handlersWiring, text, error);
Replace("[HANDLERS]", handlers, text, error);
END ApplySkeleton;
END Transformer;
PROCEDURE GetUCS32String(string : Strings.String) : Texts.PUCS32String;
VAR ucsString : Texts.PUCS32String; idx : LONGINT;
BEGIN
ucsString := NIL;
IF (string # NIL) & (Strings.Length(string^) > 0) THEN
NEW(ucsString, 5 * Strings.Length(string^));
idx := 0; UTF8Strings.UTF8toUnicode(string^, ucsString^, idx);
END;
RETURN ucsString;
END GetUCS32String;
PROCEDURE Replace(CONST pattern : ARRAY OF CHAR; by : Strings.Buffer; text : Texts.Text; VAR error : BOOLEAN);
VAR string : Strings.String; ucsPattern, ucsString : Texts.PUCS32String; nofReplacements, idx : LONGINT;
BEGIN
ASSERT(Strings.Length(pattern) > 2);
ASSERT(by # NIL);
ASSERT(text # NIL);
error := FALSE;
string := by.GetString();
ucsString := GetUCS32String(string);
IF (ucsString = NIL) THEN NEW(ucsString, 1); ucsString[0] := 0; END;
NEW(ucsPattern, 5 * Strings.Length(pattern));
idx := 0; UTF8Strings.UTF8toUnicode(pattern, ucsPattern^, idx);
TextUtilities.Replace(ucsPattern^, ucsString^, text, nofReplacements);
error := (nofReplacements # 1);
END Replace;
PROCEDURE ReplaceString(CONST string, by : ARRAY OF CHAR; text : Texts.Text; VAR error : BOOLEAN);
VAR nofReplacements, idx : LONGINT; ucsString, ucsBy : Texts.PUCS32String;
BEGIN
ASSERT(Strings.Length(string) > 2);
ASSERT(Strings.Length(by) > 0);
ASSERT(text # NIL);
nofReplacements := 0;
NEW(ucsString, 6 * Strings.Length(string));
NEW(ucsBy, 6 * Strings.Length(by));
idx := 0; UTF8Strings.UTF8toUnicode(string, ucsString^, idx);
idx := 0; UTF8Strings.UTF8toUnicode(by, ucsBy^, idx);
TextUtilities.Replace(ucsString^, ucsBy^, text, nofReplacements);
error := nofReplacements # 1;
END ReplaceString;
PROCEDURE AlignmentToStream(alignment : LONGINT; w : Streams.Writer);
BEGIN
CASE alignment OF
|WMComponents.AlignNone: w.String("WMComponents.AlignNone");
|WMComponents.AlignLeft: w.String("WMComponents.AlignLeft");
|WMComponents.AlignTop: w.String("WMComponents.AlignTop");
|WMComponents.AlignRight: w.String("WMComponents.AlignRight");
|WMComponents.AlignBottom: w.String("WMComponents.AlignBottom");
|WMComponents.AlignClient: w.String("WMComponents.AlignClient");
ELSE
w.Int(alignment, 0);
END;
END AlignmentToStream;
PROCEDURE GetPropertyNameAsString(property : WMProperties.Property; VAR value : ARRAY OF CHAR);
VAR string : Strings.String;
BEGIN
ASSERT(property # NIL);
value := "";
string := property.GetName();
IF (string # NIL) THEN
IF (string^ = "ID") THEN value := "id";
ELSIF (string^ = "UID") THEN value := "uid";
ELSIF (string^ = "BgLeftDefault") THEN value := "imgDefaultNameLeft";
ELSIF (string^ = "BgRightDefault") THEN value := "imgDefaultNameRight";
ELSIF (string^ = "BgMiddleDefault") THEN value := "imgDefaultNameMiddle";
ELSIF (string^ = "BgLeftHover") THEN value := "imgHoverNameLeft";
ELSIF (string^ = "BgRightHover") THEN value := "imgHoverNameRight";
ELSIF (string^ = "BgMiddleHover") THEN value := "imgHoverNameMiddle";
ELSIF (string^ = "BgLeftPressed") THEN value := "imgPressedNameLeft";
ELSIF (string^ = "BgRightPressed") THEN value := "imgPressedNameRight";
ELSIF (string^ = "BgMiddlePressed") THEN value := "imgPressedNameMiddle";
ELSIF (string^ = "BgTopDefault") THEN value := "imgDefaultNameTop";
ELSIF (string^ = "BgBottomDefault") THEN value := "imgDefaultNameBottom";
ELSIF (string^ = "BgTopHover") THEN value := "imgHoverNameTop";
ELSIF (string^ = "BgBottomHover") THEN value := "imgHoverNameBottom";
ELSIF (string^ = "BgTopPressed") THEN value := "imgPressedNameTop";
ELSIF (string^ = "BgBottomPressed") THEN value := "imgPressedNameBottom";
ELSE
COPY(string^, value);
value[0] := Strings.LOW(value[0]);
END;
END;
END GetPropertyNameAsString;
PROCEDURE Indent(writer : Streams.Writer; level : LONGINT);
BEGIN
WHILE (level > 0) DO writer.Char(TAB); DEC(level); END;
END Indent;
PROCEDURE TypeToSuffix(CONST moduleName, typeName : ARRAY OF CHAR; VAR suffix : ARRAY OF CHAR);
BEGIN
suffix := "";
IF (moduleName = "WMStandardComponents") THEN
IF (typeName = "Button") THEN
suffix := "Btn";
END;
END;
END TypeToSuffix;
PROCEDURE GetTypeAsString(component : Repositories.Component; VAR typeString : ARRAY OF CHAR);
VAR td : Modules.TypeDesc;
BEGIN
ASSERT(component # NIL);
typeString := "";
td := Modules.TypeOf(component);
IF (td # NIL) THEN
IF (td.mod # NIL) THEN
COPY(td.mod.name, typeString);
Strings.Append(typeString, ".");
END;
Strings.Append(typeString, td.name);
END;
END GetTypeAsString;
PROCEDURE TransformComponent*(component : WMComponents.Component; CONST base, skeleton, fileName, moduleName : ARRAY OF CHAR; VAR res : LONGINT);
VAR transformer : Transformer;
BEGIN
ASSERT(component # NIL);
NEW(transformer);
transformer.Transform(component(WMComponents.Component), NIL, res);
IF (res = 0) THEN
transformer.GenerateCode(fileName, base, skeleton, moduleName, res);
END;
END TransformComponent;
PROCEDURE Transform*(context : Commands.Context);
VAR
options : Options.Options;
componentName, baseName, skeletonName, moduleName, fileName : Files.FileName;
content : XML.Content; component : Repositories.Component;
res : LONGINT;
BEGIN
NEW(options);
options.Add("b", "base", Options.String);
options.Add("f", "filename", Options.String);
options.Add("s", "skeleton", Options.String);
IF options.Parse(context.arg, context.error) THEN
context.arg.SkipWhitespace; context.arg.String(componentName);
context.arg.SkipWhitespace; context.arg.String(moduleName);
IF ~options.GetString("base", baseName) THEN COPY(DefaultBaseName, baseName); END;
IF ~options.GetString("skeleton", skeletonName) THEN COPY(DefaultSkeletonName, skeletonName); END;
IF ~options.GetString("filename", fileName) THEN
COPY(moduleName, fileName);
END;
IF Strings.ContainsChar(componentName, ".", FALSE) THEN
content := WMComponents.Load(componentName);
IF (content # NIL) & (content IS WMComponents.Component) THEN
TransformComponent(content(WMComponents.Component), baseName, skeletonName, fileName, moduleName, res);
IF (res = 0) THEN
context.out.String(componentName); context.out.String(" written to "); context.out.String(fileName); context.out.String(FileExtension);
context.out.String(" and "); context.out.String(fileName); context.out.String(FileSuffixBase); context.out.String(FileExtension);
context.out.Ln;
ELSE
context.error.String("Transformation failed, res = "); context.error.Int(res, 0); context.error.Ln;
END;
ELSE
context.error.String("Could not load component from file "); context.error.String(componentName);
context.error.Ln;
END;
ELSE
Repositories.GetComponentByString(componentName, component, res);
IF (res = Repositories.Ok) THEN
IF (component IS WMComponents.Component) THEN
TransformComponent(component(WMComponents.Component), baseName, skeletonName, fileName, moduleName, res);
IF (res = 0) THEN
context.out.String(componentName); context.out.String(" written to "); context.out.String(fileName); context.out.String(FileExtension);
context.out.String(" and "); context.out.String(fileName); context.out.String(FileSuffixBase); context.out.String(FileExtension);
context.out.Ln;
ELSE
context.error.String("Transformation failed, res = "); context.error.Int(res, 0); context.error.Ln;
END;
ELSE
context.error.String("Component type mismatch"); context.error.Ln;
END;
ELSE
context.error.String("Could not load component "); context.error.String(componentName);
context.error.String(", res: "); context.error.Int(res, 0); context.error.Ln;
END;
END;
END;
END Transform;
END WMBuilderTransformer.
WMBuilderTransformer.Transform Test:TestFont:0 TestMod TestMod.Mod ~
WMBuilderTransformer.Transform Testxxx2:Mixer Test ~
WMBuilderTransformer.Transform Demo.wm Test ~
SystemTools.Free WMBuilderTransformer ~
WMBuilderTransformer.Test ~