about summary refs log tree commit diff
path: root/pkgs/development/libraries/glib/hardcode-gsettings.cocci
blob: bedacf846bc49e8566ba5c8673ade5e22e4b51b8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
 * Since Nix does not have a standard location like /usr/share,
 * where GSettings system could look for schemas, we need to point the software to a correct location somehow.
 * For executables, we handle this using wrappers but this is not an option for libraries like e-d-s.
 * Instead, we hardcode the schema path when creating the settings.
 * A schema path (ie org.gnome.evolution) can be replaced by @EVOLUTION_SCHEMA_PATH@
 * which is then replaced at build time by substituteAll.
 * The mapping is provided in a json file ./glib-schema-to-var.json
 */

@initialize:python@
@@
import json

cpp_constants = {}

def register_cpp_constant(const_name, val):
    cpp_constants[const_name] = val.strip()

def resolve_cpp_constant(const_name):
    return cpp_constants.get(const_name, const_name)

with open("./glib-schema-to-var.json") as mapping_file:
    schema_to_var = json.load(mapping_file);

def get_schema_directory(schema_path):
    # Sometimes the schema id is referenced using C preprocessor #define constant in the same file
    # let’s try to resolve it first.
    schema_path = resolve_cpp_constant(schema_path.strip()).strip('"')
    if schema_path in schema_to_var:
        return f'"@{schema_to_var[schema_path]}@"'
    raise Exception(f"Unknown schema path {schema_path!r}, please add it to ./glib-schema-to-var.json")


@find_cpp_constants@
identifier const_name;
expression val;
@@

#define const_name val

@script:python record_cpp_constants depends on find_cpp_constants@
const_name << find_cpp_constants.const_name;
val << find_cpp_constants.val;
@@

register_cpp_constant(const_name, val)


@depends on ever record_cpp_constants || never record_cpp_constants@
// We want to run after #define constants have been collected but even if there are no #defines.
expression SCHEMA_PATH;
expression settings;
// Coccinelle does not like autocleanup macros in + sections,
// let’s use fresh id with concatenation to produce the code as a string.
fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_PATH) { get_schema_directory(SCHEMA_PATH) };
@@
-settings = g_settings_new(SCHEMA_PATH);
+{
+	schema_source_decl;
+	schema_decl;
+	schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
+	                                                            g_settings_schema_source_get_default(),
+	                                                            TRUE,
+	                                                            NULL);
+	schema = g_settings_schema_source_lookup(schema_source, SCHEMA_PATH, FALSE);
+	settings = g_settings_new_full(schema, NULL, NULL);
+}