Code Search for Developers
 
 
  

m_config.c from The Open2x Project at Krugle


Show m_config.c syntax highlighted

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef MP_DEBUG
#    include <assert.h>
#endif

#include "m_config.h"
#include "m_option.h"
#include "mp_msg.h"
#include "help_mp.h"

m_config_t     *
m_config_new(void)
{
    m_config_t     *config;

    config = (m_config_t *) calloc(1, sizeof(m_config_t));
    config->lvl = 1;            // 0 Is the defaults
    return config;
}

void
m_config_free(m_config_t * config)
{
    m_config_option_t *i = config->opts,
        *ct;
    m_config_save_slot_t *sl,
                   *st;

#ifdef MP_DEBUG
    assert(config != NULL);
#endif

    while (i)
    {
        if (i->flags & M_CFG_OPT_ALIAS)
            sl = NULL;
        else
            sl = i->slots;
        while (sl)
        {
            m_option_free(i->opt, sl->data);
            st = sl->prev;
            free(sl);
            sl = st;
        }
        if (i->name != i->opt->name)
            free(i->name);
        ct = i->next;
        free(i);
        i = ct;
    }
    free(config);
}

void
m_config_push(m_config_t * config)
{
    m_config_option_t *co;
    m_config_save_slot_t *slot;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 0);
#endif

    config->lvl++;

    for (co = config->opts; co; co = co->next)
    {
        if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
            continue;
        if (co->opt->flags & (M_OPT_GLOBAL | M_OPT_NOSAVE))
            continue;
        if ((co->opt->flags & M_OPT_OLD) && !(co->flags && M_CFG_OPT_SET))
            continue;
        if (co->flags & M_CFG_OPT_ALIAS)
            continue;

        // Update the current status
        m_option_save(co->opt, co->slots->data, co->opt->p);

        // Allocate a new slot 
        slot = (m_config_save_slot_t *) calloc(1, sizeof(m_config_save_slot_t) + co->opt->type->size);
        slot->lvl = config->lvl;
        slot->prev = co->slots;
        co->slots = slot;
        m_option_copy(co->opt, co->slots->data, co->slots->prev->data);
        // Reset our set flag
        co->flags &= ~M_CFG_OPT_SET;
    }

    mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Config pushed level is now %d\n", config->lvl);
}

void
m_config_pop(m_config_t * config)
{
    m_config_option_t *co;
    m_config_save_slot_t *slot;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 1);
#endif

    for (co = config->opts; co; co = co->next)
    {
        int             pop = 0;

        if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
            continue;
        if (co->opt->flags & (M_OPT_GLOBAL | M_OPT_NOSAVE))
            continue;
        if (co->flags & M_CFG_OPT_ALIAS)
            continue;
        if (co->slots->lvl > config->lvl)
            mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_SaveSlotTooOld, config->lvl, co->slots->lvl);

        while (co->slots->lvl >= config->lvl)
        {
            m_option_free(co->opt, co->slots->data);
            slot = co->slots;
            co->slots = slot->prev;
            free(slot);
            pop++;
        }
        if (pop)                // We removed some ctx -> set the previous value
            m_option_set(co->opt, co->opt->p, co->slots->data);
    }

    config->lvl--;
    mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Config poped level=%d\n", config->lvl);
}

static void
m_config_add_option(m_config_t * config, m_option_t * arg, char *prefix)
{
    m_config_option_t *co;
    m_config_save_slot_t *sl;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 0);
    assert(arg != NULL);
#endif

    // Allocate a new entry for this option
    co = (m_config_option_t *) calloc(1, sizeof(m_config_option_t) + arg->type->size);
    co->opt = arg;

    // Fill in the full name
    if (prefix && strlen(prefix) > 0)
    {
        int             l = strlen(prefix) + 1 + strlen(arg->name) + 1;

        co->name = (char *) malloc(l);
        sprintf(co->name, "%s:%s", prefix, arg->name);
    }
    else
        co->name = arg->name;

    // Option with childs -> add them
    if (arg->type->flags & M_OPT_TYPE_HAS_CHILD)
    {
        m_option_t     *ol = arg->p;
        int             i;

        co->slots = NULL;
        for (i = 0; ol[i].name != NULL; i++)
            m_config_add_option(config, &ol[i], co->name);
    }
    else
    {
        m_config_option_t *i;

        // Check if there is alredy an option pointing to this address
        if (arg->p)
        {
            for (i = config->opts; i; i = i->next)
            {
                if (i->opt->p == arg->p)
                {               // So we don't save the same vars more than 1 time
                    co->slots = i->slots;
                    co->flags |= M_CFG_OPT_ALIAS;
                    break;
                }
            }
        }
        if (!(co->flags & M_CFG_OPT_ALIAS))
        {
            // Allocate a slot for the defaults
            sl = (m_config_save_slot_t *) calloc(1, sizeof(m_config_save_slot_t) + arg->type->size);
            m_option_save(arg, sl->data, (void **) arg->p);
            // Hack to avoid too much trouble with dynamicly allocated data :
            // We always use a dynamic version
            if ((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void **) arg->p))
            {
                *(void **) arg->p = NULL;
                m_option_set(arg, arg->p, sl->data);
            }
            sl->lvl = 0;
            sl->prev = NULL;
            co->slots = (m_config_save_slot_t *) calloc(1, sizeof(m_config_save_slot_t) + arg->type->size);
            co->slots->prev = sl;
            co->slots->lvl = config->lvl;
            m_option_copy(co->opt, co->slots->data, sl->data);
        }                       // !M_OPT_ALIAS
    }
    co->next = config->opts;
    config->opts = co;
}

