#!/usr/bin/env python 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) 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_getter_case(f, val): f.write('\t\tcase FreeRDP_' + val + ':\n') f.write('\t\t\treturn settings->' + val + ';\n\n') def write_getter(f, entry_dict, entry_type, entry_name): isString = 'string' in entry_name isPointer = 'pointer' in entry_name values = get_values(entry_dict, entry_type) if isPointer: f.write('const void*') elif isString: f.write('const ' + entry_type) else: f.write(entry_type) f.write(' freerdp_settings_get_' + entry_name.lower() + '(const rdpSettings* settings, size_t id)\n') f.write('{\n') f.write('\tif (!settings)\n') f.write('\t\treturn FALSE;\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, "[%s] Invalid key index %"PRIuz, __FUNCTION__, id);\n') f.write('\t\t\treturn FALSE;\n') f.write('\t}\n') f.write('}\n\n') def write_setter_case(f, val, isString, isPointer): f.write('\t\tcase FreeRDP_' + val + ':\n') if not isString: f.write('\t\t\tsettings->' + val + ' = val;\n') f.write('\t\t\tbreak;\n\n') else: f.write('\t\t\tfree(settings->' + val + ');\n') f.write('\t\t\tsettings->' + val + ' = (val ? _strdup(val) : NULL);\n') f.write('\t\t\treturn (!val || settings->' + val + ' != NULL);\n\n') def write_setter(f, entry_dict, entry_type, entry_name): isString = 'string' in entry_name isPointer = 'pointer' in entry_name values = get_values(entry_dict, entry_type) f.write('BOOL freerdp_settings_set_' + entry_name.lower() + '(rdpSettings* settings, size_t id, ') if isString or isPointer: f.write('const ') if not isPointer: f.write(entry_type + ' val)\n') else: f.write('void* val)\n') f.write('{\n') f.write('\tif (!settings)\n') f.write('\t\treturn FALSE;\n\n') f.write('\tswitch (id)\n') f.write('\t{\n') if values: for val in values: write_setter_case(f, val, isString, isPointer) f.write('\t\tdefault:\n') f.write('\t\t\tWLog_ERR(TAG, "[%s] Invalid key index %"PRIuz, __FUNCTION__, id);\n') f.write('\t\t\treturn FALSE;\n') f.write('\t}\n') f.write('\treturn TRUE;\n') f.write('}\n\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.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('ALIGN64'): sline = sline[7:].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 \n') f.write('#include \n\n') f.write('#define TAG FREERDP_TAG("common.settings")\n\n') getter_list = dict(type_list) setter_list = 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_getter(f, getter_list, '*', 'pointer') # write_setter(f, setter_list, '*', 'pointer') 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')