Updated Danish translation
[banshee.git] / build / GSettingsSchemaExtractor.cs
blobb4ecc807087e980d14d9faee063566331bec76b8
1 using System;
2 using System.IO;
3 using System.Linq;
4 using System.Text;
5 using System.Text.RegularExpressions;
6 using System.Collections.Generic;
7 using System.Reflection;
9 public class GSettingsSchemaExtractorProgram
11 private static HashSet<FieldInfo> schema_fields;
12 private static int schema_count;
14 public static void Main(string [] args)
16 if (args.Length != 1) {
17 Console.Error.WriteLine ("Usage: gsettings-schema-extractor.exe /path/to/binaries/");
18 Environment.Exit (1);
21 var dir = new DirectoryInfo (args [0]);
22 if (!dir.Exists) {
23 Console.Error.WriteLine (args [0] + " does not exist");
24 Environment.Exit (1);
27 Extract (dir);
30 private static void Extract (DirectoryInfo dir)
32 var dot_net_assemblies = dir.EnumerateFiles ()
33 .Where (f => f.FullName.EndsWith (".dll", true, System.Globalization.CultureInfo.InvariantCulture) ||
34 f.FullName.EndsWith (".exe", true, System.Globalization.CultureInfo.InvariantCulture));
36 if (!dot_net_assemblies.Any ()) {
37 Console.Error.WriteLine ("No binary files found in specified path");
38 Environment.Exit (1);
41 var types = new List<Type> ();
42 foreach (var file in dot_net_assemblies) {
43 Assembly asm = Assembly.LoadFrom (file.FullName);
44 types.AddRange (asm.GetTypes ());
45 Console.WriteLine ("Inspecting types in " + file.Name);
48 StringBuilder sbuilder = Extract (types);
49 if (sbuilder != null) {
51 string outputFile = Path.Combine (dir.FullName, "org.gnome.banshee.gschema.xml");
53 using (StreamWriter writer = new StreamWriter (outputFile)) {
54 writer.Write (sbuilder.ToString ());
57 Console.WriteLine ("Successfully wrote " + Path.GetFileName (outputFile));
61 internal static StringBuilder Extract (IEnumerable<Type> types)
63 Console.WriteLine ("Generating schemas");
64 schema_count = 0;
65 schema_fields = new HashSet<FieldInfo> ();
67 foreach (Type type in types) {
68 foreach (FieldInfo field in type.GetFields (BindingFlags.Public |
69 BindingFlags.NonPublic |
70 BindingFlags.Static)) {
71 if (CheckForValidEntry (type, field)) {
72 schema_fields.Add (field);
77 if (schema_fields.Count > 0) {
79 var schemaSet = new SchemaSet ();
81 foreach (FieldInfo field in schema_fields) {
82 GSettingsKey.ExtractFromField (schemaSet, field);
85 StringBuilder final = new StringBuilder ();
86 final.Append ("<schemalist>\n");
88 foreach (GSettingsSchema schema in schemaSet.Schemas.Values) {
89 final.Append (schema.ToString ());
92 final.Append ("</schemalist>\n");
94 return final;
96 return null;
99 internal class InvalidSchemaException : Exception
101 internal InvalidSchemaException (string msg) : base (msg)
106 static bool CheckForValidEntry (Type type, FieldInfo field)
108 if (!field.FieldType.IsGenericType || field.Name == "Zero") {
109 return false;
112 string type_definition = field.FieldType.GetGenericTypeDefinition ().Name;
114 if (type_definition.StartsWith ("SchemaEntry")) {
115 Console.WriteLine ("Found SchemaEntry: " + type.FullName + "." + field.Name);
117 return true;
120 return false;
123 private static string GetStringValueOfFieldNamed (object schemaEntryObject, string fieldName)
125 FieldInfo field = schemaEntryObject.GetType ().GetField (fieldName);
126 return (string)field.GetValue (schemaEntryObject);
129 private static string GetValueString (Type type, object o)
131 if (type == typeof (bool)) {
132 return o == null ? null : o.ToString ().ToLower ();
135 if (type == typeof (string)) {
136 string value = o == null ? String.Empty : o.ToString ();
137 return String.Format ("'{0}'", value);
140 if (type == typeof (int) || type == typeof (double)) {
141 return o == null ? null : o.ToString ();
144 throw new Exception (String.Format ("Unsupported type '{0}'", type));
147 private static string GetGcType (Type type)
149 if (type == null) {
150 throw new ArgumentNullException ("type");
153 // gctypes to return taken from http://developer.gnome.org/glib/unstable/glib-GVariant.html#GVariantClass
155 if (type == typeof (bool)) {
156 return "b";
159 if (type == typeof (int)) {
160 return "i";
163 if (type == typeof (double)) {
164 return "d";
167 if (type == typeof (string)) {
168 return "s";
171 throw new Exception (String.Format ("Unsupported type '{0}'", type));
174 internal struct GSettingsSchema
176 internal string Id { get; private set; }
177 internal string Path { get { return Id.Replace ("org.gnome.", "/apps/").Replace (".", "/") + "/"; } }
179 internal HashSet<GSettingsKey> Keys { get; private set; }
181 internal GSettingsSchema (string id) : this ()
183 Id = id;
184 Keys = new HashSet<GSettingsKey> ();
187 public override string ToString ()
189 string result = String.Empty;
190 result += String.Format (" <schema id=\"{0}\" path=\"{1}\" gettext-domain=\"banshee\">\n", Id, Path);
191 foreach (var key in Keys) {
192 result += key.ToString ();
194 result += (" </schema>\n");
195 return result;
200 internal struct GSettingsKey
202 internal GSettingsSchema ParentSchema { get; private set; }
203 internal string Default { get; private set; }
204 internal string KeyName { get; private set; }
205 internal string KeyType { get; private set; }
206 internal string Summary { get; private set; }
207 internal string Description { get; private set; }
209 internal static GSettingsKey ExtractFromField (SchemaSet schemaSet, FieldInfo field)
211 if (field == null) {
212 throw new ArgumentNullException ("field");
215 object schema = field.GetValue (null);
216 if (schema == null) {
217 throw new InvalidSchemaException (String.Format (
218 "Schema could not be retrieved from field {0} in type {1}",
219 field.Name, field.DeclaringType.FullName));
222 var default_value_field = schema.GetType ().GetField ("DefaultValue");
223 var default_value = default_value_field.GetValue (schema);
225 var default_value_type = default_value_field.FieldType;
226 var namespce = GetStringValueOfFieldNamed (schema, "Namespace");
227 var key = GetStringValueOfFieldNamed (schema, "Key");
228 var short_description = GetStringValueOfFieldNamed (schema, "ShortDescription");
229 var long_description = GetStringValueOfFieldNamed (schema, "LongDescription");
231 return new GSettingsKey (schemaSet, default_value, default_value_type, namespce, key, short_description, long_description);
234 private GSettingsKey (SchemaSet schemaSet, object defaultValue, Type defaultValueType,
235 string namespce, string key,
236 string short_desc, string long_desc) : this ()
238 ParentSchema = schemaSet.RetrieveOrCreate (namespce);
240 Default = GetDefault (defaultValue, defaultValueType);
241 KeyName = key.Replace ("_", "-");
242 KeyType = GetTypeAttrib (defaultValue, defaultValueType);
243 Summary = short_desc;
244 Description = long_desc;
246 ParentSchema.Keys.Add (this);
249 public override string ToString ()
251 string result = String.Empty;
252 result += String.Format (" <key name=\"{0}\" type=\"{1}\">\n", KeyName, KeyType);
253 result += String.Format (" <default>{0}</default>\n", Default);
254 result += String.Format (" <summary>{0}</summary>\n", Summary);
255 result += String.Format (" <description>{0}</description>\n", Description);
256 result += (" </key>\n");
257 return result;
261 internal class SchemaSet
263 internal SchemaSet ()
265 Schemas = new Dictionary<string, GSettingsSchema> ();
268 internal Dictionary<string, GSettingsSchema> Schemas { get; private set; }
270 private static string NamespaceToId (string namespce)
272 return "org.gnome.banshee." + CamelCaseToUnderScoreLowerCase (namespce);
275 internal GSettingsSchema RetrieveOrCreate (string namespce)
277 string id = NamespaceToId (namespce);
278 GSettingsSchema schema;
279 if (!Schemas.TryGetValue (id, out schema)) {
280 schema = new GSettingsSchema (id);
281 Schemas [id] = schema;
283 return schema;
287 internal static string GetTypeAttrib (object defaultValue, Type defaultValueType)
289 var i_enumerable_interface = defaultValueType.GetInterfaces ()
290 .Where (i => i.IsGenericType && i.GetGenericTypeDefinition () == typeof (IEnumerable<>)).FirstOrDefault ();
291 bool list = defaultValueType.IsArray;
292 if (list) {
293 var inner_type = i_enumerable_interface.GetGenericArguments () [0];
294 return "a" + GetGcType (inner_type);
296 return GetGcType (defaultValueType);
299 internal static string GetDefault (object defaultValue, Type defaultValueType)
301 bool list = defaultValueType.IsArray;
303 string str_val = null;
305 if (list) {
306 if (defaultValue == null || ((object[])defaultValue).Length == 0) {
307 str_val = "[]";
308 } else {
309 var type = Type.GetTypeArray ((object [])defaultValue) [0];
310 str_val = "[";
311 object [] arr = (object [])defaultValue;
312 for (int i = 0; i < arr.Length; i++) {
313 str_val += GetValueString (type, arr [i]).Replace (",", "\\,");
314 if (i < arr.Length - 1) {
315 str_val += ",";
318 str_val += "]";
320 } else {
321 str_val = GetValueString (defaultValueType, defaultValue);
323 return str_val;
326 private static string CamelCaseToUnderScoreLowerCase (string s)
328 string undercase = String.Empty;
329 string [] tokens = Regex.Split (s, "([A-Z]{1}[a-z]+)");
331 for(int i = 0; i < tokens.Length; i++) {
332 if (tokens [i] == String.Empty) {
333 continue;
336 undercase += tokens [i].ToLower();
337 if (i < tokens.Length - 2) {
338 undercase += "_";
342 return undercase;