[glib/new-gsettings] Make the gconf schema parser a class
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/new-gsettings] Make the gconf schema parser a class
- Date: Sat, 17 Apr 2010 16:00:47 +0000 (UTC)
commit aac33fb2a807e4d5b0baa45d7a1c638911761a97
Author: Vincent Untz <vuntz gnome org>
Date: Sat Apr 17 11:57:06 2010 -0400
Make the gconf schema parser a class
gio/gsettings-schema-convert | 341 ++++++++++++++++++++++--------------------
1 files changed, 177 insertions(+), 164 deletions(-)
---
diff --git a/gio/gsettings-schema-convert b/gio/gsettings-schema-convert
index d16c1cc..54c15e9 100755
--- a/gio/gsettings-schema-convert
+++ b/gio/gsettings-schema-convert
@@ -22,6 +22,8 @@
# TODO: add alias support for choices
# choices: 'this-is-an-alias' = 'real', 'other', 'real'
+# TODO: we don't support migrating a pair from a gconf schema. It has yet to be
+# seen in real-world usage, though.
import os
import sys
@@ -348,106 +350,6 @@ class GSettingsSchemaKey:
######################################
-def map_gconf_type_to_variant_type(gconftype, gconfsubtype):
- typemap = { 'string': 's', 'int': 'i', 'float': 'f', 'bool': 'b', 'list': 'a' }
- result = typemap[gconftype]
- if gconftype == 'list':
- result = result + typemap[gconfsubtype]
- return result
-
-
-class GConfSchema:
-
- def __init__(self, node):
- locale_node = node.find('locale')
-
- self.key = node.find('key').text
- self.type = node.find('type').text
- if self.type == 'list':
- self.list_type = node.find('list_type').text
- else:
- self.list_type = None
- self.varianttype = map_gconf_type_to_variant_type(self.type, self.list_type)
-
- applyto_node = node.find('applyto')
- if applyto_node is not None:
- self.applyto = node.find('applyto').text
- self.applyto.strip()
- self.keyname = self.applyto[self.applyto.rfind('/')+1:]
- self.prefix = self.applyto[:self.applyto.rfind('/')+1]
- else:
- self.applyto = None
- self.key.strip()
- self.keyname = self.key[self.key.rfind('/')+1:]
- self.prefix = self.key[:self.key.rfind('/')+1]
- self.prefix = os.path.normpath(self.prefix)
-
- try:
- self.default = locale_node.find('default').text
- self.localized = 'messages'
- except:
- try:
- self.default = node.find('default').text
- self.localized = None
- except:
- raise GSettingsSchemaConvertException('No default value for key \'%s\'. A default value is always required in GSettings schemas.' % self.applyto or self.key)
- self.typed_default = None
-
- self.short = self._get_value_with_locale(node, locale_node, 'short')
- self.long = self._get_value_with_locale(node, locale_node, 'long')
-
- self.short = self._oneline(self.short)
- self.long = self._oneline(self.long)
-
- # Fix the default to be parsable by GVariant
- if self.type == 'string':
- if not self.default:
- self.default = '\'\''
- else:
- self.default.replace('\'', '\\\'')
- self.default = '\'%s\'' % self.default
- elif self.type == 'bool':
- self.default = self.default.lower()
- elif self.type == 'list':
- l = self.default.strip()
- if not (l[0] == '[' and l[-1] == ']'):
- raise GSettingsSchemaConvertException('Cannot parse default list value \'%s\' for key \'%s\'.' % (self.default, self.applyto or self.key))
- values = l[1:-1].strip()
- if not values:
- self.typed_default = '@%s []' % self.varianttype
- elif self.list_type == 'string':
- items = [ item.strip() for item in values.split(',') ]
- items = [ item.replace('\'', '\\\'') for item in items ]
- values = ', '.join([ '\'%s\'' % item for item in items ])
- self.default = '[ %s ]' % values
-
- def _get_value_with_locale(self, node, locale_node, element):
- element_node = None
- if locale_node is not None:
- element_node = locale_node.find(element)
- if element_node is None:
- element_node = node.find(element)
- if element_node is not None:
- return element_node.text
- else:
- return None
-
- def _oneline(self, s):
- lines = s.splitlines()
- result = ''
- for line in lines:
- result += ' ' + line.lstrip()
- return result.strip()
-
- def get_gsettings_schema_key(self):
- key = GSettingsSchemaKey()
- key.fill(self.keyname, self.varianttype, self.default, self.typed_default, self.localized, self.keyname, self.short, self.long, None, None)
- return key
-
-
-######################################
-
-
class SimpleSchemaParser:
allowed_tokens = {
@@ -733,82 +635,192 @@ class SimpleSchemaParser:
######################################
-def read_gconf_schema(gconf_schema_file, default_schema_id):
- gsettings_schema_root = GSettingsSchemaRoot()
+def map_gconf_type_to_variant_type(gconftype, gconfsubtype):
+ typemap = { 'string': 's', 'int': 'i', 'float': 'f', 'bool': 'b', 'list': 'a' }
+ result = typemap[gconftype]
+ if gconftype == 'list':
+ result = result + typemap[gconfsubtype]
+ return result
- default_schema_id_count = 0
- gconfschemafile_node = ET.parse(gconf_schema_file).getroot()
- for schemalist_node in gconfschemafile_node.findall('schemalist'):
- for schema_node in schemalist_node.findall('schema'):
- gconf_schema = GConfSchema(schema_node)
+class GConfSchema:
- schemas_only = (gconf_schema.applyto is not None)
+ def __init__(self, node):
+ locale_node = node.find('locale')
- dirpath = gconf_schema.prefix
- if dirpath[0] != '/':
- raise GSettingsSchemaConvertException('Key \'%s\' has a relative path. There is no relative path in GSettings schemas.' % gconf_schema.applyto or gconf_schema.key)
+ self.key = node.find('key').text
+ self.type = node.find('type').text
+ if self.type == 'list':
+ self.list_type = node.find('list_type').text
+ else:
+ self.list_type = None
+ self.varianttype = map_gconf_type_to_variant_type(self.type, self.list_type)
- # remove leading 'schemas/' for schemas-only keys
- if schemas_only and dirpath.startswith('/schemas/'):
- dirpath = dirpath[len('/schemas'):]
+ applyto_node = node.find('applyto')
+ if applyto_node is not None:
+ self.applyto = node.find('applyto').text
+ self.applyto.strip()
+ self.keyname = self.applyto[self.applyto.rfind('/')+1:]
+ self.prefix = self.applyto[:self.applyto.rfind('/')+1]
+ else:
+ self.applyto = None
+ self.key.strip()
+ self.keyname = self.key[self.key.rfind('/')+1:]
+ self.prefix = self.key[:self.key.rfind('/')+1]
+ self.prefix = os.path.normpath(self.prefix)
- if len(dirpath) == 1:
- raise GSettingsSchemaConvertException('Key \'%s\' is a toplevel key. Toplevel keys are not accepted in GSettings schemas.' % gconf_schema.applyto or gconf_schema.key)
+ try:
+ self.default = locale_node.find('default').text
+ self.localized = 'messages'
+ except:
+ try:
+ self.default = node.find('default').text
+ self.localized = None
+ except:
+ raise GSettingsSchemaConvertException('No default value for key \'%s\'. A default value is always required in GSettings schemas.' % self.applyto or self.key)
+ self.typed_default = None
- # remove trailing slash because we'll split the string
- if dirpath[-1] == '/':
- dirpath = dirpath[:-1]
- # and also remove leading slash when splitting
- hierarchy = dirpath[1:].split('/')
+ self.short = self._get_value_with_locale(node, locale_node, 'short')
+ self.long = self._get_value_with_locale(node, locale_node, 'long')
- # we don't want to put apps/ and desktop/ keys in the same schema,
- # so we have a first step where we make sure to create a new schema
- # to avoid this case if necessary
- gsettings_schema = None
- for schema in gsettings_schema_root.schemas:
- if schemas_only:
- schema_path = schema.path
- else:
- schema_path = schema._hacky_path
- if dirpath.startswith(schema_path):
- gsettings_schema = schema
+ self.short = self._oneline(self.short)
+ self.long = self._oneline(self.long)
+
+ # Fix the default to be parsable by GVariant
+ if self.type == 'string':
+ if not self.default:
+ self.default = '\'\''
+ else:
+ self.default.replace('\'', '\\\'')
+ self.default = '\'%s\'' % self.default
+ elif self.type == 'bool':
+ self.default = self.default.lower()
+ elif self.type == 'list':
+ l = self.default.strip()
+ if not (l[0] == '[' and l[-1] == ']'):
+ raise GSettingsSchemaConvertException('Cannot parse default list value \'%s\' for key \'%s\'.' % (self.default, self.applyto or self.key))
+ values = l[1:-1].strip()
+ if not values:
+ self.typed_default = '@%s []' % self.varianttype
+ elif self.list_type == 'string':
+ items = [ item.strip() for item in values.split(',') ]
+ items = [ item.replace('\'', '\\\'') for item in items ]
+ values = ', '.join([ '\'%s\'' % item for item in items ])
+ self.default = '[ %s ]' % values
+
+ def _get_value_with_locale(self, node, locale_node, element):
+ element_node = None
+ if locale_node is not None:
+ element_node = locale_node.find(element)
+ if element_node is None:
+ element_node = node.find(element)
+ if element_node is not None:
+ return element_node.text
+ else:
+ return None
+
+ def _oneline(self, s):
+ lines = s.splitlines()
+ result = ''
+ for line in lines:
+ result += ' ' + line.lstrip()
+ return result.strip()
+
+ def get_gsettings_schema_key(self):
+ key = GSettingsSchemaKey()
+ key.fill(self.keyname, self.varianttype, self.default, self.typed_default, self.localized, self.keyname, self.short, self.long, None, None)
+ return key
+
+
+######################################
+
+
+class GConfSchemaParser:
+
+ def __init__(self, file, default_schema_id):
+ self.file = file
+ self.default_schema_id = default_schema_id
+
+ self.root = None
+ self.default_schema_id_count = 0
+
+ def _insert_schema(self, gconf_schema):
+ schemas_only = (gconf_schema.applyto is not None)
+
+ dirpath = gconf_schema.prefix
+ if dirpath[0] != '/':
+ raise GSettingsSchemaConvertException('Key \'%s\' has a relative path. There is no relative path in GSettings schemas.' % gconf_schema.applyto or gconf_schema.key)
+
+ # remove leading 'schemas/' for schemas-only keys
+ if schemas_only and dirpath.startswith('/schemas/'):
+ dirpath = dirpath[len('/schemas'):]
+
+ if len(dirpath) == 1:
+ raise GSettingsSchemaConvertException('Key \'%s\' is a toplevel key. Toplevel keys are not accepted in GSettings schemas.' % gconf_schema.applyto or gconf_schema.key)
+
+ # remove trailing slash because we'll split the string
+ if dirpath[-1] == '/':
+ dirpath = dirpath[:-1]
+ # and also remove leading slash when splitting
+ hierarchy = dirpath[1:].split('/')
+
+ # we don't want to put apps/ and desktop/ keys in the same schema,
+ # so we have a first step where we make sure to create a new schema
+ # to avoid this case if necessary
+ gsettings_schema = None
+ for schema in self.root.schemas:
+ if schemas_only:
+ schema_path = schema.path
+ else:
+ schema_path = schema._hacky_path
+ if dirpath.startswith(schema_path):
+ gsettings_schema = schema
+ break
+ if not gsettings_schema:
+ gsettings_schema = GSettingsSchema()
+ if self.default_schema_id:
+ gsettings_schema.id = self.default_schema_id
+ if self.default_schema_id_count > 0:
+ gsettings_schema.id += '.FIXME-%s' % self.default_schema_id_count
+ self.default_schema_id_count += 1
+ else:
+ gsettings_schema.id = 'FIXME'
+ if schemas_only:
+ gsettings_schema.path = '/' + hierarchy[0] + '/'
+ else:
+ gsettings_schema._hacky_path = '/' + hierarchy[0] + '/'
+ self.root.schemas.append(gsettings_schema)
+
+ # we create all the subdirs that lead to this key
+ gsettings_dir = gsettings_schema
+ for item in hierarchy[1:]:
+ subdir = None
+ for dir in gsettings_dir.dirs:
+ if dir.name == item:
+ subdir = dir
break
- if not gsettings_schema:
- gsettings_schema = GSettingsSchema()
- if default_schema_id:
- gsettings_schema.id = default_schema_id
- if default_schema_id_count > 0:
- gsettings_schema.id += '.FIXME-%s' % default_schema_id_count
- default_schema_id_count += 1
- else:
- gsettings_schema.id = 'FIXME'
- if schemas_only:
- gsettings_schema.path = '/' + hierarchy[0] + '/'
- else:
- gsettings_schema._hacky_path = '/' + hierarchy[0] + '/'
- gsettings_schema_root.schemas.append(gsettings_schema)
+ if not subdir:
+ subdir = GSettingsSchemaDir()
+ subdir.name = item
+ gsettings_dir.dirs.append(subdir)
+ gsettings_dir = subdir
+
+ # we have the final directory, so we can put the key there
+ gsettings_dir.keys.append(gconf_schema.get_gsettings_schema_key())
- # we create all the subdirs that lead to this key
- gsettings_dir = gsettings_schema
- for item in hierarchy[1:]:
- subdir = None
- for dir in gsettings_dir.dirs:
- if dir.name == item:
- subdir = dir
- break
- if not subdir:
- subdir = GSettingsSchemaDir()
- subdir.name = item
- gsettings_dir.dirs.append(subdir)
- gsettings_dir = subdir
+ def parse(self):
+ # reset the state of the parser
+ self.root = GSettingsSchemaRoot()
+ self.default_schema_id_count = 0
- # we have the final directory, so we can put the key there
- gsettings_dir.keys.append(gconf_schema.get_gsettings_schema_key())
+ gconfschemafile_node = ET.parse(self.file).getroot()
+ for schemalist_node in gconfschemafile_node.findall('schemalist'):
+ for schema_node in schemalist_node.findall('schema'):
+ self._insert_schema(GConfSchema(schema_node))
- gsettings_schema_root.simplify()
+ self.root.simplify()
- return gsettings_schema_root
+ return self.root
######################################
@@ -866,7 +878,8 @@ def main(args):
if options.gconf:
try:
- schema_root = read_gconf_schema(argfile, options.schema_id)
+ parser = GConfSchemaParser(argfile, options.schema_id)
+ schema_root = parser.parse()
except SyntaxError, e:
raise GSettingsSchemaConvertException('\'%s\' does not look like a valid gconf schema file: %s' % (argfile, e))
else:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]