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