Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  chain.c   Sprache: C

 

/*****************************************************************************
 * chain.c : configuration module chain parsing stuff
 *****************************************************************************
 * Copyright (C) 2002-2007 VLC authors and VideoLAN
 *
 * Authors: Christophe Massiot <massiot@via.ecp.fr>
 *          Laurent Aimar <fenrir@via.ecp.fr>
 *          Eric Petit <titer@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


/*****************************************************************************
 * Preamble
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include "../libvlc.h"
#include <vlc_charset.h>
#include <vlc_plugin.h>

#include "vlc_interface.h"
#include "configuration.h"

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/

static bool IsEscapeNeeded( char c )
{
    return c == '\'' || c == '"' || c == '\\';
}
static bool IsEscape( const char *psz )
{
    if( !psz )
        return false;
    return psz[0] == '\\' && IsEscapeNeeded( psz[1] );
}
static bool IsSpace( char c  )
{
    return c == ' ' || c == '\t';
}

#define SKIPSPACE( p ) p += strspn( p, " \t" )
#define SKIPTRAILINGSPACE( p, e ) \
    do { while( e > p && IsSpace( *(e-1) ) ) e--; } while(0)

/**
 * This function will return a pointer after the end of a string element.
 * It will search the closing element which is
 * } for { (it will handle nested { ... })
 * " for "
 * ' for '
 */

static const char *ChainGetEnd( const char *psz_string )
{
    const char *p = psz_string;
    char c;

    if( !psz_string )
        return NULL;

    /* Look for a opening character */
    SKIPSPACE( p );

    for( ;; p++)
    {
        if( *p == '\0' || *p == ',' || *p == '}' )
            return p;

        if( *p == '{' || *p == '"' || *p == '\'' )
            break;
    }

    /* Set c to the closing character */
    if( *p == '{' )
        c = '}';
    else
        c = *p;
    p++;

    /* Search the closing character, handle nested {..} */
    for( ;; )
    {
        if( *p == '\0')
            return p;

        if( IsEscape( p ) )
            p += 2;
        else if( *p == c )
            return ++p;
        else if( *p == '{' && c == '}' )
            p = ChainGetEnd( p );
        else
            p++;
    }
}

/**
 * It will extract an option value (=... or {...}).
 * It will remove the initial = if present but keep the {}
 */

static char *ChainGetValue( const char **ppsz_string )
{
    const char *p = *ppsz_string;

    char *psz_value = NULL;
    const char *end;
    bool b_keep_brackets = (*p == '{');

    if( *p == '=' )
        p++;

    end = ChainGetEnd( p );
    if( end <= p )
    {
        psz_value = NULL;
    }
    else
    {
        /* Skip heading and trailing spaces.
         * This ain't necessary but will avoid simple
         * user mistakes. */

        SKIPSPACE( p );
    }

    if( end <= p )
    {
        psz_value = NULL;
    }
    else
    {
        if( *p == '\'' || *p == '"' || ( !b_keep_brackets && *p == '{' ) )
        {
            p++;

            if( *(end-1) != '\'' && *(end-1) == '"' )
                SKIPTRAILINGSPACE( p, end );

            if( end - 1 <= p )
                psz_value = NULL;
            else
                psz_value = strndup( p, end -1 - p );
        }
        else
        {
            SKIPTRAILINGSPACE( p, end );
            if( end <= p )
                psz_value = NULL;
            else
                psz_value = strndup( p, end - p );
        }
    }

    /* */
    if( psz_value )
        config_StringUnescape( psz_value );

    /* */
    *ppsz_string = end;
    return psz_value;
}

/* Parse all name=value[,] elements */
const char *config_ChainParseOptions( config_chain_t **pp_cfg, const char *psz_opts )
{
    config_chain_t **pp_next = pp_cfg;
    bool first = true;
    do
    {
        if (!first)
            psz_opts++; /* skip previous delimiter */
        SKIPSPACE( psz_opts );

        first = false;

        /* Look for the end of the name (,={}_space_) */
        size_t len = strcspn( psz_opts, "=,{} \t" );
        if( len == 0 )
            continue; /* ignore empty parameter */

        /* Append the new parameter */
        config_chain_t *p_cfg = malloc( sizeof(*p_cfg) );
        if( !p_cfg )
            break;
        p_cfg->psz_name = strndup( psz_opts, len );
        psz_opts += len;
        p_cfg->psz_value = NULL;
        p_cfg->p_next = NULL;

        *pp_next = p_cfg;
        pp_next = &p_cfg->p_next;

        /* Extract the option value */
        SKIPSPACE( psz_opts );
        if( strchr( "={", *psz_opts ) )
        {
            p_cfg->psz_value = ChainGetValue( &psz_opts );
            SKIPSPACE( psz_opts );
        }
    }
    while( !memchr( "}", *psz_opts, 2 ) );

    if( *psz_opts ) psz_opts++; /* skip '}' */;
    SKIPSPACE( psz_opts );

    return psz_opts;
}

