static bool parse_misc(struct wcore_config_attrs *attrs, const int32_t attrib_list[]) { for (int32_t i = 0; attrib_list[i]; i += 2) { int32_t key = attrib_list[i + 0]; int32_t value = attrib_list[i + 1]; switch (key) { #define CASE_INT(enum_name, struct_memb) \ case enum_name: \ if (value < -1) { \ wcore_errorf(WAFFLE_ERROR_BAD_ATTRIBUTE, \ #enum_name " has bad value %d", value); \ return false; \ } \ else { \ /* \ * Pass WAFFLE_DONT_CARE to platform module. \ * \ * From the GLX 1.4 (2005.12.16) spec: \ * GLX_DONT_CARE may be specified for all \ * attributes except GLX_LEVEL. \ * \ * From the EGL 1.4 (2011.04.06) spec: \ * EGL_DONT_CARE may be specified for all \ * attributes except EGL_LEVEL and \ * EGL_MATCH_NATIVE_PIXMAP. \ */ \ attrs->struct_memb = value; \ } \ break; #define CASE_BOOL(enum_name, struct_memb, default_value) \ case enum_name: \ if (!parse_bool(attrib_list, enum_name, \ &attrs->struct_memb, default_value)) { \ return false; \ } \ break; case WAFFLE_CONTEXT_API: case WAFFLE_CONTEXT_MAJOR_VERSION: case WAFFLE_CONTEXT_MINOR_VERSION: case WAFFLE_CONTEXT_PROFILE: case WAFFLE_CONTEXT_FORWARD_COMPATIBLE: // These keys have already been parsed. break; CASE_INT(WAFFLE_RED_SIZE, red_size) CASE_INT(WAFFLE_GREEN_SIZE, green_size) CASE_INT(WAFFLE_BLUE_SIZE, blue_size) CASE_INT(WAFFLE_ALPHA_SIZE, alpha_size) CASE_INT(WAFFLE_DEPTH_SIZE, depth_size) CASE_INT(WAFFLE_STENCIL_SIZE, stencil_size) CASE_INT(WAFFLE_SAMPLES, samples) CASE_BOOL(WAFFLE_CONTEXT_DEBUG, context_debug, false); CASE_BOOL(WAFFLE_SAMPLE_BUFFERS, sample_buffers, DEFAULT_SAMPLE_BUFFERS); CASE_BOOL(WAFFLE_DOUBLE_BUFFERED, double_buffered, DEFAULT_DOUBLE_BUFFERED); CASE_BOOL(WAFFLE_ACCUM_BUFFER, accum_buffer, DEFAULT_ACCUM_BUFFER); default: wcore_error_internal("%s", "bad attribute key should have " "been found by check_keys()"); return false; #undef CASE_INT #undef CASE_BOOL } } // Calculate rgb_size. attrs->rgb_size = 0; if (attrs->red_size != WAFFLE_DONT_CARE) attrs->rgb_size += attrs->red_size; if (attrs->green_size != WAFFLE_DONT_CARE) attrs->rgb_size += attrs->green_size; if (attrs->blue_size != WAFFLE_DONT_CARE) attrs->rgb_size += attrs->blue_size; // Calculate rgba_size. attrs->rgba_size = attrs->rgb_size; if (attrs->alpha_size != WAFFLE_DONT_CARE) attrs->rgba_size += attrs->alpha_size; return true; }
static int BuildWhere( media_library_t* p_ml, char **ppsz_where, ml_ftree_t* tree, char** sort, int* limit, const char** distinct, char*** pppsz_frompersons, int* i_frompersons, int* join ) { assert( ppsz_where && sort && distinct ); if( !tree ) /* Base case */ { return VLC_SUCCESS; } int i_ret = VLC_EGENERIC; char* psz_left = NULL; char* psz_right = NULL; switch( tree->op ) { case ML_OP_AND: case ML_OP_OR: i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ ); if( i_ret != VLC_SUCCESS ) goto parsefail; i_ret = BuildWhere( p_ml, &psz_right, tree->right, SLDPJ ); if( i_ret != VLC_SUCCESS ) goto parsefail; if( psz_left == NULL || psz_right == NULL ) { msg_Err( p_ml, "Parsing failed for AND/OR" ); i_ret = VLC_EGENERIC; goto parsefail; } if( asprintf( ppsz_where, "( %s %s %s )", psz_left, ( tree->op == ML_OP_AND ? "AND" : "OR" ), psz_right ) == -1 ) { i_ret = VLC_ENOMEM; goto parsefail; } break; case ML_OP_NOT: i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ ); if( i_ret != VLC_SUCCESS ) goto parsefail; if( psz_left == NULL ) { msg_Err( p_ml, "Parsing failed at NOT" ); i_ret = VLC_EGENERIC; goto parsefail; } if( asprintf( ppsz_where, "( NOT %s )", psz_left ) == -1 ) { i_ret = VLC_ENOMEM; goto parsefail; } break; case ML_OP_SPECIAL: i_ret = BuildWhere( p_ml, &psz_right, tree->right, SLDPJ ); if( i_ret != VLC_SUCCESS ) goto parsefail; i_ret = BuildWhere( p_ml, &psz_left, tree->left, SLDPJ ); if( i_ret != VLC_SUCCESS ) goto parsefail; /* Ignore right parse tree as this is a special node */ *ppsz_where = strdup( psz_left ? psz_left : "" ); if( !*ppsz_where ) { i_ret = VLC_ENOMEM; goto parsefail; } break; case ML_OP_NONE: switch( tree->criteria ) { case ML_PEOPLE: assert( tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_EQUAL || tree->comp == ML_COMP_STARTS_WITH || tree->comp == ML_COMP_ENDS_WITH ); *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "people%s%s.name LIKE '%s%q%s'", tree->lvalue.str ? "_" : "", tree->lvalue.str ? tree->lvalue.str : "", tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_STARTS_WITH ? "%%" : "", tree->value.str, tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_ENDS_WITH ? "%%" : "" ); if( *ppsz_where == NULL ) goto parsefail; *pppsz_frompersons = realloc( *pppsz_frompersons, ++*i_frompersons * sizeof( char* ) ); *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str; *join |= table_people; break; case ML_PEOPLE_ID: assert( tree->comp == ML_COMP_EQUAL ); *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "( people%s%s.id = %d )", tree->lvalue.str ? "_":"", tree->lvalue.str ? tree->lvalue.str:"", tree->value.i ); if( *ppsz_where == NULL ) goto parsefail; *pppsz_frompersons = realloc( *pppsz_frompersons, ++*i_frompersons * sizeof( char* ) ); *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str; *join |= table_people; break; case ML_PEOPLE_ROLE: assert( tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_EQUAL || tree->comp == ML_COMP_STARTS_WITH || tree->comp == ML_COMP_ENDS_WITH ); *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "people%s%s.role LIKE '%s%q%s'", tree->lvalue.str ? "_" : "", tree->lvalue.str ? tree->lvalue.str : "", tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_STARTS_WITH ? "%%" : "", tree->value.str, tree->comp == ML_COMP_HAS || tree->comp == ML_COMP_ENDS_WITH ? "%%" : "" ); if( *ppsz_where == NULL ) goto parsefail; *pppsz_frompersons = realloc( *pppsz_frompersons, ++*i_frompersons * sizeof( char* ) ); *pppsz_frompersons[ *i_frompersons - 1 ] = tree->lvalue.str; *join |= table_people; break; CASE_PSZ( ML_ALBUM, "album.title", table_album ); CASE_PSZ( ML_ALBUM_COVER, "album.cover", table_album ); case ML_ALBUM_ID: assert( tree->comp == ML_COMP_EQUAL ); *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "album.id = %d", tree->value.i ); if( *ppsz_where == NULL ) goto parsefail; *join |= table_album; break; CASE_PSZ( ML_COMMENT, "media.comment", table_media ); CASE_PSZ( ML_COVER, "media.cover", table_media ); CASE_INT( ML_DURATION, "media.duration", table_media ); CASE_PSZ( ML_EXTRA, "extra.extra", table_extra ); CASE_INT( ML_FILESIZE, "media.filesize", table_media ); CASE_PSZ( ML_GENRE, "media.genre", table_media ); case ML_ID: assert( tree->comp == ML_COMP_EQUAL ); *ppsz_where = sql_Printf( p_ml->p_sys->p_sql, "media.id = %d", tree->value.i ); if( *ppsz_where == NULL ) goto parsefail; *join |= table_media; break; CASE_PSZ( ML_LANGUAGE, "extra.language", table_extra ); CASE_INT( ML_LAST_PLAYED, "media.last_played", table_media ); CASE_PSZ( ML_ORIGINAL_TITLE, "media.original_title", table_media ); msg_Warn( p_ml, "Deprecated Played Count tags" ); CASE_INT( ML_PLAYED_COUNT, "media.played_count", table_media ); CASE_INT( ML_SCORE, "media.score", table_media ); CASE_PSZ( ML_TITLE, "media.title", table_media ); CASE_INT( ML_TRACK_NUMBER, "media.track", table_media); CASE_INT( ML_TYPE, "media.type", table_media ); CASE_PSZ( ML_URI, "media.uri", table_media ); CASE_INT( ML_VOTE, "media.vote", table_media ); CASE_INT( ML_YEAR, "media.year", table_media ); case ML_LIMIT: if( !*limit ) *limit = tree->value.i; else msg_Warn( p_ml, "Double LIMIT found" ); break; case ML_SORT_DESC: *sort = sql_Printf( p_ml->p_sys->p_sql, "%s%s%s DESC ", sort ? *sort : "", sort ? ", " : "", tree->value.str ); if( *sort == NULL ) goto parsefail; break; case ML_SORT_ASC: *sort = sql_Printf( p_ml->p_sys->p_sql, "%s%s%s ASC ", sort ? *sort : "", sort ? ", " : "", tree->value.str ); if( *sort == NULL ) goto parsefail; break; case ML_DISTINCT: if( !**distinct ) *distinct = "DISTINCT"; else msg_Warn( p_ml, "Double DISTINCT found!" ); break; default: msg_Err( p_ml, "Invalid select type or unsupported: %d", tree->criteria ); } break; default: msg_Err( p_ml, "Broken find tree!" ); i_ret = VLC_EGENERIC; goto parsefail; } i_ret = VLC_SUCCESS; parsefail: free( psz_left ); free( psz_right ); return i_ret; }