1MODULE Config:Section:Arguments;
2
3IMPORT
4  Object, Msg, Channel, TextRider, LongStrings,
5  XMLBuilder := XML:Builder, XML:Locator,
6  Config:Parser, CS := Config:Section;
7
8
9TYPE
10  Section* = POINTER TO SectionDesc;
11  ArgumentArray = POINTER TO ARRAY OF STRING;
12  SectionDesc = RECORD
13    (CS.SectionDesc)
14    args: ArgumentArray;
15    argNumber: LONGINT;
16  END;
17
18
19
20CONST
21  invalidContent = 1;
22  invalidAttribute = 2;
23  requireCharDataContent = 5;
24
25TYPE
26  ErrorContext = POINTER TO ErrorContextDesc;
27  ErrorContextDesc = RECORD  (* stateless *)
28    (CS.ErrorContextDesc)
29  END;
30
31VAR
32  argumentsContext: ErrorContext;
33
34
35PROCEDURE (context: ErrorContext) GetTemplate* (msg: Msg.Msg; VAR templ: Msg.LString);
36  VAR
37    t: ARRAY 128 OF Msg.LChar;
38  BEGIN
39    CASE msg. code OF
40    | invalidContent:
41      t := "Invalid content for element `${name}'"
42    | invalidAttribute:
43      t := "Attribute `${name}' is not defined for this element"
44    | requireCharDataContent:
45      t := "This element must contain character data only"
46    END;
47    context. WriteTemplate (msg, t, templ)
48  END GetTemplate;
49
50
51
52PROCEDURE Init (s: Section; id: Parser.String);
53  BEGIN
54    CS.Init (s, id);
55    s. argNumber := 0;
56    NEW (s. args, 4)
57  END Init;
58
59PROCEDURE New* (sectionName: Parser.String): Section;
60  VAR
61    s: Section;
62  BEGIN
63    NEW (s);
64    Init (s, sectionName);
65    RETURN s
66  END New;
67
68
69PROCEDURE (s: Section) ArgNumber* (): LONGINT;
70  BEGIN
71    RETURN s. argNumber
72  END ArgNumber;
73
74PROCEDURE (s: Section) Get* (position: LONGINT): STRING;
75  BEGIN
76    IF (0 <= position) & (position < s. argNumber) THEN
77      RETURN s.args[position];
78    ELSE
79      RETURN NIL
80    END
81  END Get;
82
83
84PROCEDURE (s: Section) ProcessElements* (sectionRoot: Parser.Element;
85                                         errorListener: Locator.ErrorListener);
86  VAR
87    node: Parser.Node;
88    parserString: Parser.StringPtr;
89    newArgs: ArgumentArray;
90    i: LONGINT;
91    att: XMLBuilder.Attribute;
92    lastError: Msg.Msg;
93
94  PROCEDURE Err (code: Msg.Code; xmlNode: Parser.Node);
95    BEGIN
96      lastError := errorListener. Error (argumentsContext, code, FALSE, xmlNode. pos)
97    END Err;
98
99  BEGIN
100    node := sectionRoot. content;
101    WHILE (node # NIL) DO
102      WITH node: Parser.Element DO
103        IF (node. name^ = "arg") THEN
104          FOR i := 0 TO node. attrList. len-1 DO
105            att := node. attrList. attr[i];
106            Err (invalidAttribute, node);
107            lastError. SetLStringAttrib ("name", Msg.GetLStringPtr (att. localName^))
108          END;
109
110          IF ~node. HasNoElementContent() THEN
111            Err (requireCharDataContent, node)
112          ELSE
113            IF (s. argNumber = LEN (s. args^)) THEN
114              NEW (newArgs, LEN (s. args^)*2);
115              FOR i := 0 TO LEN (s. args^)-1 DO
116                newArgs[i] := s. args[i]
117              END;
118              s. args := newArgs
119            END;
120            parserString := node. GetCharDataContent();
121            s.args[s.argNumber] := Object.NewUTF16(parserString^);
122            INC (s.argNumber)
123          END
124
125        ELSE
126          Err (invalidContent, node);
127          lastError. SetLStringAttrib ("name", Msg.GetLStringPtr (s. name^))
128        END
129
130      | node: Parser.CharData DO
131        IF ~node. IsWhitespace() THEN
132          Err (invalidContent, node)
133        END
134      END;
135      node := node. nextNode
136    END
137  END ProcessElements;
138
139PROCEDURE (s: Section) DumpContent* (ch: Channel.Channel);
140  VAR
141    w: TextRider.Writer;
142    i: LONGINT;
143    str8: ARRAY 2048 OF CHAR;
144  BEGIN
145    w := TextRider.ConnectWriter (ch);
146    LongStrings.Short (s. name^, "?", str8);
147    w. WriteString ("<");
148    w. WriteString (str8);
149    w. WriteString (">"); w. WriteLn;
150    FOR i := 0 TO s. argNumber-1 DO
151      w. WriteString ("  <arg>");
152      w. WriteObject (s. args[i]);
153      w. WriteString ("</arg>");
154      w. WriteLn
155    END;
156    LongStrings.Short (s. name^, "?", str8);
157    w. WriteString ("</");
158    w. WriteString (str8);
159    w. WriteString (">"); w. WriteLn
160  END DumpContent;
161
162BEGIN
163  NEW (argumentsContext);
164  Msg.InitContext (argumentsContext, "Config:Section:Arguments");
165END Config:Section:Arguments.
166