int
m_config_register_options(m_config_t * config, m_option_t * args)
{
    int             i;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 0);
    assert(args != NULL);
#endif

    for (i = 0; args[i].name != NULL; i++)
        m_config_add_option(config, &args[i], NULL);

    return 1;
}

static m_config_option_t *
m_config_get_co(m_config_t * config, char *arg)
{
    m_config_option_t *co;

    for (co = config->opts; co; co = co->next)
    {
        int             l = strlen(co->name) - 1;

        if ((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && (co->name[l] == '*'))
        {
            if (strncasecmp(co->name, arg, l) == 0)
                return co;
        }
        else if (strcasecmp(co->name, arg) == 0)
            return co;
    }
    return NULL;
}

static int
m_config_parse_option(m_config_t * config, char *arg, char *param, int set)
{
    m_config_option_t *co;
    int             r = 0;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 0);
    assert(arg != NULL);
#endif

    co = m_config_get_co(config, arg);
    if (!co)
    {
//    mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Unknown option: %s\n",arg);
        return M_OPT_UNKNOWN;
    }

#ifdef MP_DEBUG
    // This is the only mandatory function
    assert(co->opt->type->parse);
#endif

    // Check if this option isn't forbiden in the current mode
    if ((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG))
    {
        mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_InvalidCfgfileOption, arg);
        return M_OPT_INVALID;
    }
    if ((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD))
    {
        mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_InvalidCmdlineOption, arg);
        return M_OPT_INVALID;
    }

    // Option with childs are a bit different to parse
    if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
    {
        char          **lst = NULL;
        int             i,
                        sr;

        // Parse the child options
        r = m_option_parse(co->opt, arg, param, &lst, M_COMMAND_LINE);
        // Set them now
        if (r >= 0)
            for (i = 0; lst && lst[2 * i]; i++)
            {
                int             l = strlen(co->name) + 1 + strlen(lst[2 * i]) + 1;

                if (r >= 0)
                {
                    // Build the full name
                    char            n[l];

                    sprintf(n, "%s:%s", co->name, lst[2 * i]);
                    sr = m_config_parse_option(config, n, lst[2 * i + 1], set);
                    if (sr < 0)
                    {
                        if (sr == M_OPT_UNKNOWN)
                        {
                            mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_InvalidSuboption, co->name, lst[2 * i]);
                            r = M_OPT_INVALID;
                        }
                        else if (sr == M_OPT_MISSING_PARAM)
                        {
                            mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_MissingSuboptionParameter, lst[2 * i], co->name);
                            r = M_OPT_INVALID;
                        }
                        else
                            r = sr;
                    }
                }
                free(lst[2 * i]);
                free(lst[2 * i + 1]);
            }
        if (lst)
            free(lst);
    }
    else
        r = m_option_parse(co->opt, arg, param, set ? co->slots->data : NULL, config->mode);

    // Parsing failed ?
    if (r < 0)
        return r;
    // Set the option
    if (set)
    {
        m_option_set(co->opt, co->opt->p, co->slots->data);
        co->flags |= M_CFG_OPT_SET;
    }

    return r;
}

int
m_config_set_option(m_config_t * config, char *arg, char *param)
{
    mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting %s=%s\n", arg, param);
    return m_config_parse_option(config, arg, param, 1);
}

int
m_config_check_option(m_config_t * config, char *arg, char *param)
{
    int             r;

    mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Checking %s=%s\n", arg, param);
    r = m_config_parse_option(config, arg, param, 0);
    if (r == M_OPT_MISSING_PARAM)
    {
        mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_MissingOptionParameter, arg);
        return M_OPT_INVALID;
    }
    return r;
}


m_option_t     *
m_config_get_option(m_config_t * config, char *arg)
{
    m_config_option_t *co;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(config->lvl > 0);
    assert(arg != NULL);
#endif

    co = m_config_get_co(config, arg);
    if (co)
        return co->opt;
    else
        return NULL;
}