char *config_ChainCreate( char **ppsz_name, config_chain_t **pp_cfg,
                          const char *psz_chain )
{
    size_t len;

    *ppsz_name = NULL;
    *pp_cfg    = NULL;

    if( !psz_chain )
        return NULL;
    SKIPSPACE( psz_chain );

    /* Look for parameter (a {...} or :...) or end of name (space or nul) */
    len = strcspn( psz_chain, "{: \t" );
    *ppsz_name = strndup( psz_chain, len );
    psz_chain += len;

    /* Parse the parameters */
    SKIPSPACE( psz_chain );
    if( *psz_chain == '{' )
        psz_chain = config_ChainParseOptions( pp_cfg, psz_chain );

    if( *psz_chain == ':' )
        return strdup( psz_chain + 1 );

    return NULL;
}

void config_ChainDestroy( config_chain_t *p_cfg )
{
    while( p_cfg != NULL )
    {
        config_chain_t *p_next;

        p_next = p_cfg->p_next;

        free( p_cfg->psz_name );
        free( p_cfg->psz_value );
        free( p_cfg );

        p_cfg = p_next;
    }
}

#undef config_ChainParse
void config_ChainParse( vlc_object_t *p_this, const char *psz_prefix,
                        const char *const *ppsz_options, const config_chain_t *cfg )
{
    if( psz_prefix == NULL ) psz_prefix = "";
    size_t plen = 1 + strlen( psz_prefix );

    /* First, var_Create all variables */
    for( size_t i = 0; ppsz_options[i] != NULL; i++ )
    {
        const char *optname = ppsz_options[i];
        if (optname[0] == '*')
            optname++;

        char name[plen + strlen( optname )];
        snprintf( name, sizeof (name), "%s%s", psz_prefix, optname );
        if( var_Create( p_this, name,
                        config_GetType( name ) | VLC_VAR_DOINHERIT ) )
            return /* VLC_xxx */;

        module_config_t* p_conf = config_FindConfig( name );
        if( p_conf )
        {
            switch( CONFIG_CLASS( p_conf->i_type ) )
            {
                case CONFIG_ITEM_INTEGER:
                    var_Change( p_this, name, VLC_VAR_SETMINMAX,
                        (vlc_value_t){ .i_int = p_conf->min.i },
                        (vlc_value_t){ .i_int = p_conf->max.i } );
                    break;
                case CONFIG_ITEM_FLOAT:
                    var_Change( p_this, name, VLC_VAR_SETMINMAX,
                        (vlc_value_t){ .f_float = p_conf->min.f },
                        (vlc_value_t){ .f_float = p_conf->max.f } );
                    break;
            }
        }
    }

    /* Now parse options and set value */
    for(; cfg; cfg = cfg->p_next )
    {
        vlc_value_t val;
        bool b_yes = true;
        bool b_once = false;
        size_t i;

        if( cfg->psz_name == NULL || *cfg->psz_name == '\0' )
            continue;

        for( i = 0; ppsz_options[i] != NULL; i++ )
        {
            if( !strcmp( ppsz_options[i], cfg->psz_name ) )
            {
                break;
            }
            if( ( !strncmp( cfg->psz_name, "no-", 3 ) &&
                  !strcmp( ppsz_options[i], cfg->psz_name + 3 ) ) ||
                ( !strncmp( cfg->psz_name, "no", 2 ) &&
                  !strcmp( ppsz_options[i], cfg->psz_name + 2 ) ) )
            {
                b_yes = false;
                break;
            }

            if( *ppsz_options[i] == '*' &&
                !strcmp( &ppsz_options[i][1], cfg->psz_name ) )
            {
                b_once = true;
                break;
            }

        }

        if( ppsz_options[i] == NULL )
        {
            msg_Warn( p_this, "option %s is unknown", cfg->psz_name );
            continue;
        }

        /* create name */
        char name[plen + strlen( ppsz_options[i] )];
        const char *psz_name = name;
        snprintf( name, sizeof (name), "%s%s", psz_prefix,
                  b_once ? (ppsz_options[i] + 1) : ppsz_options[i] );

        const struct vlc_param *param = vlc_param_Find(name);

        if (param == NULL)
        {
            msg_Warn(p_this, "unknown option %s", name);
            continue;
        }

        /* Check if the option is deprecated */
        /* This is basically cut and paste from src/misc/configuration.c
         * with slight changes */

        if (param->obsolete)
        {
            msg_Err(p_this, "Option %s is not supported any longer.", name);
            /* TODO: this should return an error and end option parsing
             * ... but doing this would change the VLC API and all the
             * modules so i'll do it later */

           continue;
        }

        /* get the type of the variable */
        const int i_type = CONFIG_CLASS(param->item.i_type);

        if( i_type != CONFIG_ITEM_BOOL && cfg->psz_value == NULL )
        {
            msg_Warn( p_this, "missing value for option %s", cfg->psz_name );
            continue;
        }
        if( i_type != CONFIG_ITEM_STRING && b_once )
        {
            msg_Warn( p_this, "*option_name need to be a string option" );
            continue;
        }

        switch( i_type )
        {
            case CONFIG_ITEM_BOOL:
                val.b_bool = b_yes;
                break;
            case CONFIG_ITEM_INTEGER:
                val.i_int = strtoll( cfg->psz_value ? cfg->psz_value : "0",
                                     NULL, 0 );
                break;
            case CONFIG_ITEM_FLOAT:
                val.f_float = vlc_atof_c( cfg->psz_value ? cfg->psz_value : "0" );
                break;
            case CONFIG_ITEM_STRING:
                val.psz_string = cfg->psz_value;
                break;
            default:
                msg_Warn( p_this, "unhandled config var type (%d)", i_type );
                memset( &val, 0, sizeof( vlc_value_t ) );
                break;
        }
        if( b_once )
        {
            vlc_value_t val2;

            var_Get( p_this, psz_name, &val2 );
            if( *val2.psz_string )
            {
                free( val2.psz_string );
                msg_Dbg( p_this, "ignoring option %s (not first occurrence)", psz_name );
                continue;
            }
            free( val2.psz_string );
        }
        var_Set( p_this, psz_name, val );
        msg_Dbg( p_this, "set config option: %s to %s", psz_name,
                 cfg->psz_value ? cfg->psz_value : "(null)" );
    }
}

