EXPORT m64p_error CALL ConfigSaveFile(void) { if (!l_ConfigInit) return M64ERR_NOT_INIT; /* copy the active config list to the saved config list */ copy_configlist_active_to_saved(); /* write the saved config list out to a file */ return (write_configlist_file()); }
m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride) { m64p_error rval; const char *configpath = NULL; char *filepath; long filelen, pathlen; FILE *fPtr; char *configtext; config_section *current_section = NULL; char *line, *end, *lastcomment; if (l_ConfigInit) return M64ERR_ALREADY_INIT; l_ConfigInit = 1; /* if a data directory was specified, make a copy of it */ if (DataDirOverride != NULL) { l_DataDirOverride = (char *) malloc(strlen(DataDirOverride) + 1); if (l_DataDirOverride == NULL) return M64ERR_NO_MEMORY; strcpy(l_DataDirOverride, DataDirOverride); } /* if a config directory was specified, make a copy of it */ if (ConfigDirOverride != NULL) { l_ConfigDirOverride = (char *) malloc(strlen(ConfigDirOverride) + 1); if (l_ConfigDirOverride == NULL) return M64ERR_NO_MEMORY; strcpy(l_ConfigDirOverride, ConfigDirOverride); } /* get the full pathname to the config file and try to open it */ configpath = ConfigGetUserConfigPath(); if (configpath == NULL) return M64ERR_FILES; filepath = (char *) malloc(strlen(configpath) + 32); if (filepath == NULL) return M64ERR_NO_MEMORY; strcpy(filepath, configpath); pathlen = strlen(filepath); if (filepath[pathlen - 1] != OSAL_DIR_SEPARATOR) { filepath[pathlen] = OSAL_DIR_SEPARATOR; filepath[pathlen + 1] = 0; } strcat(filepath, MUPEN64PLUS_CFG_NAME); fPtr = fopen(filepath, "rb"); if (fPtr == NULL) { DebugMessage(M64MSG_INFO, "Couldn't open configuration file '%s'. Using defaults.", filepath); free(filepath); l_SaveConfigOnExit = 1; /* auto-save the config file so that the defaults will be saved to disk */ return M64ERR_SUCCESS; } free(filepath); /* read the entire config file */ fseek(fPtr, 0L, SEEK_END); filelen = ftell(fPtr); fseek(fPtr, 0L, SEEK_SET); configtext = (char *) malloc(filelen + 16); if (configtext == NULL) { fclose(fPtr); return M64ERR_NO_MEMORY; } if (fread(configtext, 1, filelen, fPtr) != filelen) { free(configtext); fclose(fPtr); return M64ERR_FILES; } fclose(fPtr); /* parse the file data */ current_section = NULL; line = configtext; end = configtext + filelen; lastcomment = NULL; *end = 0; while (line < end) { char *pivot, *varname, *varvalue; /* get the pointer to the next line, and null-terminate this line */ char *nextline = strchr(line, '\n'); if (nextline == NULL) nextline = end; *nextline++ = 0; /* strip the whitespace and handle comment */ strip_whitespace(line); if (strlen(line) < 1) { line = nextline; continue; } if (line[0] == '#') { line++; strip_whitespace(line); lastcomment = line; line = nextline; continue; } /* handle section definition line */ if (strlen(line) > 2 && line[0] == '[' && line[strlen(line)-1] == ']') { line++; line[strlen(line)-1] = 0; rval = ConfigOpenSection(line, (m64p_handle *) ¤t_section); if (rval != M64ERR_SUCCESS) { free(configtext); return rval; } lastcomment = NULL; line = nextline; continue; } /* handle variable definition */ pivot = strchr(line, '='); if (current_section == NULL || pivot == NULL) { line = nextline; continue; } varname = line; varvalue = pivot + 1; *pivot = 0; strip_whitespace(varname); strip_whitespace(varvalue); if (varvalue[0] == '"' && varvalue[strlen(varvalue)-1] == '"') { varvalue++; varvalue[strlen(varvalue)-1] = 0; ConfigSetDefaultString((m64p_handle) current_section, varname, varvalue, lastcomment); } else if (osal_insensitive_strcmp(varvalue, "false") == 0) { ConfigSetDefaultBool((m64p_handle) current_section, varname, 0, lastcomment); } else if (osal_insensitive_strcmp(varvalue, "true") == 0) { ConfigSetDefaultBool((m64p_handle) current_section, varname, 1, lastcomment); } else if (is_numeric(varvalue)) { int val_int = (int) strtol(varvalue, NULL, 10); float val_float = (float) strtod(varvalue, NULL); if ((val_float - val_int) != 0.0) ConfigSetDefaultFloat((m64p_handle) current_section, varname, val_float, lastcomment); else ConfigSetDefaultInt((m64p_handle) current_section, varname, val_int, lastcomment); } else { /* assume that it's a string */ ConfigSetDefaultString((m64p_handle) current_section, varname, varvalue, lastcomment); } lastcomment = NULL; line = nextline; } /* release memory used for config file text */ free(configtext); /* duplicate the entire config data list, to store a copy of the list which represents the state of the file on disk */ copy_configlist_active_to_saved(); return M64ERR_SUCCESS; }
m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride) { m64p_error rval; const char *configpath = NULL; char *filepath; long filelen; FILE *fPtr; char *configtext; config_section *current_section = NULL; char *line, *end, *lastcomment; if (l_ConfigInit) return M64ERR_ALREADY_INIT; l_ConfigInit = 1; /* if a data directory was specified, make a copy of it */ if (DataDirOverride != NULL) { l_DataDirOverride = strdup(DataDirOverride); if (l_DataDirOverride == NULL) return M64ERR_NO_MEMORY; /* TODO mupen64plus-ae specific hack */ strcpy(l_DataDirOverride, DataDirOverride); } /* if a config directory was specified, make a copy of it */ if (ConfigDirOverride != NULL) { l_ConfigDirOverride = strdup(ConfigDirOverride); if (l_ConfigDirOverride == NULL) return M64ERR_NO_MEMORY; } /* get the full pathname to the config file and try to open it */ configpath = ConfigGetUserConfigPath(); if (configpath == NULL) return M64ERR_FILES; filepath = combinepath(configpath, MUPEN64PLUS_CFG_NAME); if (filepath == NULL) return M64ERR_NO_MEMORY; fPtr = fopen(filepath, "rb"); if (fPtr == NULL) { DebugMessage(M64MSG_INFO, "Couldn't open configuration file '%s'. Using defaults.", filepath); free(filepath); l_SaveConfigOnExit = 1; /* auto-save the config file so that the defaults will be saved to disk */ return M64ERR_SUCCESS; } free(filepath); /* read the entire config file */ fseek(fPtr, 0L, SEEK_END); filelen = ftell(fPtr); fseek(fPtr, 0L, SEEK_SET); configtext = (char *) malloc(filelen + 1); if (configtext == NULL) { fclose(fPtr); return M64ERR_NO_MEMORY; } if (fread(configtext, 1, filelen, fPtr) != filelen) { free(configtext); fclose(fPtr); return M64ERR_FILES; } fclose(fPtr); /* parse the file data */ current_section = NULL; line = configtext; end = configtext + filelen; lastcomment = NULL; *end = 0; while (line < end) { ini_line l = ini_parse_line(&line); switch (l.type) { case INI_COMMENT: lastcomment = l.value; break; case INI_SECTION: rval = ConfigOpenSection(l.name, (m64p_handle *) ¤t_section); if (rval != M64ERR_SUCCESS) { free(configtext); return rval; } lastcomment = NULL; break; case INI_PROPERTY: if (l.value[0] == '"' && l.value[strlen(l.value)-1] == '"') { l.value++; l.value[strlen(l.value)-1] = 0; ConfigSetDefaultString((m64p_handle) current_section, l.name, l.value, lastcomment); } else if (osal_insensitive_strcmp(l.value, "false") == 0) { ConfigSetDefaultBool((m64p_handle) current_section, l.name, 0, lastcomment); } else if (osal_insensitive_strcmp(l.value, "true") == 0) { ConfigSetDefaultBool((m64p_handle) current_section, l.name, 1, lastcomment); } else if (is_numeric(l.value)) { int val_int = (int) strtol(l.value, NULL, 10); float val_float = (float) strtod(l.value, NULL); if ((val_float - val_int) != 0.0) ConfigSetDefaultFloat((m64p_handle) current_section, l.name, val_float, lastcomment); else ConfigSetDefaultInt((m64p_handle) current_section, l.name, val_int, lastcomment); } else { /* assume that it's a string */ ConfigSetDefaultString((m64p_handle) current_section, l.name, l.value, lastcomment); } lastcomment = NULL; break; default: break; } } /* release memory used for config file text */ free(configtext); /* duplicate the entire config data list, to store a copy of the list which represents the state of the file on disk */ copy_configlist_active_to_saved(); return M64ERR_SUCCESS; }