settings.c
changeset 3628 bd4a6601e5a2
parent 3615 59b36aaa050a
child 3631 33532b85cce9
equal deleted inserted replaced
3627:14c1566323fd 3628:bd4a6601e5a2
    32 #include "settings.h"
    32 #include "settings.h"
    33 #include "command.h"
    33 #include "command.h"
    34 #include "console.h"
    34 #include "console.h"
    35 #include "saveload.h"
    35 #include "saveload.h"
    36 #include "npf.h"
    36 #include "npf.h"
       
    37 #include "newgrf.h"
    37 
    38 
    38 /** The patch values that are used for new games and/or modified in config file */
    39 /** The patch values that are used for new games and/or modified in config file */
    39 Patches _patches_newgame;
    40 Patches _patches_newgame;
    40 
    41 
    41 typedef struct IniFile IniFile;
    42 typedef struct IniFile IniFile;
    42 typedef struct IniItem IniItem;
    43 typedef struct IniItem IniItem;
    43 typedef struct IniGroup IniGroup;
    44 typedef struct IniGroup IniGroup;
    44 typedef struct SettingsMemoryPool SettingsMemoryPool;
    45 typedef struct SettingsMemoryPool SettingsMemoryPool;
       
    46 
       
    47 typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
       
    48 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
       
    49 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
    45 
    50 
    46 static void pool_init(SettingsMemoryPool **pool);
    51 static void pool_init(SettingsMemoryPool **pool);
    47 static void *pool_alloc(SettingsMemoryPool **pool, uint size);
    52 static void *pool_alloc(SettingsMemoryPool **pool, uint size);
    48 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size);
    53 static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size);
    49 static void pool_free(SettingsMemoryPool **pool);
    54 static void pool_free(SettingsMemoryPool **pool);
   815  * @param IniFile handle to the ini file with the source data
   820  * @param IniFile handle to the ini file with the source data
   816  * @param grpname character string identifying the section-header of the ini
   821  * @param grpname character string identifying the section-header of the ini
   817  * file that will be parsed
   822  * file that will be parsed
   818  * @param list pointer to an string(pointer) array that will store the parsed
   823  * @param list pointer to an string(pointer) array that will store the parsed
   819  * entries of the given section
   824  * entries of the given section
   820  * @param len the maximum number of items available for the above list */
   825  * @param len the maximum number of items available for the above list
   821 static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len)
   826  * @param proc callback function that can override how the values are stored
       
   827  * inside the list */
       
   828 static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
   822 {
   829 {
   823 	IniGroup *group = ini_getgroup(ini, grpname, -1);
   830 	IniGroup *group = ini_getgroup(ini, grpname, -1);
   824 	IniItem *item;
   831 	IniItem *item;
   825 	uint i;
   832 	const char *entry;
       
   833 	uint i, j;
   826 
   834 
   827 	if (group == NULL) return;
   835 	if (group == NULL) return;
   828 
   836 
   829 	item = group->item;
   837 	for (i = j = 0, item = group->item; item != NULL; item = item->next) {
   830 	for (i = 0; i != len; i++) {
   838 		entry = (proc != NULL) ? proc(item, i++) : item->name;
   831 		if (item == NULL) break;
   839 
   832 		list[i] = strdup(item->name);
   840 		if (entry == NULL || list == NULL) continue;
   833 		item = item->next;
   841 
       
   842 		if (j == len) break;
       
   843 		list[j++] = strdup(entry);
   834 	}
   844 	}
   835 }
   845 }
   836 
   846 
   837 /** Saves all items from a list into the 'grpname' section
   847 /** Saves all items from a list into the 'grpname' section
   838  * The list parameter can be a NULL pointer, in this case a callback function
   848  * The list parameter can be a NULL pointer, in this case a callback function
   841  * @param grpname character string identifying the section-header of the ini file
   851  * @param grpname character string identifying the section-header of the ini file
   842  * @param list pointer to an string(pointer) array that will be used as the
   852  * @param list pointer to an string(pointer) array that will be used as the
   843  * source to be saved into the relevant ini section
   853  * source to be saved into the relevant ini section
   844  * @param len the maximum number of items available for the above list
   854  * @param len the maximum number of items available for the above list
   845  * @param proc callback function that can will provide the source data if defined */
   855  * @param proc callback function that can will provide the source data if defined */
   846 static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len)
   856 static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
   847 {
   857 {
   848 	IniGroup *group = ini_getgroup(ini, grpname, -1);
   858 	IniGroup *group = ini_getgroup(ini, grpname, -1);
   849 	IniItem *item = NULL;
   859 	IniItem *item = NULL;
       
   860 	const char *entry;
   850 	uint i;
   861 	uint i;
   851 	bool first = true;
   862 	bool first = true;
   852 
   863 
       
   864 	if (proc == NULL && list == NULL) return;
   853 	if (group == NULL) return;
   865 	if (group == NULL) return;
   854 	group->item = NULL;
   866 	group->item = NULL;
   855 
   867 
   856 	for (i = 0; i != len; i++) {
   868 	for (i = 0; i != len; i++) {
   857 		if (list[i] == NULL || list[i][0] == '\0') continue;
   869 		entry = (proc != NULL) ? proc(NULL, i) : list[i];
       
   870 
       
   871 		if (entry == NULL || *entry == '\0') continue;
   858 
   872 
   859 		if (first) { // add first item to the head of the group
   873 		if (first) { // add first item to the head of the group
   860 			item = ini_item_alloc(group, list[i], strlen(list[i]));
   874 			item = ini_item_alloc(group, entry, strlen(entry));
   861 			item->value = item->name;
   875 			item->value = item->name;
   862 			group->item = item;
   876 			group->item = item;
   863 			first = false;
   877 			first = false;
   864 		} else { // all other items are attached to the previous one
   878 		} else { // all other items are attached to the previous one
   865 			item->next = ini_item_alloc(group, list[i], strlen(list[i]));
   879 			item->next = ini_item_alloc(group, entry, strlen(entry));
   866 			item = item->next;
   880 			item = item->next;
   867 			item->value = item->name;
   881 			item->value = item->name;
   868 		}
   882 		}
   869 	}
   883 	}
   870 }
   884 }
  1383 #undef NC
  1397 #undef NC
  1384 #undef MS
  1398 #undef MS
  1385 #undef NO
  1399 #undef NO
  1386 #undef CR
  1400 #undef CR
  1387 
  1401 
  1388 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
  1402 const char *GRFProcessParams(const IniItem *item, uint index)
  1389 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len);
  1403 {
       
  1404 	GRFConfig *c;
       
  1405 
       
  1406 	/* Saving newgrf stuff to configuration, not done since it is kept the same */
       
  1407 	if (item == NULL) return NULL;
       
  1408 
       
  1409 	/* Loading newgrf stuff from configuration file */
       
  1410 	c = calloc(1, sizeof(*c));
       
  1411 	c->filename = strdup(item->name);
       
  1412 	c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
       
  1413 	if (c->num_params == (byte)-1) {
       
  1414 		ShowInfoF("ini: error in array '%s'", item->name);
       
  1415 		c->num_params = 0;
       
  1416 	}
       
  1417 
       
  1418 	if (_first_grfconfig == NULL) {
       
  1419 		_first_grfconfig = c;
       
  1420 	} else {
       
  1421 		GRFConfig *c2;
       
  1422 		/* Attach the label to the end of the list */
       
  1423 		for (c2 = _first_grfconfig; c2->next != NULL; c2 = c2->next);
       
  1424 		c2->next = c;
       
  1425 	}
       
  1426 
       
  1427 	return c->filename;
       
  1428 }
  1390 
  1429 
  1391 /* Common handler for saving/loading variables to the configuration file */
  1430 /* Common handler for saving/loading variables to the configuration file */
  1392 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list)
  1431 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list)
  1393 {
  1432 {
  1394 	proc(ini, (const SettingDesc*)_misc_settings,    "misc",  NULL);
  1433 	proc(ini, (const SettingDesc*)_misc_settings,    "misc",  NULL);
  1401 	proc(ini, _patch_settings,   "patches",  &_patches_newgame);
  1440 	proc(ini, _patch_settings,   "patches",  &_patches_newgame);
  1402 	proc(ini, _currency_settings,"currency", &_custom_currency);
  1441 	proc(ini, _currency_settings,"currency", &_custom_currency);
  1403 
  1442 
  1404 #ifdef ENABLE_NETWORK
  1443 #ifdef ENABLE_NETWORK
  1405 	proc(ini, (const SettingDesc*)_network_settings, "network", NULL);
  1444 	proc(ini, (const SettingDesc*)_network_settings, "network", NULL);
  1406 	proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list));
  1445 	proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL);
  1407 	proc_list(ini, "bans",    _network_ban_list,  lengthof(_network_ban_list));
  1446 	proc_list(ini, "bans",    _network_ban_list,  lengthof(_network_ban_list), NULL);
  1408 #endif /* ENABLE_NETWORK */
  1447 #endif /* ENABLE_NETWORK */
  1409 }
  1448 }
  1410 
  1449 
  1411 /** Load the values from the configuration files */
  1450 /** Load the values from the configuration files */
  1412 void LoadFromConfig(void)
  1451 void LoadFromConfig(void)
  1413 {
  1452 {
  1414 	IniFile *ini = ini_load(_config_file);
  1453 	IniFile *ini = ini_load(_config_file);
  1415 	HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
  1454 	HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
  1416 	ini_load_setting_list(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files));
  1455 	ini_load_setting_list(ini, "newgrf", NULL, 0, GRFProcessParams);
  1417 	ini_free(ini);
  1456 	ini_free(ini);
  1418 }
  1457 }
  1419 
  1458 
  1420 /** Save the values to the configuration file */
  1459 /** Save the values to the configuration file */
  1421 void SaveToConfig(void)
  1460 void SaveToConfig(void)