void           *
m_config_get_option_ptr(m_config_t * config, char *arg)
{
    m_option_t     *conf;

#ifdef MP_DEBUG
    assert(config != NULL);
    assert(arg != NULL);
#endif

    conf = m_config_get_option(config, arg);
    if (!conf)
        return NULL;
    return conf->p;
}

void
m_config_print_option_list(m_config_t * config)
{
    char            min[50],
                    max[50];
    m_config_option_t *co;
    int             count = 0;

    if (!config->opts)
        return;

    mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_OptionListHeader);
    for (co = config->opts; co; co = co->next)
    {
        m_option_t     *opt = co->opt;

        if (opt->type->flags & M_OPT_TYPE_HAS_CHILD)
            continue;
        if (opt->flags & M_OPT_MIN)
            sprintf(min, "%-8.0f", opt->min);
        else
            strcpy(min, "No");
        if (opt->flags & M_OPT_MAX)
            sprintf(max, "%-8.0f", opt->max);
        else
            strcpy(max, "No");
        mp_msg(MSGT_FIXME, MSGL_FIXME, " %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s   %-3.3s   %-3.3s\n",
               co->name, co->opt->type->name, min, max, opt->flags & CONF_GLOBAL ? "Yes" : "No", opt->flags & CONF_NOCMD ? "No" : "Yes", opt->flags & CONF_NOCFG ? "No" : "Yes");
        count++;
    }
    mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_TotalOptions, count);
}




See more files for this project here

The Open2x Project

The Open2x project exists to provide an open source resource for the GP2X handheld console based on the MagicEyes MMSP2 processing platform and MP2520F SoC. The project hosts Linux kernel source for the GP2X, boot loader (U-Boot) source and more.

Project homepage: http://www.distant-earth.com/open2x
Programming language(s): Assembly,C,C++
License: other

  default_skin/
    asf.png
    avi.png
    body.png
    dat.png
    downarrow.png
    error.png
    ext.png
    ext_on.png
    folder.png
    full.png
    loading.png
    mpg.png
    nand.png
    nand_on.png
    normal.png
    resume.png
    save.png
    sd.png
    sd_on.png
    selectbar.png
    uparrow.png
    wmv.png
  etc/
    codecs.conf
    dvb-menu.conf
    example.conf
    input.conf
    inttypes.h
    menu.conf
    mplayer.desktop
    mplayer.ico
  fbdisp/
    Makefile
    fblin16.c
    fblin24.c
    fblin32.c
    fbs.h
    fontdisp.h
    fontout.c
    gfxdev.h
    gfxfontext.c
    gfxfontload.c
    gfxfontout.c
    gfxtype.h
    gulim_96_10_eng.c
    gulim_96_10_han.c
    main.c
    scr_fb.c
  help/
    help_diff.sh
    help_mp-bg.h
    help_mp-cs.h
    help_mp-de.h
    help_mp-dk.h
    help_mp-el.h
    help_mp-en.h
    help_mp-es.h
    help_mp-fr.h
    help_mp-hu.h
    help_mp-it.h
    help_mp-ja.h
    help_mp-ko.h
    help_mp-mk.h
    help_mp-nl.h
    help_mp-no.h
    help_mp-pl.h
    help_mp-pt_BR.h
    help_mp-ro.h
    help_mp-ru.h
  libaf/
  libao2/
  libmpcodecs/
  libmpdemux/
  loader/
  osdep/
  AUTHORS
  DirDisplay.c
  DirDisplay.h
  DirList.c
  DirList.h
  FontDisplay.c
  FontDisplay.h
  LICENSE
  Makefile
  bswap.h
  codec-cfg.c
  codec-cfg.h
  config.h
  config.mak
  csource.lst
  cx25874.h
  drawcontrol.c
  drawcontrol.h
  dualcpu.h
  filelistview.c
  filelistview.h
  find_sub.c
  g2player.h
  get_path.c
  glock.c
  glock.h
  guictrl.c
  guictrl.h
  gv.c
  gvlib_export.h
  help_mp.h
  i2c.h
  imgNumber.h
  imgbinary.h
  m_config.c
  m_config.h
  m_option.c
  m_option.h
  m_struct.c
  m_struct.h
  mangle.h
  mixer.c
  mixer.h
  mmsp2_940_if.c
  mmsp2_if.h
  mp_msg.c
  mp_msg.h
  mplayer.c
  mplayer.h
  open2x-mplayer.sh
  rtc_1024_table.h
  subdisp.c
  subdisp.h
  subreader.c
  subreader.h
  typed.h
  version.h
  vpp.h
  vpts_q.c
  wincetype.h