Example #1
0
EXPORT m64p_error CALL ConfigDeleteSection(const char *SectionName)
{
    config_section *curr_section;
    config_var *curr_var;

    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (l_ConfigListActive == NULL)
        return M64ERR_INPUT_NOT_FOUND;

    /* find the named section and pull it out of the list */
    curr_section = l_ConfigListActive;
    if (osal_insensitive_strcmp(l_ConfigListActive->name, SectionName) == 0)
    {
        l_ConfigListActive = l_ConfigListActive->next;
    }
    else
    {
        while (curr_section != NULL)
        {
            config_section *next_section = curr_section->next;
            if (next_section == NULL)
                return M64ERR_INPUT_NOT_FOUND;
            if (osal_insensitive_strcmp(next_section->name, SectionName) == 0)
            {
                curr_section->next = next_section->next;
                curr_section = next_section;
                break;
            }
            curr_section = next_section;
        }
    }

    /* delete all the variables in this section */
    curr_var = curr_section->first_var;
    while (curr_var != NULL)
    {
        config_var *next_var = curr_var->next;
        if (curr_var->val_string != NULL)
            free(curr_var->val_string);
        if (curr_var->comment != NULL)
            free(curr_var->comment);
        free(curr_var);
        curr_var = next_var;
    }
    /* delete the section itself */
    free(curr_section);

    return M64ERR_SUCCESS;
}
Example #2
0
EXPORT m64p_error CALL ConfigOpenSection(const char *SectionName, m64p_handle *ConfigSectionHandle)
{
    config_section *curr_section, *new_section;

    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (SectionName == NULL || ConfigSectionHandle == NULL)
        return M64ERR_INPUT_ASSERT;

    /* walk through the section list, looking for a case-insensitive name match */
    curr_section = l_ConfigListActive;
    while (curr_section != NULL)
    {
        if (osal_insensitive_strcmp(SectionName, curr_section->name) == 0)
        {
            *ConfigSectionHandle = curr_section;
            return M64ERR_SUCCESS;
        }
        curr_section = curr_section->next;
    }

    /* didn't find the section, so create new one */
    new_section = (config_section *) malloc(sizeof(config_section));
    if (new_section == NULL)
        return M64ERR_NO_MEMORY;
    new_section->magic = SECTION_MAGIC;
    strncpy(new_section->name, SectionName, 63);
    new_section->name[63] = 0;
    new_section->first_var = NULL;
    new_section->next = NULL;

    /* add section to list in alphabetical order */
    if (l_ConfigListActive == NULL || osal_insensitive_strcmp(SectionName, l_ConfigListActive->name) < 0)
    {
        new_section->next = l_ConfigListActive;
        l_ConfigListActive = new_section;
    }
    else
    {
        curr_section = l_ConfigListActive;
        while (curr_section->next != NULL && osal_insensitive_strcmp(SectionName, curr_section->next->name) >= 0)
            curr_section = curr_section->next;
        new_section->next = curr_section->next;
        curr_section->next = new_section;
    }

    *ConfigSectionHandle = new_section;
    return M64ERR_SUCCESS;
}
Example #3
0
EXPORT m64p_error CALL ConfigOpenSection(const char *SectionName, m64p_handle *ConfigSectionHandle)
{
    config_section **curr_section;
    config_section *new_section;

    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (SectionName == NULL || ConfigSectionHandle == NULL)
        return M64ERR_INPUT_ASSERT;

    /* walk through the section list, looking for a case-insensitive name match */
    curr_section = find_alpha_section_link(&l_ConfigListActive, SectionName);
    if (*curr_section != NULL && osal_insensitive_strcmp(SectionName, (*curr_section)->name) == 0)
    {
        *ConfigSectionHandle = *curr_section;
        return M64ERR_SUCCESS;
    }

    /* didn't find the section, so create new one */
    new_section = config_section_create(SectionName);
    if (new_section == NULL)
        return M64ERR_NO_MEMORY;

    /* add section to list in alphabetical order */
    new_section->next = *curr_section;
    *curr_section = new_section;

    *ConfigSectionHandle = new_section;
    return M64ERR_SUCCESS;
}
Example #4
0
EXPORT m64p_error CALL ConfigRevertChanges(const char *SectionName)
{
    config_section *input_section, *curr_section, *new_section, *temp_next_ptr;

    /* check input conditions */
    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (SectionName == NULL)
        return M64ERR_INPUT_ASSERT;

    /* walk through the Active section list, looking for a case-insensitive name match with input string */
    input_section = l_ConfigListActive;
    while (input_section != NULL)
    {
        if (osal_insensitive_strcmp(SectionName, input_section->name) == 0)
            break;
        input_section = input_section->next;
    }
    if (input_section == NULL)
        return M64ERR_INPUT_NOT_FOUND;

    /* walk through the Saved section list, looking for a case-insensitive name match */
    curr_section = l_ConfigListSaved;
    while (curr_section != NULL)
    {
        if (osal_insensitive_strcmp(SectionName, curr_section->name) == 0)
            break;
        curr_section = curr_section->next;
    }
    /* if this section isn't present in saved list, then it has been newly created */
    if (curr_section == NULL)
        return M64ERR_INPUT_NOT_FOUND;

    /* we need to save the "next" pointer in the active section, because this will get blown away by the deepcopy */
    temp_next_ptr = input_section->next;
    /* delete the variables from the Active section */
    delete_section_vars(input_section);
    /* copy all of the section data from the Saved section to the Active one */
    new_section = section_deepcopy(curr_section, input_section);
    if (new_section == NULL)
        return M64ERR_NO_MEMORY;  /* it's very bad if this happens, because original data from Active section has been deleted */
    /* new_section should be == to input_section.  now put the "next" pointer back */
    input_section->next = temp_next_ptr;

    /* should be good to go */
    return M64ERR_SUCCESS;
}
Example #5
0
EXPORT m64p_error CALL ConfigExternalGetParameter(m64p_handle Handle, const char *SectionName, const char *ParamName, char* ParamPtr, int ParamMaxLength)
{
    struct external_config* ext_config = Handle;
    int foundSection = 0;
    if (ParamPtr == NULL || SectionName == NULL || ParamName == NULL)
        return M64ERR_INPUT_INVALID;

    void *buffer = malloc(ext_config->length + 1);
    memcpy(buffer, ext_config->file, ext_config->length + 1);
    char *line = buffer;
    char *end = line + ext_config->length;
    while (line < end)
    {
        ini_line l = ini_parse_line(&line);
        switch (l.type)
        {
            case INI_SECTION:
                if (osal_insensitive_strcmp(SectionName, l.name) == 0)
                    foundSection = 1;
                else
                    foundSection = 0;
                break;
            case INI_PROPERTY:
                if (foundSection)
                {
                    if (osal_insensitive_strcmp(ParamName, l.name) == 0)
                    {
                        strncpy(ParamPtr, l.value, ParamMaxLength);
                        free(buffer);
                        return M64ERR_SUCCESS;
                    }
                }
                break;
            default:
                break;
        }
    }
    free(buffer);
    return M64ERR_INPUT_NOT_FOUND;
}
Example #6
0
static config_var *find_section_var(config_section *section, const char *ParamName)
{
    /* walk through the linked list of variables in the section */
    config_var *curr_var;
    for (curr_var = section->first_var; curr_var != NULL; curr_var = curr_var->next)
    {
        if (osal_insensitive_strcmp(ParamName, curr_var->name) == 0)
            return curr_var;
    }

    /* couldn't find this configuration parameter */
    return NULL;
}
Example #7
0
EXPORT int CALL ConfigGetParamBool(m64p_handle ConfigSectionHandle, const char *ParamName)
{
    config_section *section;
    config_var *var;

    /* check input conditions */
    if (!l_ConfigInit || ConfigSectionHandle == NULL || ParamName == NULL)
    {
        DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): Input assertion!");
        return 0;
    }

    section = (config_section *) ConfigSectionHandle;
    if (section->magic != SECTION_MAGIC)
    {
        DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): ConfigSectionHandle invalid!");
        return 0;
    }

    /* if this parameter doesn't already exist, return an error */
    var = find_section_var(section, ParamName);
    if (var == NULL)
    {
        DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): Parameter '%s' not found!", ParamName);
        return 0;
    }

    /* translate the actual variable type to an int */
    switch(var->type)
    {
        case M64TYPE_INT:
            return (var->val_int != 0);
        case M64TYPE_FLOAT:
            return (var->val_float != 0.0);
        case M64TYPE_BOOL:
            return var->val_int;
        case M64TYPE_STRING:
            return (osal_insensitive_strcmp(var->val_string, "true") == 0);
        default:
            DebugMessage(M64MSG_ERROR, "ConfigGetParamBool(): invalid internal parameter type for '%s'", ParamName);
            return 0;
    }

    return 0;
}
Example #8
0
EXPORT m64p_error CALL ConfigSaveSection(const char *SectionName)
{
    config_section *curr_section, *new_section;
    config_section **insertion_point;

    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (SectionName == NULL || strlen(SectionName) < 1)
        return M64ERR_INPUT_ASSERT;

    /* walk through the Active section list, looking for a case-insensitive name match */
    curr_section = find_section(l_ConfigListActive, SectionName);
    if (curr_section == NULL)
        return M64ERR_INPUT_NOT_FOUND;

    /* duplicate this section */
    new_section = section_deepcopy(curr_section);
    if (new_section == NULL)
        return M64ERR_NO_MEMORY;

    /* update config section that's in the Saved list with the new one */
    insertion_point = find_alpha_section_link(&l_ConfigListSaved, SectionName);
    if (*insertion_point != NULL && osal_insensitive_strcmp((*insertion_point)->name, SectionName) == 0)
    {
        /* the section exists in the saved list and will be replaced */
        new_section->next = (*insertion_point)->next;
        delete_section(*insertion_point);
        *insertion_point = new_section;
    }
    else
    {
        /* the section didn't exist in the saved list and has to be inserted */
        new_section->next = *insertion_point;
        *insertion_point = new_section;
    }

    /* write the saved config list out to a file */
    return (write_configlist_file());
}
Example #9
0
EXPORT m64p_error CALL ConfigSaveSection(const char *SectionName)
{
    config_section *curr_section, *new_section;

    if (!l_ConfigInit)
        return M64ERR_NOT_INIT;
    if (SectionName == NULL || strlen(SectionName) < 1)
        return M64ERR_INPUT_ASSERT;

    /* walk through the Active section list, looking for a case-insensitive name match */
    curr_section = l_ConfigListActive;
    while (curr_section != NULL)
    {
        if (osal_insensitive_strcmp(SectionName, curr_section->name) == 0)
            break;
        curr_section = curr_section->next;
    }
    if (curr_section == NULL)
        return M64ERR_INPUT_NOT_FOUND;

    /* duplicate this section */
    new_section = section_deepcopy(curr_section, NULL);
    if (new_section == NULL)
        return M64ERR_NO_MEMORY;

    /* update config section that's in the Saved list with the new one */
    if (l_ConfigListSaved == NULL || osal_insensitive_strcmp(SectionName, l_ConfigListSaved->name) < 0)
    {
        /* the saved section is new and goes at the beginning of the list */
        new_section->next = l_ConfigListSaved;
        l_ConfigListSaved = new_section;
    }
    else if (osal_insensitive_strcmp(SectionName, l_ConfigListSaved->name) == 0)
    {
        /* the saved section replaces the first section in the list */
        new_section->next = l_ConfigListSaved->next;
        delete_section_vars(l_ConfigListSaved);
        free(l_ConfigListSaved);
        l_ConfigListSaved = new_section;
    }
    else
    {
        curr_section = l_ConfigListSaved;
        while (curr_section->next != NULL && osal_insensitive_strcmp(SectionName, curr_section->next->name) > 0)
            curr_section = curr_section->next;
        if (curr_section->next == NULL || osal_insensitive_strcmp(SectionName, curr_section->next->name) < 0)
        {
            /* the saved section is new and goes after the curr_section */
            new_section->next = curr_section->next;
            curr_section->next = new_section;
        }
        else
        {
            /* the saved section replaces curr_section->next */
            config_section *old_section = curr_section->next;
            new_section->next = old_section->next;
            delete_section_vars(old_section);
            free(old_section);
            curr_section->next = new_section;
        }
    }

    /* write the saved config list out to a file */
    return (write_configlist_file());
}
Example #10
0
EXPORT int CALL ConfigHasUnsavedChanges(const char *SectionName)
{
    config_section *input_section, *curr_section;
    config_var *active_var, *saved_var;

    /* check input conditions */
    if (!l_ConfigInit)
    {
        DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Core config not initialized!");
        return 0;
    }

    /* if SectionName is NULL or blank, then check all sections */
    if (SectionName == NULL || strlen(SectionName) < 1)
    {
        int iNumActiveSections = 0, iNumSavedSections = 0;
        /* first, search through all sections in Active list.  Recursively call ourself and return 1 if changed */
        curr_section = l_ConfigListActive;
        while (curr_section != NULL)
        {
            if (ConfigHasUnsavedChanges(curr_section->name))
                return 1;
            curr_section = curr_section->next;
            iNumActiveSections++;
        }
        /* Next, count the number of Saved sections and see if the count matches */
        curr_section = l_ConfigListSaved;
        while (curr_section != NULL)
        {
            curr_section = curr_section->next;
            iNumSavedSections++;
        }
        if (iNumActiveSections == iNumSavedSections)
            return 0;  /* no changes */
        else
            return 1;
    }

    /* walk through the Active section list, looking for a case-insensitive name match with input string */
    input_section = l_ConfigListActive;
    while (input_section != NULL)
    {
        if (osal_insensitive_strcmp(SectionName, input_section->name) == 0)
            break;
        input_section = input_section->next;
    }
    if (input_section == NULL)
    {
        DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): section name '%s' not found!", SectionName);
        return 0;
    }

    /* walk through the Saved section list, looking for a case-insensitive name match */
    curr_section = l_ConfigListSaved;
    while (curr_section != NULL)
    {
        if (osal_insensitive_strcmp(input_section->name, curr_section->name) == 0)
            break;
        curr_section = curr_section->next;
    }
    /* if this section isn't present in saved list, then it has been newly created */
    if (curr_section == NULL)
        return 1;

    /* compare all of the variables in the two sections. They are expected to be in the same order */
    active_var = input_section->first_var;
    saved_var = curr_section->first_var;
    while (active_var != NULL && saved_var != NULL)
    {
        if (strncmp(active_var->name, saved_var->name, 64) != 0)
            return 1;
        if (active_var->type != saved_var->type)
            return 1;
        switch(active_var->type)
        {
            case M64TYPE_INT:
                if (active_var->val_int != saved_var->val_int)
                    return 1;
                break;
            case M64TYPE_FLOAT:
                if (active_var->val_float != saved_var->val_float)
                    return 1;
                break;
            case M64TYPE_BOOL:
                if ((active_var->val_int != 0) != (saved_var->val_int != 0))
                    return 1;
                break;
            case M64TYPE_STRING:
                if (active_var->val_string == NULL)
                {
                    DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Variable '%s' NULL Active string pointer!", active_var->name);
                    return 1;
                }
                if (saved_var->val_string == NULL)
                {
                    DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Variable '%s' NULL Saved string pointer!", active_var->name);
                    return 1;
                }
                if (strcmp(active_var->val_string, saved_var->val_string) != 0)
                    return 1;
                break;
            default:
                DebugMessage(M64MSG_ERROR, "ConfigHasUnsavedChanges(): Invalid variable '%s' type %i!", active_var->name, active_var->type);
                return 1;
        }
        if (active_var->comment != NULL && saved_var->comment != NULL && strcmp(active_var->comment, saved_var->comment) != 0)
            return 1;
        active_var = active_var->next;
        saved_var = saved_var->next;
    }

    /* any extra new variables on the end, or deleted variables? */
    if (active_var != NULL || saved_var != NULL)
        return 1;

    /* exactly the same */
    return 0;
}
Example #11
0
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 *) &current_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;
}
Example #12
0
static int SetConfigParameter(const char *ParamSpec)
{
    char *ParsedString, *VarName, *VarValue=NULL;
    m64p_handle ConfigSection;
    m64p_type VarType;
    m64p_error rval;

    if (ParamSpec == NULL)
    {
        DebugMessage(M64MSG_ERROR, "ParamSpec is NULL in SetConfigParameter()");
        return 1;
    }

    /* make a copy of the input string */
    ParsedString = (char *) malloc(strlen(ParamSpec) + 1);
    if (ParsedString == NULL)
    {
        DebugMessage(M64MSG_ERROR, "SetConfigParameter() couldn't allocate memory for temporary string.");
        return 2;
    }
    strcpy(ParsedString, ParamSpec);

    /* parse it for the simple section[name]=value format */
    VarName = strchr(ParsedString, '[');
    if (VarName != NULL)
    {
        *VarName++ = 0;
        VarValue = strchr(VarName, ']');
        if (VarValue != NULL)
        {
            *VarValue++ = 0;
        }
    }
    if (VarName == NULL || VarValue == NULL || *VarValue != '=')
    {
        DebugMessage(M64MSG_ERROR, "invalid (param-spec) '%s'", ParamSpec);
        free(ParsedString);
        return 3;
    }
    VarValue++;

    /* then set the value */
    rval = (*ConfigOpenSection)(ParsedString, &ConfigSection);
    if (rval != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_ERROR, "SetConfigParameter failed to open config section '%s'", ParsedString);
        free(ParsedString);
        return 4;
    }
    if ((*ConfigGetParameterType)(ConfigSection, VarName, &VarType) == M64ERR_SUCCESS)
    {
        switch(VarType)
        {
            int ValueInt;
            float ValueFloat;
            case M64TYPE_INT:
                ValueInt = atoi(VarValue);
                ConfigSetParameter(ConfigSection, VarName, M64TYPE_INT, &ValueInt);
                break;
            case M64TYPE_FLOAT:
                ValueFloat = (float) atof(VarValue);
                ConfigSetParameter(ConfigSection, VarName, M64TYPE_FLOAT, &ValueFloat);
                break;
            case M64TYPE_BOOL:
                ValueInt = (int) (osal_insensitive_strcmp(VarValue, "true") == 0);
                ConfigSetParameter(ConfigSection, VarName, M64TYPE_BOOL, &ValueInt);
                break;
            case M64TYPE_STRING:
                ConfigSetParameter(ConfigSection, VarName, M64TYPE_STRING, VarValue);
                break;
            default:
                DebugMessage(M64MSG_ERROR, "invalid VarType in SetConfigParameter()");
                return 5;
        }
    }
    else
    {
        ConfigSetParameter(ConfigSection, VarName, M64TYPE_STRING, VarValue);
    }

    free(ParsedString);
    return 0;
}
Example #13
0
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 *) &current_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;
}