engine: issue warnings once per source
[dconf.git] / editor / dconf-schema.vala
blobfd35fb2158e3733aac114c2329ee83dacf7bd1d7
1 public class SchemaKey
3 public Schema schema;
4 public string name;
5 public string type;
6 public Variant default_value;
7 public SchemaValueRange? range;
8 public SchemaValueRange type_range;
9 public List<SchemaChoice> choices;
10 public string? enum_name;
11 public string? summary;
12 public string? description;
13 public string? gettext_domain;
15 public SchemaKey.from_xml(Xml.Node* node, Schema schema, string? gettext_domain)
17 this.schema = schema;
18 this.gettext_domain = gettext_domain;
20 for (var prop = node->properties; prop != null; prop = prop->next)
22 if (prop->name == "name")
23 name = prop->children->content;
24 else if (prop->name == "type")
25 type = prop->children->content;
26 else if (prop->name == "enum")
28 type = "s";
29 enum_name = prop->children->content;
31 else if (prop->name == "flags")
32 /* TODO: support this properly */
33 type = "as";
34 else
35 warning ("Unknown property on <key>, %s", prop->name);
38 //if (name == null || type == null)
39 // ?
41 for (var child = node->children; child != null; child = child->next)
43 if (child->name == "default")
45 try
47 default_value = Variant.parse(new VariantType(type), child->get_content());
49 catch (VariantParseError e)
51 // ...
54 else if (child->name == "summary")
55 summary = child->get_content();
56 else if (child->name == "description")
57 description = child->get_content();
58 else if (child->name == "range")
59 range = new SchemaValueRange.from_xml(type, child);
60 else if (child->name == "choices")
62 for (var n = child->children; n != null; n = n->next)
64 if (n->type != Xml.ElementType.ELEMENT_NODE)
65 continue;
66 if (n->name != "choice")
68 warning ("Unknown child tag in <choices>, <%s>", n->name);
69 continue;
72 string? value = null;
73 for (var prop = n->properties; prop != null; prop = prop->next)
75 if (prop->name == "value")
76 value = prop->children->content;
77 else
78 warning ("Unknown property on <choice>, %s", prop->name);
81 if (value == null)
83 warning ("Ignoring <choice> with no value");
84 continue;
87 var v = new Variant.string (value);
88 choices.append (new SchemaChoice(value, v));
91 else if (child->name == "aliases")
93 for (var n = child->children; n != null; n = n->next)
95 if (n->type != Xml.ElementType.ELEMENT_NODE)
96 continue;
97 if (n->name != "alias")
99 warning ("Unknown child tag in <aliases>, <%s>", n->name);
100 continue;
103 string? value = null, target = null;
104 for (var prop = n->properties; prop != null; prop = prop->next)
106 if (prop->name == "value")
107 value = prop->children->content;
108 else if (prop->name == "target")
109 target = prop->children->content;
110 else
111 warning ("Unknown property on <alias>, %s", prop->name);
114 if (value == null)
116 warning ("Ignoring <alias> with no value");
117 continue;
119 if (target == null)
121 warning ("Ignoring <alias> with no target");
122 continue;
125 var v = new Variant.string (target);
126 choices.append (new SchemaChoice(value, v));
129 else if (child->type != Xml.ElementType.TEXT_NODE && child->type != Xml.ElementType.COMMENT_NODE)
130 warning ("Unknown child tag in <key>, <%s>", child->name);
133 //if (default_value == null)
134 // ?
138 public class SchemaValue : GLib.Object
140 public uint index;
141 public string nick;
142 public int value;
144 public SchemaValue(uint index, string nick, int value)
146 this.index = index;
147 this.nick = nick;
148 this.value = value;
152 public class SchemaChoice
154 public string name;
155 public Variant value;
157 public SchemaChoice(string name, Variant value)
159 this.name = name;
160 this.value = value;
164 public class SchemaValueRange
166 public Variant min;
167 public Variant max;
169 public SchemaValueRange.from_xml(string type, Xml.Node* node)
171 for (var prop = node->properties; prop != null; prop = prop->next)
173 if (prop->name == "min")
177 min = Variant.parse(new VariantType(type), prop->children->content);
179 catch (VariantParseError e)
181 // ...
184 else if (prop->name == "max")
188 max = Variant.parse(new VariantType(type), prop->children->content);
190 catch (VariantParseError e)
192 // ...
195 else
196 warning ("Unknown property in <range>, %s", prop->name);
199 //if (min == null || max == null)
200 // ?
204 public class SchemaEnum
206 public SchemaList list;
207 public string id;
208 public GLib.List<SchemaValue> values = new GLib.List<SchemaValue>();
210 public SchemaEnum.from_xml(SchemaList list, Xml.Node* node)
212 this.list = list;
214 for (var prop = node->properties; prop != null; prop = prop->next)
216 if (prop->name == "id")
217 id = prop->children->content;
218 else
219 warning ("Unknown property in <enum>, %s", prop->name);
222 //if (id = null)
223 // ?
225 for (var child = node->children; child != null; child = child->next)
227 if (child->name == "value")
229 string? nick = null;
230 int value = -1;
232 for (var prop = child->properties; prop != null; prop = prop->next)
234 if (prop->name == "value")
235 value = int.parse(prop->children->content);
236 else if (prop->name == "nick")
237 nick = prop->children->content;
238 else
239 warning ("Unknown property in enum <value>, %s", prop->name);
242 //if (value < 0 || nick == null)
243 // ?
245 var schema_value = new SchemaValue (values.length(), nick, value);
246 values.append(schema_value);
248 else if (child->type != Xml.ElementType.TEXT_NODE && child->type != Xml.ElementType.COMMENT_NODE)
249 warning ("Unknown tag in <enum>, <%s>", child->name);
252 //if (default_value == null)
253 // ?
257 public class SchemaFlags
259 public SchemaList list;
260 public string id;
261 public GLib.List<SchemaValue> values = new GLib.List<SchemaValue>();
263 public SchemaFlags.from_xml(SchemaList list, Xml.Node* node)
265 this.list = list;
267 for (var prop = node->properties; prop != null; prop = prop->next)
269 if (prop->name == "id")
270 id = prop->children->content;
271 else
272 warning ("Unknown property in <flags>, %s", prop->name);
275 //if (id = null)
276 // ?
278 for (var child = node->children; child != null; child = child->next)
280 if (child->name == "value")
282 string? nick = null;
283 int value = -1;
285 for (var prop = child->properties; prop != null; prop = prop->next)
287 if (prop->name == "value")
288 value = int.parse(prop->children->content);
289 else if (prop->name == "nick")
290 nick = prop->children->content;
291 else
292 warning ("Unknown property in flags <value>, %s", prop->name);
295 //if (value < 0 || nick == null)
296 // ?
298 var schema_value = new SchemaValue (values.length(), nick, value);
299 values.append(schema_value);
301 else if (child->type != Xml.ElementType.TEXT_NODE && child->type != Xml.ElementType.COMMENT_NODE)
302 warning ("Unknown tag in <flags>, <%s>", child->name);
305 //if (default_value == null)
306 // ?
310 public class Schema
312 public SchemaList list;
313 public string id;
314 public string? path;
315 public GLib.HashTable<string, SchemaKey> keys = new GLib.HashTable<string, SchemaKey>(str_hash, str_equal);
317 public Schema.from_xml(SchemaList list, Xml.Node* node, string? gettext_domain)
319 this.list = list;
321 for (var prop = node->properties; prop != null; prop = prop->next)
323 if (prop->name == "id")
324 id = prop->children->content;
325 else if (prop->name == "path")
326 path = prop->children->content; // FIXME: Does the path have to end with '/'?
327 else if (prop->name == "gettext-domain")
328 gettext_domain = prop->children->content;
329 else
330 warning ("Unknown property on <schema>, %s", prop->name);
333 //if (id == null)
336 for (var child = node->children; child != null; child = child->next)
338 if (child->name != "key")
339 continue;
340 var key = new SchemaKey.from_xml(child, this, gettext_domain);
341 keys.insert(key.name, key);
346 public class SchemaList
348 public GLib.HashTable<string, Schema> schemas = new GLib.HashTable<string, Schema>(str_hash, str_equal);
349 public GLib.HashTable<string, SchemaKey> keys = new GLib.HashTable<string, SchemaKey>(str_hash, str_equal);
350 public GLib.HashTable<string, SchemaEnum> enums = new GLib.HashTable<string, SchemaEnum>(str_hash, str_equal);
351 public GLib.HashTable<string, SchemaFlags> flags = new GLib.HashTable<string, SchemaFlags>(str_hash, str_equal);
353 public void parse_file(string path)
355 var doc = Xml.Parser.parse_file(path);
356 if (doc == null)
357 return;
359 var root = doc->get_root_element();
360 if (root == null)
361 return;
362 if (root->name != "schemalist")
363 return;
365 string? gettext_domain = null;
366 for (var prop = root->properties; prop != null; prop = prop->next)
368 if (prop->name == "gettext-domain")
369 gettext_domain = prop->children->content;
372 for (var node = root->children; node != null; node = node->next)
374 if (node->name == "schema")
376 var schema = new Schema.from_xml(this, node, gettext_domain);
377 if (schema.path == null)
379 // FIXME: What to do here?
380 continue;
383 foreach (var key in schema.keys.get_values())
385 string full_name = schema.path + key.name;
386 keys.insert(full_name, key);
388 schemas.insert(schema.id, schema);
390 else if (node->name == "enum")
392 var enum = new SchemaEnum.from_xml(this, node);
393 enums.insert(enum.id, enum);
395 else if (node->name == "flags")
397 var f = new SchemaFlags.from_xml(this, node);
398 flags.insert(f.id, f);
400 else if (node->type == Xml.ElementType.COMMENT_NODE)
403 else if (node->type != Xml.ElementType.TEXT_NODE)
404 warning ("Unknown tag <%s>", node->name);
407 delete doc;
410 public void parse_override(string path)
412 var keyfile = new KeyFile();
415 keyfile.load_from_file(path, KeyFileFlags.NONE);
417 catch (Error e)
419 warning("Failed to load override file %s: %s", path, e.message);
420 return;
423 foreach (var group in keyfile.get_groups())
425 var schema = schemas.lookup(group);
426 if (schema == null)
427 continue;
429 string[] keys;
430 try { keys = keyfile.get_keys(group); } catch (Error e) { continue; }
432 foreach (var key_name in keys)
434 string value;
435 try { value = keyfile.get_value(group, key_name); } catch (Error e) { continue; }
437 var key = schema.keys.lookup (key_name);
438 if (key == null)
439 continue;
441 Variant default_value;
444 default_value = Variant.parse(new VariantType(key.type), value);
446 catch (VariantParseError e)
448 // ...
449 continue;
452 key.default_value = default_value;
457 public void load_directory(string dir) throws Error
459 var directory = File.new_for_path(dir);
461 var i = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0, null);
462 while (true)
464 var info = i.next_file (null);
465 if (info == null)
466 break;
467 var name = info.get_name();
469 if (name.has_suffix(".gschema.xml") || name.has_suffix(".enums.xml"))
470 parse_file(Path.build_filename(dir, name, null));
473 i = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0, null);
474 while (true)
476 var info = i.next_file (null);
477 if (info == null)
478 break;
479 var name = info.get_name();
481 if (name.has_suffix(".override"))
482 parse_override(Path.build_filename(dir, name, null));