1MODULE H2O:Option;
2
3IMPORT Object, ADT:ArrayList, H2O:Value, Log, TextRider;
4
5TYPE
6  Option* = POINTER TO OptionDesc;
7  OptionDesc = RECORD [ABSTRACT] (Object.ObjectDesc)
8    name- : STRING;
9  END;
10
11  String* = POINTER TO StringDesc;
12  StringDesc = RECORD (OptionDesc)
13    value* : STRING;
14  END;
15
16  StringList* = POINTER TO StringListDesc;
17  StringListDesc = RECORD (OptionDesc)
18    value* : ArrayList.ArrayList(STRING);
19  END;
20
21  Boolean* = POINTER TO BooleanDesc;
22  BooleanDesc = RECORD (OptionDesc)
23    value* : BOOLEAN;
24  END;
25
26  Options* = POINTER TO OptionsDesc;
27  OptionsDesc = RECORD
28    options- : ArrayList.ArrayList(Option);
29  END;
30
31PROCEDURE IsList* (o : Option) : BOOLEAN;
32BEGIN
33  RETURN o IS StringList;
34END IsList;
35
36PROCEDURE (o : Option) [ABSTRACT] Set* (value : Value.Object) : BOOLEAN;
37END Set;
38
39PROCEDURE (o : Option) [ABSTRACT] Write* (wr : TextRider.Writer);
40END Write;
41
42PROCEDURE (b : Boolean) INIT* (name : STRING; default : BOOLEAN);
43BEGIN
44  b.name := name;
45  b.value := default;
46END INIT;
47
48PROCEDURE (b : Boolean) Set* (value : Value.Object) : BOOLEAN;
49BEGIN
50  WITH value : Value.Boolean DO
51    b.value := value.value;
52    RETURN TRUE;
53  | value : Value.LongInt DO
54    b.value := value.value # 0;
55    RETURN TRUE;
56  ELSE
57    RETURN FALSE;
58  END;
59END Set;
60
61PROCEDURE (b : Boolean) Write* (wr : TextRider.Writer);
62BEGIN
63  wr.WriteBool(b.value);
64END Write;
65
66PROCEDURE (b : String) INIT* (name : STRING; default : STRING);
67BEGIN
68  b.name := name;
69  b.value := default;
70END INIT;
71
72PROCEDURE (b : String) Set* (value : Value.Object) : BOOLEAN;
73BEGIN
74  WITH value : Value.String DO
75    b.value := value.value;
76    RETURN TRUE;
77  ELSE
78    RETURN FALSE;
79  END;
80END Set;
81
82PROCEDURE (s : String) Write* (wr : TextRider.Writer);
83BEGIN
84  wr.WriteString('"');
85  wr.WriteObject(s.value);
86  wr.WriteString('"');
87END Write;
88
89PROCEDURE (l : StringList) INIT* (name : STRING);
90BEGIN
91  l.name := name;
92  l.value := NEW(ArrayList.ArrayList(STRING), 10);
93END INIT;
94
95PROCEDURE (l : StringList) Set* (value : Value.Object) : BOOLEAN;
96BEGIN
97  WITH value : Value.String DO
98    l.value.Append(value.value);
99    RETURN TRUE
100  ELSE
101    RETURN FALSE
102  END
103END Set;
104
105PROCEDURE (l : StringList) Write* (wr : TextRider.Writer);
106VAR i : LONGINT;
107BEGIN
108  FOR i := 0 TO l.value.Size()-1 DO
109    IF i # 0 THEN wr.WriteString(", ") END;
110    wr.WriteString('"'); wr.WriteObject(l.value.Get(i)); wr.WriteString('"');
111  END;
112END Write;
113
114PROCEDURE (l : StringList) Contains* (value : STRING) : BOOLEAN;
115VAR
116  i : LONGINT;
117  string : STRING;
118BEGIN
119  FOR i := 0 TO l.value.Size() - 1 DO
120    string := l.value.Get(i);
121    IF string.Equals(value) THEN RETURN TRUE END;
122  END;
123  RETURN FALSE;
124END Contains;
125
126PROCEDURE (l : StringList) IsPrefix* (value : STRING; VAR base : STRING) : BOOLEAN;
127VAR
128  i : LONGINT;
129  prefix : STRING;
130BEGIN
131  FOR i := 0 TO l.value.Size() -1 DO
132    prefix := l.value.Get(i);
133    IF value.StartsWith(prefix) THEN
134      base := value.Substring(prefix.length, value.length);
135      RETURN TRUE;
136    END;
137  END;
138  RETURN FALSE;
139END IsPrefix;
140
141PROCEDURE (o : Options) Append* (op : Option);
142BEGIN
143  o.options.Append(op);
144END Append;
145
146PROCEDURE (o : Options) Boolean* (name : STRING; default : BOOLEAN) : Boolean;
147VAR b : Boolean;
148BEGIN
149  b := NEW(Boolean, name, default);
150  o.Append(b);
151  RETURN b;
152END Boolean;
153
154PROCEDURE (o : Options) String* (name : STRING; default : STRING) : String;
155VAR s : String;
156BEGIN
157  s := NEW(String, name, default);
158  o.Append(s);
159  RETURN s;
160END String;
161
162PROCEDURE (o : Options) StringList* (name : STRING) : StringList;
163VAR s : StringList;
164BEGIN
165  s := NEW(StringList, name);
166  o.Append(s);
167  RETURN s;
168END StringList;
169
170PROCEDURE (o : Options) Find* (name : STRING) : Option;
171VAR
172  i : LONGINT;
173  op : Option;
174BEGIN
175  FOR i := 0 TO o.options.Size()-1 DO
176    op := o.options.Get(i);
177    IF op.name.Equals(name) THEN RETURN op END;
178  END;
179  RETURN NIL;
180END Find;
181
182PROCEDURE (o : Options) Merge* (set : Options);
183VAR
184  i : LONGINT;
185  op : Option;
186BEGIN
187  FOR i := 0 TO set.options.Size()-1 DO
188    op := set.options.Get(i);
189    IF o.Find(op.name) # NIL THEN
190      Log.Object("Options:Merge duplicate name", op.name);
191    ELSE
192      o.Append(op);
193    END;
194  END;
195END Merge;
196
197PROCEDURE (o : Options) INIT* ;
198BEGIN
199  o.options := NEW(ArrayList.ArrayList(Option), 10);
200END INIT;
201
202PROCEDURE (o : Options) Write* (wr : TextRider.Writer);
203VAR i : LONGINT; opt : Option;
204BEGIN
205  FOR i := 0 TO o.options.Size()-1 DO
206    opt := o.options.Get(i);
207    wr.WriteString("  ");
208    wr.WriteObject(opt.name);
209    wr.WriteString(" = ");
210    opt.Write(wr);
211    wr.WriteString(";");
212    wr.WriteLn;
213  END;
214END Write;
215
216END H2O:Option.
217