config_chain_t *config_ChainDuplicate( const config_chain_t *p_src )
{
    config_chain_t *p_dst = NULL;
    config_chain_t **pp_last = &p_dst;

    for( ; p_src != NULL; p_src = p_src->p_next )
    {
        config_chain_t *p = malloc( sizeof(*p) );
        if( !p )
            break;
        p->p_next    = NULL;
        p->psz_name  = p_src->psz_name  ? strdup( p_src->psz_name )  : NULL;
        p->psz_value = p_src->psz_value ? strdup( p_src->psz_value ) : NULL;

        *pp_last = p;
        pp_last = &p->p_next;
    }
    return p_dst;
}

char *config_StringUnescape( char *psz_string )
{
    char *psz_src = psz_string;
    char *psz_dst = psz_string;
    if( !psz_src )
        return NULL;

    while( *psz_src )
    {
        if( IsEscape( psz_src ) )
            psz_src++;
        *psz_dst++ = *psz_src++;
    }
    *psz_dst = '\0';

    return psz_string;
}

char *config_StringEscape( const char *str )
{
    size_t length = 0;

    if( str == NULL )
        return NULL;

    for( const char *p = str; *p; p++ )
        length += IsEscapeNeeded( *p ) ? 2 : 1;

    char *ret = malloc( length + 1 ), *dst = ret;

    if( unlikely( !ret ) )
        return NULL;

    for( const char *p = str; *p; p++ )
    {
        if( IsEscapeNeeded( *p ) )
            *dst++ = '\\';
        *dst++ = *p;
    }
    *dst = '\0';
    return ret;
}

Messung
CHZG
829710093

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104848
#Domains=416966