project_files/frontlib/model/schemelist.c
changeset 10017 de822cd3df3a
parent 7497 7e1d72fc03c7
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    28 #include <stdlib.h>
    28 #include <stdlib.h>
    29 #include <limits.h>
    29 #include <limits.h>
    30 #include <string.h>
    30 #include <string.h>
    31 
    31 
    32 static char *makePrefixedName(int schemeIndex, const char *settingName) {
    32 static char *makePrefixedName(int schemeIndex, const char *settingName) {
    33 	return flib_asprintf("%i\\%s", schemeIndex, settingName);
    33     return flib_asprintf("%i\\%s", schemeIndex, settingName);
    34 }
    34 }
    35 
    35 
    36 static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
    36 static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
    37 	bool error = false;
    37     bool error = false;
    38 	for(int i=0; i<flib_meta.settingCount && !error; i++) {
    38     for(int i=0; i<flib_meta.settingCount && !error; i++) {
    39 		char *key = makePrefixedName(index, flib_meta.settings[i].name);
    39         char *key = makePrefixedName(index, flib_meta.settings[i].name);
    40 		if(!key) {
    40         if(!key) {
    41 			error = true;
    41             error = true;
    42 		} else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) {
    42         } else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) {
    43 			flib_log_e("Error reading setting %s in schemes file.", key);
    43             flib_log_e("Error reading setting %s in schemes file.", key);
    44 			error = true;
    44             error = true;
    45 		}
    45         }
    46 		free(key);
    46         free(key);
    47 	}
    47     }
    48 	return error;
    48     return error;
    49 }
    49 }
    50 
    50 
    51 static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
    51 static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
    52 	bool error = false;
    52     bool error = false;
    53 	for(int i=0; i<flib_meta.modCount && !error; i++) {
    53     for(int i=0; i<flib_meta.modCount && !error; i++) {
    54 		char *key = makePrefixedName(index, flib_meta.mods[i].name);
    54         char *key = makePrefixedName(index, flib_meta.mods[i].name);
    55 		if(!key) {
    55         if(!key) {
    56 			error = true;
    56             error = true;
    57 		} else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) {
    57         } else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) {
    58 			flib_log_e("Error reading mod %s in schemes file.", key);
    58             flib_log_e("Error reading mod %s in schemes file.", key);
    59 			error = true;
    59             error = true;
    60 		}
    60         }
    61 		free(key);
    61         free(key);
    62 	}
    62     }
    63 	return error;
    63     return error;
    64 }
    64 }
    65 
    65 
    66 static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) {
    66 static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) {
    67 	flib_scheme *result = NULL;
    67     flib_scheme *result = NULL;
    68 	char *schemeNameKey = makePrefixedName(index+1, "name");
    68     char *schemeNameKey = makePrefixedName(index+1, "name");
    69 	if(schemeNameKey) {
    69     if(schemeNameKey) {
    70 		char *schemeName = NULL;
    70         char *schemeName = NULL;
    71 		if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) {
    71         if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) {
    72 			flib_scheme *tmpScheme = flib_scheme_create(schemeName);
    72             flib_scheme *tmpScheme = flib_scheme_create(schemeName);
    73 			if(tmpScheme) {
    73             if(tmpScheme) {
    74 				if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) {
    74                 if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) {
    75 					result = tmpScheme;
    75                     result = tmpScheme;
    76 					tmpScheme = NULL;
    76                     tmpScheme = NULL;
    77 				}
    77                 }
    78 			}
    78             }
    79 			flib_scheme_destroy(tmpScheme);
    79             flib_scheme_destroy(tmpScheme);
    80 		}
    80         }
    81 		free(schemeName);
    81         free(schemeName);
    82 	}
    82     }
    83 	free(schemeNameKey);
    83     free(schemeNameKey);
    84 	return result;
    84     return result;
    85 }
    85 }
    86 
    86 
    87 static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) {
    87 static flib_schemelist *fromIniHandleError(flib_schemelist *result, flib_ini *ini) {
    88 	flib_ini_destroy(ini);
    88     flib_ini_destroy(ini);
    89 	flib_schemelist_destroy(result);
    89     flib_schemelist_destroy(result);
    90 	return NULL;
    90     return NULL;
    91 }
    91 }
    92 
    92 
    93 flib_schemelist *flib_schemelist_from_ini(const char *filename) {
    93 flib_schemelist *flib_schemelist_from_ini(const char *filename) {
    94 	if(log_badargs_if(filename==NULL)) {
    94     if(log_badargs_if(filename==NULL)) {
    95 		return NULL;
    95         return NULL;
    96 	}
    96     }
    97 
    97 
    98 	flib_schemelist *list = NULL;
    98     flib_schemelist *list = NULL;
    99 	flib_ini *ini = flib_ini_load(filename);
    99     flib_ini *ini = flib_ini_load(filename);
   100 	if(!ini || flib_ini_enter_section(ini, "schemes")) {
   100     if(!ini || flib_ini_enter_section(ini, "schemes")) {
   101 		flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename);
   101         flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename);
   102 		return fromIniHandleError(list, ini);
   102         return fromIniHandleError(list, ini);
   103 	}
   103     }
   104 
   104 
   105 	list = flib_schemelist_create();
   105     list = flib_schemelist_create();
   106 	if(!list) {
   106     if(!list) {
   107 		return fromIniHandleError(list, ini);
   107         return fromIniHandleError(list, ini);
   108 	}
   108     }
   109 
   109 
   110 	int schemeCount = 0;
   110     int schemeCount = 0;
   111 	if(flib_ini_get_int(ini, &schemeCount, "size")) {
   111     if(flib_ini_get_int(ini, &schemeCount, "size")) {
   112 		flib_log_e("Missing or malformed scheme count in config file %s.", filename);
   112         flib_log_e("Missing or malformed scheme count in config file %s.", filename);
   113 		return fromIniHandleError(list, ini);
   113         return fromIniHandleError(list, ini);
   114 	}
   114     }
   115 
   115 
   116 	for(int i=0; i<schemeCount; i++) {
   116     for(int i=0; i<schemeCount; i++) {
   117 		flib_scheme *scheme = readSchemeFromIni(ini, i);
   117         flib_scheme *scheme = readSchemeFromIni(ini, i);
   118 		if(!scheme || flib_schemelist_insert(list, scheme, i)) {
   118         if(!scheme || flib_schemelist_insert(list, scheme, i)) {
   119 			flib_scheme_destroy(scheme);
   119             flib_scheme_destroy(scheme);
   120 			flib_log_e("Error reading scheme %i from config file %s.", i, filename);
   120             flib_log_e("Error reading scheme %i from config file %s.", i, filename);
   121 			return fromIniHandleError(list, ini);
   121             return fromIniHandleError(list, ini);
   122 		}
   122         }
   123 	}
   123     }
   124 
   124 
   125 
   125 
   126 	flib_ini_destroy(ini);
   126     flib_ini_destroy(ini);
   127 	return list;
   127     return list;
   128 }
   128 }
   129 
   129 
   130 static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) {
   130 static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) {
   131 	bool error = false;
   131     bool error = false;
   132 
   132 
   133 	char *key = makePrefixedName(index+1, "name");
   133     char *key = makePrefixedName(index+1, "name");
   134 	error |= !key || flib_ini_set_str(ini, key, scheme->name);
   134     error |= !key || flib_ini_set_str(ini, key, scheme->name);
   135 	free(key);
   135     free(key);
   136 
   136 
   137 	for(int i=0; i<flib_meta.modCount && !error; i++) {
   137     for(int i=0; i<flib_meta.modCount && !error; i++) {
   138 		char *key = makePrefixedName(index+1, flib_meta.mods[i].name);
   138         char *key = makePrefixedName(index+1, flib_meta.mods[i].name);
   139 		error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]);
   139         error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]);
   140 		free(key);
   140         free(key);
   141 	}
   141     }
   142 
   142 
   143 	for(int i=0; i<flib_meta.settingCount && !error; i++) {
   143     for(int i=0; i<flib_meta.settingCount && !error; i++) {
   144 		char *key = makePrefixedName(index+1, flib_meta.settings[i].name);
   144         char *key = makePrefixedName(index+1, flib_meta.settings[i].name);
   145 		error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]);
   145         error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]);
   146 		free(key);
   146         free(key);
   147 	}
   147     }
   148 	return error;
   148     return error;
   149 }
   149 }
   150 
   150 
   151 int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) {
   151 int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) {
   152 	int result = -1;
   152     int result = -1;
   153 	if(!log_badargs_if2(filename==NULL, schemes==NULL)) {
   153     if(!log_badargs_if2(filename==NULL, schemes==NULL)) {
   154 		flib_ini *ini = flib_ini_create(NULL);
   154         flib_ini *ini = flib_ini_create(NULL);
   155 		if(ini && !flib_ini_create_section(ini, "schemes")) {
   155         if(ini && !flib_ini_create_section(ini, "schemes")) {
   156 			bool error = false;
   156             bool error = false;
   157 			error |= flib_ini_set_int(ini, "size", schemes->schemeCount);
   157             error |= flib_ini_set_int(ini, "size", schemes->schemeCount);
   158 			for(int i=0; i<schemes->schemeCount && !error; i++) {
   158             for(int i=0; i<schemes->schemeCount && !error; i++) {
   159 				error |= writeSchemeToIni(schemes->schemes[i], ini, i);
   159                 error |= writeSchemeToIni(schemes->schemes[i], ini, i);
   160 			}
   160             }
   161 
   161 
   162 			if(!error) {
   162             if(!error) {
   163 				result = flib_ini_save(ini, filename);
   163                 result = flib_ini_save(ini, filename);
   164 			}
   164             }
   165 		}
   165         }
   166 		flib_ini_destroy(ini);
   166         flib_ini_destroy(ini);
   167 	}
   167     }
   168 	return result;
   168     return result;
   169 }
   169 }
   170 
   170 
   171 flib_schemelist *flib_schemelist_create() {
   171 flib_schemelist *flib_schemelist_create() {
   172 	return flib_calloc(1, sizeof(flib_schemelist));
   172     return flib_calloc(1, sizeof(flib_schemelist));
   173 }
   173 }
   174 
   174 
   175 void flib_schemelist_destroy(flib_schemelist *list) {
   175 void flib_schemelist_destroy(flib_schemelist *list) {
   176 	if(list) {
   176     if(list) {
   177 		for(int i=0; i<list->schemeCount; i++) {
   177         for(int i=0; i<list->schemeCount; i++) {
   178 			flib_scheme_destroy(list->schemes[i]);
   178             flib_scheme_destroy(list->schemes[i]);
   179 		}
   179         }
   180 		free(list->schemes);
   180         free(list->schemes);
   181 		free(list);
   181         free(list);
   182 	}
   182     }
   183 }
   183 }
   184 
   184 
   185 flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) {
   185 flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name) {
   186 	if(!log_badargs_if2(list==NULL, name==NULL)) {
   186     if(!log_badargs_if2(list==NULL, name==NULL)) {
   187 		for(int i=0; i<list->schemeCount; i++) {
   187         for(int i=0; i<list->schemeCount; i++) {
   188 			if(!strcmp(name, list->schemes[i]->name)) {
   188             if(!strcmp(name, list->schemes[i]->name)) {
   189 				return list->schemes[i];
   189                 return list->schemes[i];
   190 			}
   190             }
   191 		}
   191         }
   192 	}
   192     }
   193 	return NULL;
   193     return NULL;
   194 }
   194 }
   195 
   195 
   196 GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*)
   196 GENERATE_STATIC_LIST_INSERT(insertScheme, flib_scheme*)
   197 GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*)
   197 GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_scheme*)
   198 
   198 
   199 int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) {
   199 int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) {
   200 	if(!log_badargs_if2(list==NULL, cfg==NULL)
   200     if(!log_badargs_if2(list==NULL, cfg==NULL)
   201 			&& !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) {
   201             && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) {
   202 		return 0;
   202         return 0;
   203 	}
   203     }
   204 	return -1;
   204     return -1;
   205 }
   205 }
   206 
   206 
   207 int flib_schemelist_delete(flib_schemelist *list, int pos) {
   207 int flib_schemelist_delete(flib_schemelist *list, int pos) {
   208 	if(!log_badargs_if(list==NULL)) {
   208     if(!log_badargs_if(list==NULL)) {
   209 		flib_scheme *elem = list->schemes[pos];
   209         flib_scheme *elem = list->schemes[pos];
   210 		if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) {
   210         if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) {
   211 			flib_scheme_destroy(elem);
   211             flib_scheme_destroy(elem);
   212 			return 0;
   212             return 0;
   213 		}
   213         }
   214 	}
   214     }
   215 	return -1;
   215     return -1;
   216 }
   216 }