Beispiel #1
0
DLLIMPORT int cfg_opt_setmulti(cfg_t *cfg, cfg_opt_t *opt, unsigned int nvalues, char **values)
{
	cfg_opt_t old;
	unsigned int i;

	if (!opt || !nvalues)
		return -1;

	old = *opt;
	opt->nvalues = 0;
	opt->values = 0;

	for (i = 0; i < nvalues; i++) {
		if (cfg_setopt(cfg, opt, values[i]))
			continue;
		/* ouch, revert */
		cfg_free_value(opt);
		opt->nvalues = old.nvalues;
		opt->values = old.values;
		return -1;
	}

	cfg_free_value(&old);
	return 0;
}
Beispiel #2
0
void remove_deprecated_config_options(const gchar *const *deprecated_config_options, guint size) {
    cfg_opt_t *opt;
    for (guint i =0; i < size; i++) {
        opt = cfg_getopt(tc, deprecated_config_options[i]);
        if (opt->nvalues != 0) {
            g_warning("Warning: %s is no longer a valid config option for the current version of Tilda.\n", deprecated_config_options[i]);
            cfg_free_value(opt);
        }
    }
}
Beispiel #3
0
DLLIMPORT void cfg_setlist(cfg_t *cfg, const char *name, unsigned int nvalues, ...)
{
	va_list ap;
	cfg_opt_t *opt = cfg_getopt(cfg, name);

	assert(opt && is_set(CFGF_LIST, opt->flags));

	cfg_free_value(opt);
	va_start(ap, nvalues);
	cfg_addlist_internal(opt, nvalues, ap);
	va_end(ap);
}
Beispiel #4
0
static int call_function(cfg_t *cfg, cfg_opt_t *opt, cfg_opt_t *funcopt)
{
    int ret;
    const char **argv;
    unsigned int i;

    /* create a regular argv string vector and call
     * the registered function
     */
    argv = calloc(funcopt->nvalues, sizeof(char *));
    for(i = 0; i < funcopt->nvalues; i++)
        argv[i] = funcopt->values[i]->string;
    ret = (*opt->func)(cfg, opt, funcopt->nvalues, argv);
    cfg_free_value(funcopt);
    free((void *)argv);
    return ret;
}
Beispiel #5
0
DLLIMPORT void cfg_free(cfg_t *cfg)
{
    int i;

    if(cfg == 0)
        return;

    for(i = 0; cfg->opts[i].name; ++i)
        cfg_free_value(&cfg->opts[i]);

    cfg_free_opt_array(cfg->opts);

    free(cfg->name);
    free(cfg->title);
    free(cfg->filename);

    free(cfg);
}
Beispiel #6
0
static cfg_value_t *cfg_opt_getval(cfg_opt_t *opt, unsigned int index)
{
	cfg_value_t *val = 0;

	assert(index == 0 || is_set(CFGF_LIST, opt->flags) || is_set(CFGF_MULTI, opt->flags));

	if (opt->simple_value.ptr)
		val = (cfg_value_t *)opt->simple_value.ptr;
	else {
		if (is_set(CFGF_RESET, opt->flags)) {
			cfg_free_value(opt);
			opt->flags &= ~CFGF_RESET;
		}

		if (index >= opt->nvalues)
			val = cfg_addval(opt);
		else
			val = opt->values[index];
	}
	return val;
}
Beispiel #7
0
void
gimmix_config_save (Conf *conf)
{
	FILE *fp;
	cfg_t *cfg;
	cfg_opt_t *sopts;
	
	cfg_opt_t opts[] = {
		CFG_SIMPLE_STR ("mpd_hostname", NULL),
		CFG_SIMPLE_INT ("mpd_port", 0),
		CFG_SIMPLE_STR ("mpd_password", NULL),
		CFG_SIMPLE_BOOL ("enable_systray", false),
		CFG_SIMPLE_BOOL ("enable_notify", false),
		CFG_END()
	};

	cfg = cfg_init(opts, 0);
	char *rcfile = cfg_tilde_expand ("~/.gimmixrc");
	
	if((fp = fopen(rcfile, "w")))
	{	
		fprintf (fp, "# Gimmix configuration\n");
		fprintf (fp, "\n# MPD hostname (default: localhost)\n");
		if (conf->hostname)
			cfg_setstr(cfg, "mpd_hostname", conf->hostname);
		sopts = cfg_getopt (cfg, "mpd_hostname");
		cfg_opt_print (sopts, fp);

		fprintf (fp, "\n# MPD port (default: 6600)\n");
		if (conf->port > 0)
			cfg_setint(cfg, "mpd_port", conf->port);
		else
			cfg_setint(cfg, "mpd_port", 0);
		sopts = cfg_getopt (cfg, "mpd_port");
		cfg_opt_print (sopts, fp);
		
		fprintf (fp, "\n# MPD password (leave blank for no password) \n");
		if (conf->password)
			cfg_setstr(cfg, "mpd_password", conf->password);
		sopts = cfg_getopt (cfg, "mpd_password");
		cfg_opt_print (sopts, fp);

		fprintf (fp, "\n# Enable/Disable systray icon (Enable = true, Disable = false)\n");
		if (conf->systray_enable == 1)
			cfg_setbool(cfg, "enable_systray", true);
		else
			cfg_setbool(cfg, "enable_systray", false);
		sopts = cfg_getopt (cfg, "enable_systray");
		cfg_opt_print (sopts, fp);
		
		fprintf (fp, "\n# Enable/Disable system tray notifications (Enable = true, Disable = false) \n");
		if (conf->notify_enable == 1)
			cfg_setbool(cfg, "enable_notify", true);
		else
			cfg_setbool(cfg, "enable_notify", false);
		sopts = cfg_getopt (cfg, "enable_notify");
		cfg_opt_print (sopts, fp);

		free (rcfile);
		fclose (fp);
	}
	else
	{	
		fprintf (stderr, "Error while saving config.\n");
	}

	cfg_free_value (opts);
	cfg_free (cfg);
	
	return;
}
Beispiel #8
0
Conf *
gimmix_config_init (void)
{
	cfg_t 		*cfg = NULL;
	char		*rcfile;
	Conf 		*conf;
	int 		ret;
	int		port = 1;
	cfg_bool_t	systray_enable = true;
	cfg_bool_t	notify_enable = true;
	
	conf = (Conf*)malloc(sizeof(Conf));
	char	*host = NULL;
	char	*pass = NULL;

	cfg_opt_t opts[] = {
		CFG_SIMPLE_STR ("mpd_hostname", &host),
		CFG_SIMPLE_INT ("mpd_port", &port),
		CFG_SIMPLE_STR ("mpd_password", &pass),
		CFG_SIMPLE_BOOL ("enable_systray", &systray_enable),
		CFG_SIMPLE_BOOL ("enable_notify", &notify_enable),
		CFG_END()
	};
	
	cfg = cfg_init (opts, 0);
	rcfile = cfg_tilde_expand ("~/.gimmixrc");
	ret = cfg_parse (cfg, rcfile);
	free (rcfile);
	
	if (ret == CFG_PARSE_ERROR)
	{
		free (conf);
		return NULL;
	}
	
	if (host != NULL)
		strncpy (conf->hostname, host, 255);
	
	if (pass != NULL)	
		strncpy (conf->password, pass, 255);
	
	conf->port = port;
	
	if (systray_enable == true)
	{	
		conf->systray_enable = 1;
	}
	else
	{	
		conf->systray_enable = 0;
	}
		
	if (notify_enable == true)
	{	
		conf->notify_enable = 1;
	}
	else
	{
		conf->notify_enable = 0;
	}

	/* Free the memory */
	cfg_free_value (opts);
	
	if (cfg)
		cfg_free (cfg);
	
	return conf;
}
Beispiel #9
0
static int cfg_parse_internal(cfg_t *cfg, int level,
                              int force_state, cfg_opt_t *force_opt)
{
    int state = 0;
    char *opttitle = 0;
    cfg_opt_t *opt = 0;
    cfg_value_t *val = 0;
    cfg_opt_t funcopt = CFG_STR(0, 0, 0);
    int num_values = 0; /* number of values found for a list option */
    int rc;

    if(force_state != -1)
        state = force_state;
    if(force_opt)
        opt = force_opt;

    while(1)
    {
        int tok = cfg_yylex(cfg);

        if(tok == 0)
        {
            /* lexer.l should have called cfg_error */
            return STATE_ERROR;
        }

        if(tok == EOF)
        {
            if(state != 0)
            {
                cfg_error(cfg, _("premature end of file"));
                return STATE_ERROR;
            }
            return STATE_EOF;
        }

        switch(state)
        {
            case 0: /* expecting an option name */
                if(tok == '}')
                {
                    if(level == 0)
                    {
                        cfg_error(cfg, _("unexpected closing brace"));
                        return STATE_ERROR;
                    }
                    return STATE_EOF;
                }
                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }
                opt = cfg_getopt(cfg, cfg_yylval);
                if(opt == 0)
                    return STATE_ERROR;
                if(opt->type == CFGT_SEC)
                {
                    if(is_set(CFGF_TITLE, opt->flags))
                        state = 6;
                    else
                        state = 5;
                }
                else if(opt->type == CFGT_FUNC)
                {
                    state = 7;
                }
                else
                    state = 1;
                break;

            case 1: /* expecting an equal sign or plus-equal sign */
                if(tok == '+')
                {
                    if(!is_set(CFGF_LIST, opt->flags))
                    {
                        cfg_error(cfg,
                                  _("attempt to append to non-list option '%s'"),
                                  opt->name);
                        return STATE_ERROR;
                    }
                    /* Even if the reset flag was set by
                     * cfg_init_defaults, appending to the defaults
                     * should be ok.
                     */
                    opt->flags &= ~CFGF_RESET;
                }
                else if(tok == '=')
                {
                    /* set the (temporary) reset flag to clear the old
                     * values, since we obviously didn't want to append */
                    opt->flags |= CFGF_RESET;
                }
                else
                {
                    cfg_error(cfg, _("missing equal sign after option '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                if(is_set(CFGF_LIST, opt->flags))
                {
                    state = 3;
                    num_values = 0;
                } else
                    state = 2;
                break;

            case 2: /* expecting an option value */
                if(tok == '}' && is_set(CFGF_LIST, opt->flags))
                {
                    state = 0;
                    if(num_values == 0 && is_set(CFGF_RESET, opt->flags))
                        /* Reset flags was set, and the empty list was
                         * specified. Free all old values. */
                        cfg_free_value(opt);
                    break;
                }

                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }

                if(cfg_setopt(cfg, opt, cfg_yylval) == 0)
                    return STATE_ERROR;
                if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                    return STATE_ERROR;
                if(is_set(CFGF_LIST, opt->flags))
                {
                    state = 4;
                    ++num_values;
                }
                else
                    state = 0;
                break;

            case 3: /* expecting an opening brace for a list option */
                if(tok != '{')
                {
                    cfg_error(cfg, _("missing opening brace for option '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                state = 2;
                break;

            case 4: /* expecting a separator for a list option, or
                     * closing (list) brace */
                if(tok == ',')
                    state = 2;
                else if(tok == '}')
                {
                    state = 0;
                    if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                        return STATE_ERROR;
                }
                else
                {
                    cfg_error(cfg, _("unexpected token '%s'"), cfg_yylval);
                    return STATE_ERROR;
                }
                break;

            case 5: /* expecting an opening brace for a section */
                if(tok != '{')
                {
                    cfg_error(cfg, _("missing opening brace for section '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }

                val = cfg_setopt(cfg, opt, opttitle);
                opttitle = 0;
                if(!val)
                    return STATE_ERROR;

                val->section->line = cfg->line;
                rc = cfg_parse_internal(val->section, level+1,-1,0);
                cfg->line = val->section->line;
                if(rc != STATE_EOF)
                    return STATE_ERROR;
                if(opt->validcb && (*opt->validcb)(cfg, opt) != 0)
                    return STATE_ERROR;
                state = 0;
                break;

            case 6: /* expecting a title for a section */
                if(tok != CFGT_STR)
                {
                    cfg_error(cfg, _("missing title for section '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                else
                    opttitle = strdup(cfg_yylval);
                state = 5;
                break;

            case 7: /* expecting an opening parenthesis for a function */
                if(tok != '(')
                {
                    cfg_error(cfg, _("missing parenthesis for function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                state = 8;
                break;

            case 8: /* expecting a function parameter or a closing paren */
                if(tok == ')')
                {
                    int ret = call_function(cfg, opt, &funcopt);
                    if(ret != 0)
                        return STATE_ERROR;
                    state = 0;
                }
                else if(tok == CFGT_STR)
                {
                    val = cfg_addval(&funcopt);
                    val->string = strdup(cfg_yylval);
                    state = 9;
                }
                else
                {
                    cfg_error(cfg, _("syntax error in call of function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                break;

            case 9: /* expecting a comma in a function or a closing paren */
                if(tok == ')')
                {
                    int ret = call_function(cfg, opt, &funcopt);
                    if(ret != 0)
                        return STATE_ERROR;
                    state = 0;
                }
                else if(tok == ',')
                    state = 8;
                else
                {
                    cfg_error(cfg, _("syntax error in call of function '%s'"),
                              opt->name);
                    return STATE_ERROR;
                }
                break;

            default:
                /* missing state, internal error, abort */
                assert(0);
        }
    }

    return STATE_EOF;
}
Beispiel #10
0
static cfg_value_t *cfg_setopt(cfg_t *cfg, cfg_opt_t *opt, char *value)
{
    cfg_value_t *val = 0;
    int b;
    char *s;
    double f;
    long int i;
    void *p;
    char *endptr;

    assert(cfg && opt);

    if(opt->simple_value)
    {
        assert(opt->type != CFGT_SEC);
        val = (cfg_value_t *)opt->simple_value;
    }
    else
    {
        if(is_set(CFGF_RESET, opt->flags))
        {
            cfg_free_value(opt);
            opt->flags &= ~CFGF_RESET;
        }

        if(opt->nvalues == 0 || is_set(CFGF_MULTI, opt->flags) ||
           is_set(CFGF_LIST, opt->flags))
        {
            val = 0;
            if(opt->type == CFGT_SEC && is_set(CFGF_TITLE, opt->flags))
            {
                unsigned int i;

                /* check if there already is a section with the same title
                 */
                assert(value);
                for(i = 0; i < opt->nvalues; i++)
                {
                    cfg_t *sec = opt->values[i]->section;
                    if(is_set(CFGF_NOCASE, cfg->flags))
                    {
                        if(strcasecmp(value, sec->title) == 0)
                            val = opt->values[i];
                    }
                    else
                    {
                        if(strcmp(value, sec->title) == 0)
                            val = opt->values[i];
                    }
                }
            }
            if(val == 0)
                val = cfg_addval(opt);
        }
        else
            val = opt->values[0];
    }

    switch(opt->type)
    {
        case CFGT_INT:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &i) != 0)
                    return 0;
                val->number = i;
            }
            else
            {
                val->number = strtol(value, &endptr, 0);
                if(*endptr != '\0')
                {
                    cfg_error(cfg, _("invalid integer value for option '%s'"),
                              opt->name);
                    return 0;
                }
                if(errno == ERANGE)
                {
                    cfg_error(cfg,
                          _("integer value for option '%s' is out of range"),
                              opt->name);
                    return 0;
                }
            }
            break;

        case CFGT_FLOAT:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &f) != 0)
                    return 0;
                val->fpnumber = f;
            }
            else
            {
                val->fpnumber = strtod(value, &endptr);
                if(*endptr != '\0')
                {
                    cfg_error(cfg,
                          _("invalid floating point value for option '%s'"),
                              opt->name);
                    return 0;
                }
                if(errno == ERANGE)
                {
                    cfg_error(cfg,
                  _("floating point value for option '%s' is out of range"),
                              opt->name);
                    return 0;
                }
            }
            break;

        case CFGT_STR:
            free(val->string);
            if(opt->parsecb)
            {
                s = 0;
                if((*opt->parsecb)(cfg, opt, value, &s) != 0)
                    return 0;
                val->string = strdup(s);
            }
            else
                val->string = strdup(value);
            break;

        case CFGT_SEC:
            if(is_set(CFGF_MULTI, opt->flags) || val->section == 0)
            {
                cfg_free(val->section);
                val->section = (cfg_t *)malloc(sizeof(cfg_t));
                assert(val->section);
                memset(val->section, 0, sizeof(cfg_t));
                val->section->name = strdup(opt->name);
                val->section->opts = cfg_dupopt_array(opt->subopts);
                val->section->flags = cfg->flags;
                val->section->filename = cfg->filename ? strdup(cfg->filename) : 0;
                val->section->line = cfg->line;
                val->section->errfunc = cfg->errfunc;
                val->section->title = value;
            }
            if(!is_set(CFGF_DEFINIT, opt->flags))
                cfg_init_defaults(val->section);
            break;

        case CFGT_BOOL:
            if(opt->parsecb)
            {
                if((*opt->parsecb)(cfg, opt, value, &b) != 0)
                    return 0;
            }
            else
            {
                b = cfg_parse_boolean(value);
                if(b == -1)
                {
                    cfg_error(cfg, _("invalid boolean value for option '%s'"),
                              opt->name);
                    return 0;
                }
            }
            val->boolean = (cfg_bool_t)b;
            break;

        case CFGT_PTR:
            assert(opt->parsecb);
            if((*opt->parsecb)(cfg, opt, value, &p) != 0)
                return 0;
            val->ptr = p;
            break;

        default:
            cfg_error(cfg, "internal error in cfg_setopt(%s, %s)",
                      opt->name, value);
            assert(0);
            break;
    }
    return val;
}