summaryrefslogtreecommitdiffstats
path: root/tools/update-settings-tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xtools/update-settings-tests349
1 files changed, 349 insertions, 0 deletions
diff --git a/tools/update-settings-tests b/tools/update-settings-tests
new file mode 100755
index 0000000..bd8e439
--- /dev/null
+++ b/tools/update-settings-tests
@@ -0,0 +1,349 @@
+#!/usr/bin/env python3
+import os
+import sys
+
+def get_values(entry_dict, entry_type):
+ values = []
+ if '*' == entry_type:
+ for key in list(entry_dict.keys()):
+ if entry_type in key:
+ values += entry_dict[key]
+ entry_dict.pop(key, None)
+ elif entry_type in dict(entry_dict):
+ values = entry_dict[entry_type]
+ entry_dict.pop(entry_type, None)
+ if values:
+ return sorted(values)
+ return values
+
+def write_entry(f, entry_dict, entry_type, entry_name):
+ values = get_values(entry_dict, entry_type)
+ if not values:
+ return
+
+ f.write('#define have_' + entry_name.lower() + '_list_indices\n')
+ f.write('static const size_t ' + entry_name.lower() + '_list_indices[] =\n')
+ f.write('{\n')
+
+ for val in values:
+ f.write('\tFreeRDP_' + val + ',\n')
+
+ f.write('};\n\n')
+
+def write_str_case(f, entry_idx, val):
+ entry_types = ['BOOL', 'UINT16', 'INT16', 'UINT32', 'INT32', 'UINT64', 'INT64', 'STRING', 'POINTER']
+ f.write('\t\t{FreeRDP_' + val + ', FREERDP_SETTINGS_TYPE_' + str(entry_types[entry_idx]) + ', "FreeRDP_' + val + '"},\n')
+
+def write_str(f, entry_dict):
+ f.write('typedef enum {\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_BOOL,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_UINT16,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_INT16,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_UINT32,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_INT32,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_UINT64,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_INT64,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_STRING,\n')
+ f.write('\tFREERDP_SETTINGS_TYPE_POINTER\n')
+ f.write('} FREERDP_SETTINGS_TYPE;\n')
+ f.write('\n')
+ f.write('struct settings_str_entry {\n')
+ f.write('\tSSIZE_T id;\n')
+ f.write('\tSSIZE_T type;\n')
+ f.write('\tconst char* str;\n')
+ f.write('};\n')
+ f.write('static const struct settings_str_entry settings_map[] =\n')
+ f.write('{\n')
+
+ entry_types = ['BOOL', 'UINT16', 'INT16', 'UINT32', 'INT32', 'UINT64', 'INT64', 'char*', '*']
+ for entry_type in entry_types:
+ values = get_values(entry_dict, entry_type)
+ if values:
+ for val in values:
+ write_str_case(f, entry_types.index(entry_type), val)
+ f.write('};\n\n')
+ f.write('\n')
+
+def write_getter_case(f, val):
+ f.write('\t\tcase FreeRDP_' + val + ':\n')
+ f.write('\t\t\treturn settings->' + val + ';\n\n')
+
+def write_getter_body(f, values, ret):
+ f.write('{\n')
+ f.write('\tWINPR_ASSERT(settings);\n\n')
+ f.write('\tswitch (id)\n')
+ f.write('\t{\n')
+ if values:
+ for val in values:
+ write_getter_case(f, val)
+ f.write('\t\tdefault:\n')
+ f.write('\t\t\tWLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, freerdp_settings_get_name_for_key(id), freerdp_settings_get_type_name_for_key(id));\n')
+ f.write('\t\t\tWINPR_ASSERT(FALSE);\n')
+ f.write('\t\t\treturn ' + ret + ';\n')
+ f.write('\t}\n')
+ f.write('}\n\n')
+
+def write_getter(f, entry_dict, entry_type, entry_name, postfix):
+ isString = 'string' in entry_name
+ isPointer = 'pointer' in entry_name
+ values = get_values(entry_dict, entry_type)
+
+ typestr = 'FreeRDP_Settings_Keys_' + entry_name.capitalize()
+ typestr = typestr.replace('_Uint', '_UInt')
+
+ if isPointer:
+ f.write('void*')
+ elif isString:
+ f.write('const ' + entry_type)
+ else:
+ f.write(entry_type)
+
+ if isPointer:
+ f.write(' freerdp_settings_get_pointer_writable(rdpSettings* settings, ' + typestr + ' id)\n')
+ else:
+ f.write(' freerdp_settings_get_' + entry_name.lower() + '(const rdpSettings* settings, ' + typestr + ' id)\n')
+ if isString or isPointer:
+ ret = 'NULL';
+ elif 'bool' in entry_name:
+ ret = 'FALSE';
+ else:
+ ret = '0';
+
+ write_getter_body(f, values, ret)
+
+ if isString:
+ f.write('char* freerdp_settings_get_' + entry_name.lower() + '_writable(rdpSettings* settings, ' + typestr + ' id)\n')
+ write_getter_body(f, values, ret)
+
+def write_setter_case(f, val, postfix, isPointer):
+ f.write('\t\tcase FreeRDP_' + val + ':\n')
+ if isPointer:
+ f.write('\t\t\tsettings->' + val + ' = cnv.v;\n')
+ f.write('\t\t\tbreak;\n\n')
+ elif not postfix:
+ f.write('\t\t\tsettings->' + val + ' = cnv.c;\n')
+ f.write('\t\t\tbreak;\n\n')
+ elif len(postfix) <= 1:
+ f.write('\t\t\treturn update_string' + postfix + '(&settings->' + val + ', cnv.c, len);\n\n')
+ else:
+ f.write('\t\t\treturn update_string' + postfix + '(&settings->' + val + ', cnv.cc, len, cleanup);\n\n')
+
+def write_setter(f, entry_dict, entry_type, entry_name, postfix):
+ isString = 'string' in entry_name
+ isPointer = 'pointer' in entry_name
+ values = get_values(entry_dict, entry_type)
+
+ typestr = 'FreeRDP_Settings_Keys_' + entry_name.capitalize()
+ typestr = typestr.replace('_Uint', '_UInt')
+ f.write('BOOL freerdp_settings_set_' + entry_name.lower())
+ f.write(postfix)
+ f.write('(rdpSettings* settings, ' + typestr + ' id, ')
+ if isString and len(postfix) > 1 or isPointer:
+ f.write('const ')
+ if not isPointer:
+ f.write(entry_type + ' val')
+ else:
+ f.write('void* val')
+ if isString and len(postfix) <= 1:
+ f.write(', size_t len)\n')
+ elif isString:
+ f.write(', size_t len, BOOL cleanup)\n')
+ else:
+ f.write(')\n')
+ f.write('{\n')
+ f.write('\tunion\n')
+ f.write('\t{\n')
+ f.write('\t\tvoid* v;\n')
+ f.write('\t\tconst void* cv;\n')
+ if not isPointer:
+ f.write(' ' + entry_type + ' c;\n')
+ f.write(' const ' + entry_type + ' cc;\n')
+ f.write('} cnv;\n')
+
+ f.write('\tWINPR_ASSERT(settings);\n\n')
+ if isPointer:
+ f.write('\tcnv.cv = val;\n\n')
+ elif isString:
+ f.write('\tcnv.cc = val;\n\n')
+ else:
+ f.write('\tcnv.c = val;\n\n')
+ f.write('\tswitch (id)\n')
+ f.write('\t{\n')
+ if values:
+ for val in values:
+ write_setter_case(f, val, postfix, isPointer)
+ f.write('\t\tdefault:\n')
+ f.write('\t\t\tWLog_ERR(TAG, "Invalid key index %" PRIuz " [%s|%s]", id, freerdp_settings_get_name_for_key(id), freerdp_settings_get_type_name_for_key(id));\n')
+ f.write('\t\t\treturn FALSE;\n')
+ f.write('\t}\n')
+ f.write('\treturn TRUE;\n')
+ f.write('}\n\n')
+ f.write('\n')
+ if isString and len(postfix) <= 1:
+ f.write('BOOL freerdp_settings_set_string_len(rdpSettings* settings, FreeRDP_Settings_Keys_String id, const char* val, size_t len)\n')
+ f.write('{\n')
+ f.write('\treturn freerdp_settings_set_string_copy_(settings, id, val, len, TRUE);\n')
+ f.write('}\n')
+ f.write('\n')
+
+ f.write('BOOL freerdp_settings_set_string(rdpSettings* settings, FreeRDP_Settings_Keys_String id, const char* val)\n')
+ f.write('{\n')
+ f.write('\tsize_t len = 0;\n')
+ f.write('\tif (val) len = strlen(val);\n')
+ f.write('\treturn freerdp_settings_set_string_copy_(settings, id, val, len, TRUE);\n')
+ f.write('}\n')
+ f.write('\n')
+
+name = os.path.dirname(os.path.realpath(__file__))
+begin = "WARNING: this data structure is carefully padded for ABI stability!"
+end = "WARNING: End of ABI stable zone!"
+
+print('begin parsing settings header')
+try:
+ type_list = dict()
+
+ with open(name + "/../include/freerdp/settings_types_private.h", "r") as f:
+ lines = f.readlines()
+ started = False
+ for line in lines:
+ if not started:
+ if begin in line:
+ started = True
+ continue
+
+ if end in line:
+ break
+
+ sline = line.strip()
+ if not sline:
+ continue
+ if sline.startswith('/'):
+ continue
+ if sline.startswith('*'):
+ continue
+ if 'padding' in sline:
+ continue
+
+ if sline.startswith('SETTINGS_DEPRECATED(ALIGN64'):
+ sline = sline[27:].strip()
+
+ sline = sline[:sline.find(');')]
+ pair = sline.split()
+ if pair[0] in type_list:
+ type_list[pair[0]].append(pair[1])
+ else:
+ type_list[pair[0]] = [pair[1]]
+
+ with open(name + '/../libfreerdp/common/settings_getters.c', 'w+') as f:
+ f.write('/* Generated by ' + '' + ' */\n\n')
+ f.write('#include "../core/settings.h"\n\n')
+ f.write('#include <winpr/assert.h>\n')
+ f.write('#include <freerdp/settings.h>\n')
+ f.write('#include <freerdp/log.h>\n\n')
+ f.write('#define TAG FREERDP_TAG("common.settings")\n\n')
+
+ f.write('static void free_string(char** current, BOOL cleanup)\n')
+ f.write('{\n')
+ f.write('\tif (cleanup)\n')
+ f.write('\t{\n')
+ f.write('\t\tif (*current)\n')
+ f.write('\t\t\tmemset(*current, 0, strlen(*current));\n')
+ f.write('\t\tfree(*current);\n')
+ f.write('\t\t(*current) = NULL;\n')
+ f.write('\t}\n')
+ f.write('}\n\n')
+
+ f.write('static BOOL alloc_empty_string(char** current, const char* next, size_t next_len)\n')
+ f.write('{\n')
+ f.write('\tif (!next && (next_len > 0))\n')
+ f.write('\t{\n')
+ f.write('\t\t*current = calloc(next_len, 1);\n')
+ f.write('\t\treturn (*current != NULL);\n')
+ f.write('\t}\n')
+ f.write('\treturn FALSE;\n')
+ f.write('}\n\n')
+
+
+ f.write('static BOOL update_string_copy_(char** current, const char* next, size_t next_len, BOOL cleanup)\n')
+ f.write('{\n')
+ f.write('\tfree_string(current, cleanup);\n')
+ f.write('\n')
+ f.write('\tif (alloc_empty_string(current, next, next_len))\n')
+ f.write('\t\treturn TRUE;\n')
+ f.write('\n')
+ f.write('\t*current = (next ? strndup(next, next_len) : NULL);\n')
+ f.write('\treturn !next || (*current != NULL);\n')
+ f.write('}\n\n')
+
+ f.write('static BOOL update_string_(char** current, char* next, size_t next_len)\n')
+ f.write('{\n')
+ f.write('\tfree_string(current, TRUE);\n')
+ f.write('\n')
+ f.write('\tif (alloc_empty_string(current, next, next_len))\n')
+ f.write('\t\treturn TRUE;\n')
+ f.write('\n')
+ f.write('\t*current = next;\n')
+ f.write('\treturn !next || (*current != NULL);\n')
+ f.write('}\n\n')
+
+ getter_list = dict(type_list)
+ setter_list = dict(type_list)
+ setter_list2 = dict(type_list)
+ write_getter(f, getter_list, 'BOOL', 'bool', '')
+ write_setter(f, setter_list, 'BOOL', 'bool', '')
+ write_getter(f, getter_list, 'UINT16', 'uint16', '')
+ write_setter(f, setter_list, 'UINT16', 'uint16', '')
+ write_getter(f, getter_list, 'INT16', 'int16', '')
+ write_setter(f, setter_list, 'INT16', 'int16', '')
+ write_getter(f, getter_list, 'UINT32', 'uint32', '')
+ write_setter(f, setter_list, 'UINT32', 'uint32', '')
+ write_getter(f, getter_list, 'INT32', 'int32', '')
+ write_setter(f, setter_list, 'INT32', 'int32', '')
+ write_getter(f, getter_list, 'UINT64', 'uint64', '')
+ write_setter(f, setter_list, 'UINT64', 'uint64', '')
+ write_getter(f, getter_list, 'INT64', 'int64', '')
+ write_setter(f, setter_list, 'INT64', 'int64', '')
+ write_getter(f, getter_list, 'char*', 'string', '_')
+ write_setter(f, setter_list, 'char*', 'string', '_')
+ write_setter(f, setter_list2, 'char*', 'string', '_copy_')
+ write_getter(f, getter_list, '*', 'pointer', '')
+ write_setter(f, setter_list, '*', 'pointer', '')
+
+ f.write('\n')
+
+ with open(name + '/../libfreerdp/common/settings_str.h', 'w+') as f:
+ f.write('/* Generated by ' + '' + ' */\n\n')
+ f.write('#ifndef FREERDP_CORE_SETTINGS_STR_H\n')
+ f.write('#define FREERDP_CORE_SETTINGS_STR_H\n\n')
+ f.write('#include "../core/settings.h"\n\n')
+ f.write('#include <freerdp/settings.h>\n')
+ f.write('#include <freerdp/log.h>\n\n')
+ f.write('#define TAG FREERDP_TAG("common.settings")\n\n')
+
+ getter_list = dict(type_list)
+ write_str(f, getter_list)
+ f.write('#endif\n')
+ f.write('\n')
+
+
+ with open(name + '/../libfreerdp/core/test/settings_property_lists.h', 'w+') as f:
+ f.write('#ifndef TEST_SETTINGS_PROPERTY_LISTS\n')
+ f.write('#define TEST_SETTINGS_PROPERTY_LISTS\n\n')
+
+ write_entry(f, type_list, 'BOOL', 'bool')
+ write_entry(f, type_list, 'UINT16', 'uint16')
+ write_entry(f, type_list, 'INT16', 'int16')
+ write_entry(f, type_list, 'UINT32', 'uint32')
+ write_entry(f, type_list, 'INT32', 'int32')
+ write_entry(f, type_list, 'UINT64', 'uint64')
+ write_entry(f, type_list, 'INT64', 'int64')
+ write_entry(f, type_list, 'char*', 'string')
+ write_entry(f, type_list, '*', 'pointer')
+
+ f.write('#endif /* TEST_SETTINGS_PROPERTY_LISTS */\n\n')
+
+ print('remaining:\n' + str(type_list))
+except IOError as e:
+ print('failed to parse settings header ' + str(e))
+ sys.exit(-1)
+print('ended parsing settings header')