changelog
[platform/upstream/freerdp.git] / scripts / update-settings-tests
1 #!/usr/bin/env python3
2 import os
3 import sys
4
5 def get_values(entry_dict, entry_type):
6     values = []
7     if '*' == entry_type:
8         for key in list(entry_dict.keys()):
9             if entry_type in key:
10                 values += entry_dict[key]
11                 entry_dict.pop(key, None)
12     elif entry_type in dict(entry_dict):
13         values = entry_dict[entry_type]
14         entry_dict.pop(entry_type, None)
15     if values:
16         return sorted(values)
17     return values
18
19 def write_entry(f, entry_dict, entry_type, entry_name):
20     values = get_values(entry_dict, entry_type)
21     if not values:
22         return
23
24     f.write('#define have_' + entry_name.lower() + '_list_indices\n')
25     f.write('static const size_t ' + entry_name.lower() + '_list_indices[] =\n')
26     f.write('{\n')
27
28     for val in values:
29         f.write('\tFreeRDP_' + val + ',\n')
30
31     f.write('};\n\n')
32
33 def write_str_case(f, entry_type, val):
34     f.write('\t\t{FreeRDP_' + val + ', ' + str(entry_type) + ', "FreeRDP_' + val + '"},\n')
35
36 def write_str(f, entry_dict):
37     f.write('struct settings_str_entry {\n')
38     f.write('\tsize_t id;\n')
39     f.write('\tsize_t type;\n')
40     f.write('\tconst char* str;\n')
41     f.write('};\n')
42     f.write('static const struct settings_str_entry settings_map[] =\n')
43     f.write('{\n')
44
45     entry_types = ['BOOL', 'UINT16', 'INT16', 'UINT32', 'INT32', 'UINT64', 'INT64', 'char*', '*']
46     for entry_type in entry_types:
47         values = get_values(entry_dict, entry_type)
48         if values:
49             for val in values:
50                 write_str_case(f, entry_types.index(entry_type), val)
51     f.write('};\n\n')
52     f.write('\n')
53     f.write('BOOL freerdp_settings_clone_keys(rdpSettings* dst, const rdpSettings* src)\n')
54     f.write('{\n')
55     f.write('\tsize_t x;\n')
56     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
57     f.write('\t{\n')
58     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
59     f.write('\t\tswitch(cur->type)\n')
60     f.write('\t\t{\n')
61     f.write('\t\t\tcase 0: /* bool */\n')
62     f.write('\t\t\t{\n')
63     f.write('\t\t\t\tBOOL sval = freerdp_settings_get_bool(src, cur->id);\n')
64     f.write('\t\t\t\tif (!freerdp_settings_set_bool(dst, cur->id, sval))\n')
65     f.write('\t\t\t\t\treturn FALSE;\n')
66     f.write('\t\t\t}\n')
67     f.write('\t\t\tbreak;\n')
68     f.write('\t\t\tcase 1: /* UINT16 */\n')
69     f.write('\t\t\t{\n')
70     f.write('\t\t\t\tUINT16 sval = freerdp_settings_get_uint16(src, cur->id);\n')
71     f.write('\t\t\t\tif (!freerdp_settings_set_uint16(dst, cur->id, sval))\n')
72     f.write('\t\t\t\t\treturn FALSE;\n')
73     f.write('\t\t\t}\n')
74     f.write('\t\t\tbreak;\n')
75     f.write('\t\t\tcase 2: /* INT16 */\n')
76     f.write('\t\t\t{\n')
77     f.write('\t\t\t\tINT16 sval = freerdp_settings_get_int16(src, cur->id);\n')
78     f.write('\t\t\t\tif (!freerdp_settings_set_int16(dst, cur->id, sval))\n')
79     f.write('\t\t\t\t\treturn FALSE;\n')
80     f.write('\t\t\t}\n')
81     f.write('\t\t\tbreak;\n')
82     f.write('\t\t\tcase 3: /* UINT32 */\n')
83     f.write('\t\t\t{\n')
84     f.write('\t\t\t\tUINT32 sval = freerdp_settings_get_uint32(src, cur->id);\n')
85     f.write('\t\t\t\tif (!freerdp_settings_set_uint32(dst, cur->id, sval))\n')
86     f.write('\t\t\t\t\treturn FALSE;\n')
87     f.write('\t\t\t}\n')
88     f.write('\t\t\tbreak;\n')
89     f.write('\t\t\tcase 4: /* INT32 */\n')
90     f.write('\t\t\t{\n')
91     f.write('\t\t\t\tINT32 sval = freerdp_settings_get_int32(src, cur->id);\n')
92     f.write('\t\t\t\tif (!freerdp_settings_set_int32(dst, cur->id, sval))\n')
93     f.write('\t\t\t\t\treturn FALSE;\n')
94     f.write('\t\t\t}\n')
95     f.write('\t\t\tbreak;\n')
96     f.write('\t\t\tcase 5: /* UINT64 */\n')
97     f.write('\t\t\t{\n')
98     f.write('\t\t\t\tUINT64 sval = freerdp_settings_get_uint64(src, cur->id);\n')
99     f.write('\t\t\t\tif (!freerdp_settings_set_uint64(dst, cur->id, sval))\n')
100     f.write('\t\t\t\t\treturn FALSE;\n')
101     f.write('\t\t\t}\n')
102     f.write('\t\t\tbreak;\n')
103     f.write('\t\t\tcase 6: /* INT64 */\n')
104     f.write('\t\t\t{\n')
105     f.write('\t\t\t\tINT64 sval = freerdp_settings_get_int64(src, cur->id);\n')
106     f.write('\t\t\t\tif (!freerdp_settings_set_int64(dst, cur->id, sval))\n')
107     f.write('\t\t\t\t\treturn FALSE;\n')
108     f.write('\t\t\t}\n')
109     f.write('\t\t\tbreak;\n')
110     f.write('\t\t\tcase 7: /* strings */\n')
111     f.write('\t\t\t{\n')
112     f.write('\t\t\t\tconst char* sval = freerdp_settings_get_string(src, cur->id);\n')
113     f.write('\t\t\t\tif (!freerdp_settings_set_string_(dst, cur->id, sval, FALSE))\n')
114     f.write('\t\t\t\t\treturn FALSE;\n')
115     f.write('\t\t\t}\n')
116     f.write('\t\t\tbreak;\n')
117     f.write('\t\t\tcase 8: /* pointer */\n')
118     f.write('\t\t\t{\n')
119     f.write('\t\t\t\tconst void* sval = freerdp_settings_get_pointer(src, cur->id);\n')
120     f.write('\t\t\t\tif (!freerdp_settings_set_pointer(dst, cur->id, sval))\n')
121     f.write('\t\t\t\t\treturn FALSE;\n')
122     f.write('\t\t\t}\n')
123     f.write('\t\t\tbreak;\n')
124
125     f.write('\t\t}\n')
126     f.write('\t}\n')
127     f.write('\treturn TRUE;\n')
128     f.write('}\n')
129     f.write('\n')
130     f.write('void freerdp_settings_free_keys(rdpSettings* dst, BOOL cleanup)\n')
131     f.write('{\n')
132     f.write('\tsize_t x;\n')
133     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
134     f.write('\t{\n')
135     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
136     f.write('\t\tswitch(cur->type)\n')
137     f.write('\t\t{\n')
138     f.write('\t\t\tcase 7: /* strings */\n')
139     f.write('\t\t\t\tfreerdp_settings_set_string_(dst, cur->id, NULL, cleanup);\n')
140     f.write('\t\t\tbreak;\n')
141     f.write('\t\t\tcase 8: /* pointer */\n')
142     f.write('\t\t\t\tfreerdp_settings_set_pointer(dst, cur->id, NULL);\n')
143     f.write('\t\t\tbreak;\n')
144     f.write('\t\t}\n')
145     f.write('\t}\n')
146     f.write('}\n')
147     f.write('\n')
148
149     f.write('SSIZE_T freerdp_settings_get_key_for_name(const char* value)\n')
150     f.write('{\n')
151     f.write('\tsize_t x;\n')
152     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
153     f.write('\t{\n')
154     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
155     f.write('\t\tif (strcmp(value, cur->str) == 0)\n')
156     f.write('\t\t\treturn cur->id;\n')
157     f.write('\t}\n')
158     f.write('\treturn -1;\n')
159     f.write('}\n')
160     f.write('\n')
161     f.write('SSIZE_T freerdp_settings_get_type_for_name(const char* value)\n')
162     f.write('{\n')
163     f.write('\tsize_t x;\n')
164     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
165     f.write('\t{\n')
166     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
167     f.write('\t\tif (strcmp(value, cur->str) == 0)\n')
168     f.write('\t\t\treturn cur->type;\n')
169     f.write('\t}\n')
170     f.write('\treturn -1;\n')
171     f.write('}\n')
172     f.write('\n')
173     f.write('SSIZE_T freerdp_settings_get_type_for_key(size_t key)\n')
174     f.write('{\n')
175     f.write('\tsize_t x;\n')
176     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
177     f.write('\t{\n')
178     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
179     f.write('\t\tif (cur->id == key)\n')
180     f.write('\t\t\treturn cur->type;\n')
181     f.write('\t}\n')
182     f.write('\treturn -1;\n')
183     f.write('}\n')
184     f.write('\n')
185     f.write('const char* freerdp_settings_get_name_for_key(size_t key)\n')
186     f.write('{\n')
187     f.write('\tsize_t x;\n')
188     f.write('\tfor(x=0; x<ARRAYSIZE(settings_map); x++)\n')
189     f.write('\t{\n')
190     f.write('\t\tconst struct settings_str_entry* cur = &settings_map[x];\n')
191     f.write('\t\tif (cur->id == key)\n')
192     f.write('\t\t\treturn cur->str;\n')
193     f.write('\t}\n')
194     f.write('\treturn NULL;\n')
195     f.write('}\n')
196     f.write('\n')
197
198 def write_getter_case(f, val):
199     f.write('\t\tcase FreeRDP_' + val + ':\n')
200     f.write('\t\t\treturn settings->' + val + ';\n\n')
201
202 def write_getter(f, entry_dict, entry_type, entry_name):
203     isString = 'string' in entry_name
204     isPointer = 'pointer' in entry_name
205     values = get_values(entry_dict, entry_type)
206
207     if isPointer:
208         f.write('const void*')
209     elif isString:
210         f.write('const ' + entry_type)
211     else:
212         f.write(entry_type)
213     f.write(' freerdp_settings_get_' + entry_name.lower() + '(const rdpSettings* settings, size_t id)\n')
214     f.write('{\n')
215     f.write('\tif (!settings)\n')
216     f.write('\t\treturn FALSE;\n\n')
217     f.write('\tswitch (id)\n')
218     f.write('\t{\n')
219     if values:
220         for val in values:
221             write_getter_case(f, val)
222     f.write('\t\tdefault:\n')
223     f.write('\t\t\tWLog_ERR(TAG, "[%s] Invalid key index %"PRIuz, __FUNCTION__,  id);\n')
224     f.write('\t\t\treturn FALSE;\n')
225     f.write('\t}\n')
226     f.write('}\n\n')
227
228 def write_setter_case(f, val, isString, isPointer):
229     f.write('\t\tcase FreeRDP_' + val + ':\n')
230     if isPointer:
231         f.write('\t\t\tsettings->' + val + ' = (void*)val;\n')
232         f.write('\t\t\tbreak;\n\n')
233     elif not isString:
234         f.write('\t\t\tsettings->' + val + ' = val;\n')
235         f.write('\t\t\tbreak;\n\n')
236     else:
237         f.write('\t\t\tif (cleanup)\n')
238         f.write('\t\t\t\tfree(settings->' + val + ');\n')
239         f.write('\t\t\tsettings->' + val + ' = (val ? _strdup(val) : NULL);\n')
240         f.write('\t\t\treturn (!val || settings->' + val + ' != NULL);\n\n')
241
242 def write_setter(f, entry_dict, entry_type, entry_name):
243     isString = 'string' in entry_name
244     isPointer = 'pointer' in entry_name
245     values = get_values(entry_dict, entry_type)
246
247     f.write('BOOL freerdp_settings_set_' + entry_name.lower())
248     if isString:
249         f.write('_')
250     f.write('(rdpSettings* settings, size_t id, ')
251     if isString or isPointer:
252         f.write('const ')
253     if not isPointer:
254         f.write(entry_type + ' val')
255     else:
256         f.write('void* val')
257     if isString:
258         f.write(', BOOL cleanup)\n')
259     else:
260         f.write(')\n')
261     f.write('{\n')
262     f.write('\tif (!settings)\n')
263     f.write('\t\treturn FALSE;\n\n')
264     f.write('\tswitch (id)\n')
265     f.write('\t{\n')
266     if values:
267         for val in values:
268             write_setter_case(f, val, isString, isPointer)
269     f.write('\t\tdefault:\n')
270     f.write('\t\t\tWLog_ERR(TAG, "[%s] Invalid key index %"PRIuz, __FUNCTION__,  id);\n')
271     f.write('\t\t\treturn FALSE;\n')
272     f.write('\t}\n')
273     f.write('\treturn TRUE;\n')
274     f.write('}\n\n')
275     f.write('\n')
276     if isString:
277         f.write('BOOL freerdp_settings_set_' + entry_name.lower() + '(rdpSettings* settings, size_t id, ')
278         if isString or isPointer:
279             f.write('const ')
280         if not isPointer:
281             f.write(entry_type + ' val')
282         else:
283             f.write('void* val')
284         f.write(')\n')
285         f.write('{\n')
286         f.write('\treturn freerdp_settings_set_' + entry_name.lower() + '_(settings, id, val, TRUE);\n')
287         f.write('}\n')
288         f.write('\n')
289
290 name = os.path.dirname(os.path.realpath(__file__))
291 begin = "WARNING: this data structure is carefully padded for ABI stability!"
292 end = "WARNING: End of ABI stable zone!"
293
294 print('begin parsing settings header')
295 try:
296     type_list = dict()
297
298     with open(name + "/../include/freerdp/settings.h", "r") as f:
299         lines = f.readlines()
300         started = False
301         for line in lines:
302             if not started:
303                 if begin in line:
304                     started = True
305                 continue
306
307             if end in line:
308                 break
309
310             sline = line.strip()
311             if not sline:
312                 continue
313             if sline.startswith('/'):
314                 continue
315             if sline.startswith('*'):
316                 continue
317             if 'padding' in sline:
318                 continue
319
320             if sline.startswith('ALIGN64'):
321                 sline = sline[7:].strip()
322
323             sline = sline[:sline.find(';')]
324             pair = sline.split()
325             if pair[0] in type_list:
326                 type_list[pair[0]].append(pair[1])
327             else:
328                 type_list[pair[0]] = [pair[1]]
329
330     with open(name + '/../libfreerdp/common/settings_getters.c', 'w+') as f:
331         f.write('/* Generated by ' + ''  + ' */\n\n')
332         f.write('#include <freerdp/settings.h>\n')
333         f.write('#include <freerdp/log.h>\n\n')
334         f.write('#define TAG FREERDP_TAG("common.settings")\n\n')
335
336         getter_list = dict(type_list)
337         setter_list = dict(type_list)
338         write_getter(f, getter_list, 'BOOL', 'bool')
339         write_setter(f, setter_list, 'BOOL', 'bool')
340         write_getter(f, getter_list, 'UINT16', 'uint16')
341         write_setter(f, setter_list, 'UINT16', 'uint16')
342         write_getter(f, getter_list, 'INT16', 'int16')
343         write_setter(f, setter_list, 'INT16', 'int16')
344         write_getter(f, getter_list, 'UINT32', 'uint32')
345         write_setter(f, setter_list, 'UINT32', 'uint32')
346         write_getter(f, getter_list, 'INT32', 'int32')
347         write_setter(f, setter_list, 'INT32', 'int32')
348         write_getter(f, getter_list, 'UINT64', 'uint64')
349         write_setter(f, setter_list, 'UINT64', 'uint64')
350         write_getter(f, getter_list, 'INT64', 'int64')
351         write_setter(f, setter_list, 'INT64', 'int64')
352         write_getter(f, getter_list, 'char*', 'string')
353         write_setter(f, setter_list, 'char*', 'string')
354         write_getter(f, getter_list, '*', 'pointer')
355         write_setter(f, setter_list, '*', 'pointer')
356
357         f.write('\n')
358
359     with open(name + '/../libfreerdp/common/settings_str.c', 'w+') as f:
360         f.write('/* Generated by ' + ''  + ' */\n\n')
361         f.write('#include <freerdp/settings.h>\n')
362         f.write('#include <freerdp/log.h>\n\n')
363         f.write('#include "../core/settings.h"\n\n')
364         f.write('#define TAG FREERDP_TAG("common.settings")\n\n')
365
366         getter_list = dict(type_list)
367         write_str(f, getter_list)
368         f.write('\n')
369
370
371     with open(name + '/../libfreerdp/core/test/settings_property_lists.h', 'w+') as f:
372         f.write('#ifndef TEST_SETTINGS_PROPERTY_LISTS\n')
373         f.write('#define TEST_SETTINGS_PROPERTY_LISTS\n\n')
374
375         write_entry(f, type_list, 'BOOL', 'bool')
376         write_entry(f, type_list, 'UINT16', 'uint16')
377         write_entry(f, type_list, 'INT16', 'int16')
378         write_entry(f, type_list, 'UINT32', 'uint32')
379         write_entry(f, type_list, 'INT32', 'int32')
380         write_entry(f, type_list, 'UINT64', 'uint64')
381         write_entry(f, type_list, 'INT64', 'int64')
382         write_entry(f, type_list, 'char*', 'string')
383         write_entry(f, type_list, '*', 'pointer')
384
385         f.write('#endif /* TEST_SETTINGS_PROPERTY_LISTS */\n\n')
386
387         print('remaining:\n' + str(type_list))
388 except IOError as e:
389     print('failed to parse settings header ' + str(e))
390     sys.exit(-1)
391 print('ended parsing settings header')