1/**
2 * Since Nix does not have a standard location like /usr/share,
3 * where GSettings system could look for schemas, we need to point the software to a correct location somehow.
4 * For executables, we handle this using wrappers but this is not an option for libraries like e-d-s.
5 * Instead, we hardcode the schema path when creating the settings.
6 * A schema path (ie org.gnome.evolution) can be replaced by @EVOLUTION_SCHEMA_ID@
7 * which is then replaced at build time by substituteAll.
8 * The mapping is provided in a json file ./glib-schema-to-var.json
9 */
10
11@initialize:python@
12@@
13import json
14
15cpp_constants = {}
16
17def register_cpp_constant(const_name, val):
18 cpp_constants[const_name] = val.strip()
19
20def resolve_cpp_constant(const_name):
21 return cpp_constants.get(const_name, const_name)
22
23with open("./glib-schema-to-var.json") as mapping_file:
24 schema_to_var = json.load(mapping_file);
25
26def get_schema_directory(schema_id):
27 # Sometimes the schema id is referenced using C preprocessor #define constant in the same file
28 # let’s try to resolve it first.
29 schema_id = resolve_cpp_constant(schema_id.strip()).strip('"')
30 if schema_id in schema_to_var:
31 return f'"@{schema_to_var[schema_id]}@"'
32 raise Exception(f"Unknown schema path {schema_id!r}, please add it to ./glib-schema-to-var.json")
33
34@find_cpp_constants@
35identifier const_name;
36expression val;
37@@
38
39#define const_name val
40
41@script:python record_cpp_constants depends on find_cpp_constants@
42const_name << find_cpp_constants.const_name;
43val << find_cpp_constants.val;
44@@
45
46register_cpp_constant(const_name, val)
47
48
49@depends on ever record_cpp_constants || never record_cpp_constants@
50// We want to run after #define constants have been collected but even if there are no #defines.
51expression SCHEMA_ID;
52expression settings;
53// Coccinelle does not like autocleanup macros in + sections,
54// let’s use fresh id with concatenation to produce the code as a string.
55fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
56fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
57fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
58@@
59-settings = g_settings_new(SCHEMA_ID);
60+{
61+ schema_source_decl;
62+ schema_decl;
63+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
64+ g_settings_schema_source_get_default(),
65+ TRUE,
66+ NULL);
67+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
68+ settings = g_settings_new_full(schema, NULL, NULL);
69+}
70
71
72@depends on ever record_cpp_constants || never record_cpp_constants@
73// We want to run after #define constants have been collected but even if there are no #defines.
74expression SCHEMA_ID;
75expression settings;
76expression BACKEND;
77// Coccinelle does not like autocleanup macros in + sections,
78// let’s use fresh id with concatenation to produce the code as a string.
79fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
80fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
81fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
82@@
83-settings = g_settings_new_with_backend(SCHEMA_ID, BACKEND);
84+{
85+ schema_source_decl;
86+ schema_decl;
87+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
88+ g_settings_schema_source_get_default(),
89+ TRUE,
90+ NULL);
91+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
92+ settings = g_settings_new_full(schema, BACKEND, NULL);
93+}
94
95
96@depends on ever record_cpp_constants || never record_cpp_constants@
97// We want to run after #define constants have been collected but even if there are no #defines.
98expression SCHEMA_ID;
99expression settings;
100expression BACKEND;
101expression PATH;
102// Coccinelle does not like autocleanup macros in + sections,
103// let’s use fresh id with concatenation to produce the code as a string.
104fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
105fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
106fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
107@@
108-settings = g_settings_new_with_backend_and_path(SCHEMA_ID, BACKEND, PATH);
109+{
110+ schema_source_decl;
111+ schema_decl;
112+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
113+ g_settings_schema_source_get_default(),
114+ TRUE,
115+ NULL);
116+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
117+ settings = g_settings_new_full(schema, BACKEND, PATH);
118+}
119
120
121@depends on ever record_cpp_constants || never record_cpp_constants@
122// We want to run after #define constants have been collected but even if there are no #defines.
123expression SCHEMA_ID;
124expression settings;
125expression PATH;
126// Coccinelle does not like autocleanup macros in + sections,
127// let’s use fresh id with concatenation to produce the code as a string.
128fresh identifier schema_source_decl = "g_autoptr(GSettingsSchemaSource) " ## "schema_source";
129fresh identifier schema_decl = "g_autoptr(GSettingsSchema) " ## "schema";
130fresh identifier SCHEMA_DIRECTORY = script:python(SCHEMA_ID) { get_schema_directory(SCHEMA_ID) };
131@@
132-settings = g_settings_new_with_path(SCHEMA_ID, PATH);
133+{
134+ schema_source_decl;
135+ schema_decl;
136+ schema_source = g_settings_schema_source_new_from_directory(SCHEMA_DIRECTORY,
137+ g_settings_schema_source_get_default(),
138+ TRUE,
139+ NULL);
140+ schema = g_settings_schema_source_lookup(schema_source, SCHEMA_ID, FALSE);
141+ settings = g_settings_new_full(schema, NULL, PATH);
142+}