X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fhttp%2Frpn.c;h=982d4556b8af059df19b6f33d6187e1b1795fca9;hb=2709abbb60aeeba299d9cab347cda64f635c2b26;hp=1fbb1e0e4af769d6b8a64e79cad86a3ae31d3019;hpb=2cb472dba008f7d877ffe6bae9c5575253365282;p=vlc diff --git a/modules/control/http/rpn.c b/modules/control/http/rpn.c index 1fbb1e0e4a..982d4556b8 100644 --- a/modules/control/http/rpn.c +++ b/modules/control/http/rpn.c @@ -1,7 +1,7 @@ /***************************************************************************** * rpn.c : RPN evaluator for the HTTP Interface ***************************************************************************** - * Copyright (C) 2001-2005 the VideoLAN team + * Copyright (C) 2001-2006 the VideoLAN team * $Id$ * * Authors: Gildas Bazin @@ -22,22 +22,26 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include "http.h" +#include "vlc_url.h" +#include "vlc_meta.h" +#include "vlc_strings.h" static vlc_object_t *GetVLCObject( intf_thread_t *p_intf, const char *psz_object, - vlc_bool_t *pb_need_release ) + bool *pb_need_release ) { intf_sys_t *p_sys = p_intf->p_sys; int i_object_type = 0; vlc_object_t *p_object = NULL; - *pb_need_release = VLC_FALSE; + *pb_need_release = false; - if( !strcmp( psz_object, "VLC_OBJECT_ROOT" ) ) - i_object_type = VLC_OBJECT_ROOT; - else if( !strcmp( psz_object, "VLC_OBJECT_VLC" ) ) - p_object = VLC_OBJECT(p_intf->p_vlc); + if( !strcmp( psz_object, "VLC_OBJECT_LIBVLC" ) ) + p_object = VLC_OBJECT(p_intf->p_libvlc); else if( !strcmp( psz_object, "VLC_OBJECT_INTF" ) ) p_object = VLC_OBJECT(p_intf); else if( !strcmp( psz_object, "VLC_OBJECT_PLAYLIST" ) ) @@ -48,26 +52,24 @@ static vlc_object_t *GetVLCObject( intf_thread_t *p_intf, i_object_type = VLC_OBJECT_VOUT; else if( !strcmp( psz_object, "VLC_OBJECT_AOUT" ) ) i_object_type = VLC_OBJECT_AOUT; - else if( !strcmp( psz_object, "VLC_OBJECT_SOUT" ) ) - i_object_type = VLC_OBJECT_SOUT; else msg_Warn( p_intf, "unknown object type (%s)", psz_object ); if( p_object == NULL && i_object_type ) { - *pb_need_release = VLC_TRUE; + *pb_need_release = true; p_object = vlc_object_find( p_intf, i_object_type, FIND_ANYWHERE ); } return p_object; } -void E_(SSInit)( rpn_stack_t *st ) +void SSInit( rpn_stack_t *st ) { st->i_stack = 0; } -void E_(SSClean)( rpn_stack_t *st ) +void SSClean( rpn_stack_t *st ) { while( st->i_stack > 0 ) { @@ -75,7 +77,7 @@ void E_(SSClean)( rpn_stack_t *st ) } } -void E_(SSPush)( rpn_stack_t *st, const char *s ) +void SSPush( rpn_stack_t *st, const char *s ) { if( st->i_stack < STACK_MAX ) { @@ -83,7 +85,7 @@ void E_(SSPush)( rpn_stack_t *st, const char *s ) } } -char *E_(SSPop)( rpn_stack_t *st ) +char *SSPop( rpn_stack_t *st ) { if( st->i_stack <= 0 ) { @@ -95,7 +97,7 @@ char *E_(SSPop)( rpn_stack_t *st ) } } -int E_(SSPopN)( rpn_stack_t *st, mvar_t *vars ) +int SSPopN( rpn_stack_t *st, mvar_t *vars ) { char *name; char *value; @@ -103,11 +105,11 @@ int E_(SSPopN)( rpn_stack_t *st, mvar_t *vars ) char *end; int i; - name = E_(SSPop)( st ); + name = SSPop( st ); i = strtol( name, &end, 0 ); if( end == name ) { - value = E_(mvar_GetValue)( vars, name ); + value = mvar_GetValue( vars, name ); i = atoi( value ); } free( name ); @@ -115,15 +117,15 @@ int E_(SSPopN)( rpn_stack_t *st, mvar_t *vars ) return( i ); } -void E_(SSPushN)( rpn_stack_t *st, int i ) +void SSPushN( rpn_stack_t *st, int i ) { - char v[512]; + char v[12]; - sprintf( v, "%d", i ); - E_(SSPush)( st, v ); + snprintf( v, sizeof (v), "%d", i ); + SSPush( st, v ); } -void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, +void EvaluateRPN( intf_thread_t *p_intf, mvar_t *vars, rpn_stack_t *st, char *exp ) { intf_sys_t *p_sys = p_intf->p_sys; @@ -141,14 +143,14 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, if( *exp == '\'' ) { /* extract string */ - p = E_(FirstWord)( exp, exp ); - E_(SSPush)( st, exp ); + p = FirstWord( exp, exp ); + SSPush( st, exp ); exp = p; continue; } /* extract token */ - p = E_(FirstWord)( exp, exp ); + p = FirstWord( exp, exp ); s = exp; if( p == NULL ) { @@ -167,129 +169,129 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, /* 1. Integer function */ if( !strcmp( s, "!" ) ) { - E_(SSPushN)( st, ~E_(SSPopN)( st, vars ) ); + SSPushN( st, ~SSPopN( st, vars ) ); } else if( !strcmp( s, "^" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) ^ E_(SSPopN)( st, vars ) ); + SSPushN( st, SSPopN( st, vars ) ^ SSPopN( st, vars ) ); } else if( !strcmp( s, "&" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) & E_(SSPopN)( st, vars ) ); + SSPushN( st, SSPopN( st, vars ) & SSPopN( st, vars ) ); } else if( !strcmp( s, "|" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) | E_(SSPopN)( st, vars ) ); + SSPushN( st, SSPopN( st, vars ) | SSPopN( st, vars ) ); } else if( !strcmp( s, "+" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) + E_(SSPopN)( st, vars ) ); + SSPushN( st, SSPopN( st, vars ) + SSPopN( st, vars ) ); } else if( !strcmp( s, "-" ) ) { - int j = E_(SSPopN)( st, vars ); - int i = E_(SSPopN)( st, vars ); - E_(SSPushN)( st, i - j ); + int j = SSPopN( st, vars ); + int i = SSPopN( st, vars ); + SSPushN( st, i - j ); } else if( !strcmp( s, "*" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) * E_(SSPopN)( st, vars ) ); + SSPushN( st, SSPopN( st, vars ) * SSPopN( st, vars ) ); } else if( !strcmp( s, "/" ) ) { int i, j; - j = E_(SSPopN)( st, vars ); - i = E_(SSPopN)( st, vars ); + j = SSPopN( st, vars ); + i = SSPopN( st, vars ); - E_(SSPushN)( st, j != 0 ? i / j : 0 ); + SSPushN( st, j != 0 ? i / j : 0 ); } else if( !strcmp( s, "%" ) ) { int i, j; - j = E_(SSPopN)( st, vars ); - i = E_(SSPopN)( st, vars ); + j = SSPopN( st, vars ); + i = SSPopN( st, vars ); - E_(SSPushN)( st, j != 0 ? i % j : 0 ); + SSPushN( st, j != 0 ? i % j : 0 ); } /* 2. integer tests */ else if( !strcmp( s, "=" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) == E_(SSPopN)( st, vars ) ? -1 : 0 ); + SSPushN( st, SSPopN( st, vars ) == SSPopN( st, vars ) ? -1 : 0 ); } else if( !strcmp( s, "!=" ) ) { - E_(SSPushN)( st, E_(SSPopN)( st, vars ) != E_(SSPopN)( st, vars ) ? -1 : 0 ); + SSPushN( st, SSPopN( st, vars ) != SSPopN( st, vars ) ? -1 : 0 ); } else if( !strcmp( s, "<" ) ) { - int j = E_(SSPopN)( st, vars ); - int i = E_(SSPopN)( st, vars ); + int j = SSPopN( st, vars ); + int i = SSPopN( st, vars ); - E_(SSPushN)( st, i < j ? -1 : 0 ); + SSPushN( st, i < j ? -1 : 0 ); } else if( !strcmp( s, ">" ) ) { - int j = E_(SSPopN)( st, vars ); - int i = E_(SSPopN)( st, vars ); + int j = SSPopN( st, vars ); + int i = SSPopN( st, vars ); - E_(SSPushN)( st, i > j ? -1 : 0 ); + SSPushN( st, i > j ? -1 : 0 ); } else if( !strcmp( s, "<=" ) ) { - int j = E_(SSPopN)( st, vars ); - int i = E_(SSPopN)( st, vars ); + int j = SSPopN( st, vars ); + int i = SSPopN( st, vars ); - E_(SSPushN)( st, i <= j ? -1 : 0 ); + SSPushN( st, i <= j ? -1 : 0 ); } else if( !strcmp( s, ">=" ) ) { - int j = E_(SSPopN)( st, vars ); - int i = E_(SSPopN)( st, vars ); + int j = SSPopN( st, vars ); + int i = SSPopN( st, vars ); - E_(SSPushN)( st, i >= j ? -1 : 0 ); + SSPushN( st, i >= j ? -1 : 0 ); } /* 3. string functions */ else if( !strcmp( s, "strcat" ) ) { - char *s2 = E_(SSPop)( st ); - char *s1 = E_(SSPop)( st ); + char *s2 = SSPop( st ); + char *s1 = SSPop( st ); char *str = malloc( strlen( s1 ) + strlen( s2 ) + 1 ); strcpy( str, s1 ); strcat( str, s2 ); - E_(SSPush)( st, str ); + SSPush( st, str ); free( s1 ); free( s2 ); free( str ); } else if( !strcmp( s, "strcmp" ) ) { - char *s2 = E_(SSPop)( st ); - char *s1 = E_(SSPop)( st ); + char *s2 = SSPop( st ); + char *s1 = SSPop( st ); - E_(SSPushN)( st, strcmp( s1, s2 ) ); + SSPushN( st, strcmp( s1, s2 ) ); free( s1 ); free( s2 ); } else if( !strcmp( s, "strncmp" ) ) { - int n = E_(SSPopN)( st, vars ); - char *s2 = E_(SSPop)( st ); - char *s1 = E_(SSPop)( st ); + int n = SSPopN( st, vars ); + char *s2 = SSPop( st ); + char *s1 = SSPop( st ); - E_(SSPushN)( st, strncmp( s1, s2 , n ) ); + SSPushN( st, strncmp( s1, s2 , n ) ); free( s1 ); free( s2 ); } else if( !strcmp( s, "strsub" ) ) { - int n = E_(SSPopN)( st, vars ); - int m = E_(SSPopN)( st, vars ); + int n = SSPopN( st, vars ); + int m = SSPopN( st, vars ); int i_len; - char *s = E_(SSPop)( st ); + char *s = SSPop( st ); char *str; if( n >= m ) @@ -306,22 +308,22 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, memcpy( str, s + m - 1, i_len ); str[ i_len ] = '\0'; - E_(SSPush)( st, str ); + SSPush( st, str ); free( s ); free( str ); } else if( !strcmp( s, "strlen" ) ) { - char *str = E_(SSPop)( st ); + char *str = SSPop( st ); - E_(SSPushN)( st, strlen( str ) ); + SSPushN( st, strlen( str ) ); free( str ); } else if( !strcmp( s, "str_replace" ) ) { - char *psz_to = E_(SSPop)( st ); - char *psz_from = E_(SSPop)( st ); - char *psz_in = E_(SSPop)( st ); + char *psz_to = SSPop( st ); + char *psz_from = SSPop( st ); + char *psz_in = SSPop( st ); char *psz_in_current = psz_in; char *psz_out = malloc( strlen(psz_in) * strlen(psz_to) + 1 ); char *psz_out_current = psz_out; @@ -338,7 +340,7 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, psz_out_current += strlen(psz_in_current); *psz_out_current = '\0'; - E_(SSPush)( st, psz_out ); + SSPush( st, psz_out ); free( psz_to ); free( psz_from ); free( psz_in ); @@ -346,34 +348,31 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } else if( !strcmp( s, "url_extract" ) ) { - char *url = E_(mvar_GetValue)( vars, "url_value" ); - char *name = E_(SSPop)( st ); - char value[512]; - char *tmp; + char *url = mvar_GetValue( vars, "url_value" ); + char *name = SSPop( st ); + char *value = ExtractURIString( url, name ); + if( value != NULL ) + { + decode_URI( value ); + SSPush( st, value ); + free( value ); + } + else + SSPush( st, "" ); - E_(ExtractURIValue)( url, name, value, 512 ); - E_(DecodeEncodedURI)( value ); - tmp = E_(FromUTF8)( p_intf, value ); - E_(SSPush)( st, tmp ); - free( tmp ); free( name ); } else if( !strcmp( s, "url_encode" ) ) { - char *url = E_(SSPop)( st ); - char *value; - - value = E_(ToUTF8)( p_intf, url ); - free( url ); - url = value; - value = vlc_UrlEncode( url ); + char *url = SSPop( st ); + char *value = vlc_UrlEncode( url ); free( url ); - E_(SSPush)( st, value ); + SSPush( st, value ); free( value ); } else if( !strcmp( s, "addslashes" ) ) { - char *psz_src = E_(SSPop)( st ); + char *psz_src = SSPop( st ); char *psz_dest; char *str = psz_src; @@ -390,169 +389,135 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } *p = '\0'; - E_(SSPush)( st, psz_dest ); + SSPush( st, psz_dest ); free( psz_src ); free( psz_dest ); } else if( !strcmp( s, "stripslashes" ) ) { - char *psz_src = E_(SSPop)( st ); + char *psz_src = SSPop( st ); char *psz_dest; + char *str = psz_src; p = psz_dest = strdup( psz_src ); - while( *psz_src ) + while( *str ) { - if( *psz_src == '\\' && *(psz_src + 1) ) + if( *str == '\\' && *(str + 1) ) { - psz_src++; + str++; } - *p++ = *psz_src++; + *p++ = *str++; } *p = '\0'; - E_(SSPush)( st, psz_dest ); + SSPush( st, psz_dest ); free( psz_src ); free( psz_dest ); } else if( !strcmp( s, "htmlspecialchars" ) ) { - char *psz_src = E_(SSPop)( st ); + char *psz_src = SSPop( st ); char *psz_dest; - char *str = psz_src; - p = psz_dest = malloc( strlen( str ) * 6 + 1 ); + psz_dest = convert_xml_special_chars( psz_src ); - while( *str != '\0' ) - { - if( *str == '&' ) - { - strcpy( p, "&" ); - p += 5; - } - else if( *str == '\"' ) - { - strcpy( p, """ ); - p += 6; - } - else if( *str == '\'' ) - { - strcpy( p, "'" ); - p += 6; - } - else if( *str == '<' ) - { - strcpy( p, "<" ); - p += 4; - } - else if( *str == '>' ) - { - strcpy( p, ">" ); - p += 4; - } - else - { - *p++ = *str; - } - str++; - } - *p = '\0'; - - E_(SSPush)( st, psz_dest ); + SSPush( st, psz_dest ); free( psz_src ); free( psz_dest ); } else if( !strcmp( s, "realpath" ) ) { - char *psz_src = E_(SSPop)( st ); - char *psz_dir = E_(RealPath)( p_intf, psz_src ); + char *psz_src = SSPop( st ); + char *psz_dir = RealPath( p_intf, psz_src ); - E_(SSPush)( st, psz_dir ); + SSPush( st, psz_dir ); free( psz_src ); free( psz_dir ); } /* 4. stack functions */ else if( !strcmp( s, "dup" ) ) { - char *str = E_(SSPop)( st ); - E_(SSPush)( st, str ); - E_(SSPush)( st, str ); + char *str = SSPop( st ); + SSPush( st, str ); + SSPush( st, str ); free( str ); } else if( !strcmp( s, "drop" ) ) { - char *str = E_(SSPop)( st ); + char *str = SSPop( st ); free( str ); } else if( !strcmp( s, "swap" ) ) { - char *s1 = E_(SSPop)( st ); - char *s2 = E_(SSPop)( st ); + char *s1 = SSPop( st ); + char *s2 = SSPop( st ); - E_(SSPush)( st, s1 ); - E_(SSPush)( st, s2 ); + SSPush( st, s1 ); + SSPush( st, s2 ); free( s1 ); free( s2 ); } else if( !strcmp( s, "flush" ) ) { - E_(SSClean)( st ); - E_(SSInit)( st ); + SSClean( st ); + SSInit( st ); } else if( !strcmp( s, "store" ) ) { - char *value = E_(SSPop)( st ); - char *name = E_(SSPop)( st ); + char *value = SSPop( st ); + char *name = SSPop( st ); - E_(mvar_PushNewVar)( vars, name, value ); + mvar_PushNewVar( vars, name, value ); free( name ); free( value ); } else if( !strcmp( s, "value" ) ) { - char *name = E_(SSPop)( st ); - char *value = E_(mvar_GetValue)( vars, name ); + char *name = SSPop( st ); + char *value = mvar_GetValue( vars, name ); - E_(SSPush)( st, value ); + SSPush( st, value ); free( name ); } /* 5. player control */ else if( !strcmp( s, "vlc_play" ) ) { - int i_id = E_(SSPopN)( st, vars ); + int i_id = SSPopN( st, vars ); int i_ret; - i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_ITEMPLAY, + i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY, + true, NULL, playlist_ItemGetById( p_sys->p_playlist, - i_id ) ); + i_id, true ) ); msg_Dbg( p_intf, "requested playlist item: %i", i_id ); - E_(SSPushN)( st, i_ret ); + SSPushN( st, i_ret ); } else if( !strcmp( s, "vlc_stop" ) ) { - playlist_Control( p_sys->p_playlist, PLAYLIST_STOP ); + playlist_Control( p_sys->p_playlist, PLAYLIST_STOP, true ); msg_Dbg( p_intf, "requested playlist stop" ); } else if( !strcmp( s, "vlc_pause" ) ) { - playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE ); + playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE, true ); msg_Dbg( p_intf, "requested playlist pause" ); } else if( !strcmp( s, "vlc_next" ) ) { - playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, 1 ); + playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, true, 1 ); msg_Dbg( p_intf, "requested playlist next" ); } else if( !strcmp( s, "vlc_previous" ) ) { - playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, -1 ); + playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, true, -1 ); msg_Dbg( p_intf, "requested playlist previous" ); } else if( !strcmp( s, "vlc_seek" ) ) { - char *psz_value = E_(SSPop)( st ); - E_(HandleSeek)( p_intf, psz_value ); + char *psz_value = SSPop( st ); + HandleSeek( p_intf, psz_value ); msg_Dbg( p_intf, "requested playlist seek: %s", psz_value ); free( psz_value ); } @@ -565,9 +530,9 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, if( !strcmp( s, "vlc_var_type" ) ) { - char *psz_object = E_(SSPop)( st ); - char *psz_variable = E_(SSPop)( st ); - vlc_bool_t b_need_release; + char *psz_object = SSPop( st ); + char *psz_variable = SSPop( st ); + bool b_need_release; p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); @@ -580,7 +545,7 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } else { - char *psz_variable = E_(SSPop)( st ); + char *psz_variable = SSPop( st ); p_object = VLC_OBJECT(p_intf); i_type = config_GetType( p_object, psz_variable ); free( psz_variable ); @@ -624,20 +589,20 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, else psz_type = "INVALID"; - E_(SSPush)( st, psz_type ); + SSPush( st, psz_type ); } else if( !strcmp( s, "vlc_var_set" ) ) { - char *psz_object = E_(SSPop)( st ); - char *psz_variable = E_(SSPop)( st ); - vlc_bool_t b_need_release; + char *psz_object = SSPop( st ); + char *psz_variable = SSPop( st ); + bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); if( p_object != NULL ) { - vlc_bool_t b_error = VLC_FALSE; + bool b_error = false; char *psz_value = NULL; vlc_value_t val; int i_type; @@ -647,13 +612,13 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: - val.b_bool = E_(SSPopN)( st, vars ); + val.b_bool = SSPopN( st, vars ); msg_Dbg( p_intf, "requested %s var change: %s->%d", psz_object, psz_variable, val.b_bool ); break; case VLC_VAR_INTEGER: case VLC_VAR_HOTKEY: - val.i_int = E_(SSPopN)( st, vars ); + val.i_int = SSPopN( st, vars ); msg_Dbg( p_intf, "requested %s var change: %s->%d", psz_object, psz_variable, val.i_int ); break; @@ -662,21 +627,21 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: case VLC_VAR_VARIABLE: - val.psz_string = psz_value = E_(SSPop)( st ); + val.psz_string = psz_value = SSPop( st ); msg_Dbg( p_intf, "requested %s var change: %s->%s", psz_object, psz_variable, psz_value ); break; case VLC_VAR_FLOAT: - psz_value = E_(SSPop)( st ); + psz_value = SSPop( st ); val.f_float = atof( psz_value ); msg_Dbg( p_intf, "requested %s var change: %s->%f", psz_object, psz_variable, val.f_float ); break; default: - E_(SSPopN)( st, vars ); + SSPopN( st, vars ); msg_Warn( p_intf, "invalid %s variable type %d (%s)", psz_object, i_type & VLC_VAR_TYPE, psz_variable ); - b_error = VLC_TRUE; + b_error = true; } if( !b_error ) @@ -694,9 +659,9 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } else if( !strcmp( s, "vlc_var_get" ) ) { - char *psz_object = E_(SSPop)( st ); - char *psz_variable = E_(SSPop)( st ); - vlc_bool_t b_need_release; + char *psz_object = SSPop( st ); + char *psz_variable = SSPop( st ); + bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); @@ -712,37 +677,39 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: - E_(SSPushN)( st, val.b_bool ); + SSPushN( st, val.b_bool ); break; case VLC_VAR_INTEGER: case VLC_VAR_HOTKEY: - E_(SSPushN)( st, val.i_int ); + SSPushN( st, val.i_int ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: case VLC_VAR_VARIABLE: - E_(SSPush)( st, val.psz_string ); + SSPush( st, val.psz_string ); free( val.psz_string ); break; case VLC_VAR_FLOAT: { char psz_value[20]; - snprintf( psz_value, sizeof(psz_value), "%f", val.f_float ); - E_(SSPush)( st, psz_value ); + lldiv_t value = lldiv( val.f_float * 1000000, 1000000 ); + snprintf( psz_value, sizeof(psz_value), "%lld.%06u", + value.quot, (unsigned int)value.rem ); + SSPush( st, psz_value ); break; } default: msg_Warn( p_intf, "invalid %s variable type %d (%s)", psz_object, i_type & VLC_VAR_TYPE, psz_variable ); - E_(SSPush)( st, "" ); + SSPush( st, "" ); } } else { msg_Warn( p_intf, "vlc_var_get called without an object" ); - E_(SSPush)( st, "" ); + SSPush( st, "" ); } free( psz_variable ); free( psz_object ); @@ -752,8 +719,8 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } else if( !strcmp( s, "vlc_object_exists" ) ) { - char *psz_object = E_(SSPop)( st ); - vlc_bool_t b_need_release; + char *psz_object = SSPop( st ); + bool b_need_release; vlc_object_t *p_object = GetVLCObject( p_intf, psz_object, &b_need_release ); @@ -761,34 +728,34 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, vlc_object_release( p_object ); if( p_object != NULL ) - E_(SSPush)( st, "1" ); + SSPush( st, "1" ); else - E_(SSPush)( st, "0" ); + SSPush( st, "0" ); } else if( !strcmp( s, "vlc_config_set" ) ) { - char *psz_variable = E_(SSPop)( st ); + char *psz_variable = SSPop( st ); int i_type = config_GetType( p_intf, psz_variable ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: case VLC_VAR_INTEGER: - config_PutInt( p_intf, psz_variable, E_(SSPopN)( st, vars ) ); + config_PutInt( p_intf, psz_variable, SSPopN( st, vars ) ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: case VLC_VAR_FILE: case VLC_VAR_DIRECTORY: { - char *psz_string = E_(SSPop)( st ); + char *psz_string = SSPop( st ); config_PutPsz( p_intf, psz_variable, psz_string ); free( psz_string ); break; } case VLC_VAR_FLOAT: { - char *psz_string = E_(SSPop)( st ); + char *psz_string = SSPop( st ); config_PutFloat( p_intf, psz_variable, atof(psz_string) ); free( psz_string ); break; @@ -801,14 +768,14 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } else if( !strcmp( s, "vlc_config_get" ) ) { - char *psz_variable = E_(SSPop)( st ); + char *psz_variable = SSPop( st ); int i_type = config_GetType( p_intf, psz_variable ); switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_BOOL: case VLC_VAR_INTEGER: - E_(SSPushN)( st, config_GetInt( p_intf, psz_variable ) ); + SSPushN( st, config_GetInt( p_intf, psz_variable ) ); break; case VLC_VAR_STRING: case VLC_VAR_MODULE: @@ -816,27 +783,30 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, case VLC_VAR_DIRECTORY: { char *psz_string = config_GetPsz( p_intf, psz_variable ); - E_(SSPush)( st, psz_string ); + SSPush( st, psz_string ); free( psz_string ); break; } case VLC_VAR_FLOAT: { char psz_string[20]; - snprintf( psz_string, sizeof(psz_string), "%f", - config_GetFloat( p_intf, psz_variable ) ); - E_(SSPush)( st, psz_string ); + lldiv_t value = lldiv( config_GetFloat( p_intf, psz_variable ) + * 1000000, 1000000 ); + snprintf( psz_string, sizeof(psz_string), "%lld.%06u", + value.quot, (unsigned int)value.rem ); + SSPush( st, psz_string ); break; } default: msg_Warn( p_intf, "vlc_config_get called on unknown var (%s)", psz_variable ); + SSPush( st, "" ); } free( psz_variable ); } else if( !strcmp( s, "vlc_config_save" ) ) { - char *psz_module = E_(SSPop)( st ); + char *psz_module = SSPop( st ); int i_result; if( !*psz_module ) @@ -848,7 +818,7 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, if( psz_module != NULL ) free( psz_module ); - E_(SSPushN)( st, i_result ); + SSPushN( st, i_result ); } else if( !strcmp( s, "vlc_config_reset" ) ) { @@ -857,60 +827,64 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, /* 6. playlist functions */ else if( !strcmp( s, "playlist_add" ) ) { - char *psz_name = E_(SSPop)( st ); - char *mrl = E_(SSPop)( st ); - char *tmp; - playlist_item_t *p_item; - int i_id; + char *psz_name = SSPop( st ); + char *mrl = SSPop( st ); + input_item_t *p_input; + int i_ret; - tmp = E_(ToUTF8)( p_intf, psz_name ); - free( psz_name ); - psz_name = tmp; - tmp = E_(ToUTF8)( p_intf, mrl ); - free( mrl ); - mrl = tmp; + p_input = MRLParse( p_intf, mrl, psz_name ); - if( !*psz_name ) + char *psz_uri = input_item_GetURI( p_input ); + if( !p_input || !psz_uri || !*psz_uri ) { - p_item = E_(MRLParse)( p_intf, mrl, mrl ); - } - else - { - p_item = E_(MRLParse)( p_intf, mrl, psz_name ); - } - - if( p_item == NULL || p_item->input.psz_uri == NULL || - !*p_item->input.psz_uri ) - { - i_id = VLC_EGENERIC; + i_ret = VLC_EGENERIC; msg_Dbg( p_intf, "invalid requested mrl: %s", mrl ); } else { - i_id = playlist_AddItem( p_sys->p_playlist, p_item, - PLAYLIST_APPEND, PLAYLIST_END ); - msg_Dbg( p_intf, "requested mrl add: %s", mrl ); + i_ret = playlist_AddInput( p_sys->p_playlist, p_input, + PLAYLIST_APPEND, PLAYLIST_END, true, + false); + vlc_gc_decref( p_input ); + if( i_ret == VLC_SUCCESS ) + msg_Dbg( p_intf, "requested mrl add: %s", mrl ); + else + msg_Warn( p_intf, "adding mrl %s failed", mrl ); } - E_(SSPushN)( st, i_id ); + free( psz_uri ); + SSPushN( st, i_ret ); free( mrl ); free( psz_name ); } else if( !strcmp( s, "playlist_empty" ) ) { - playlist_LockClear( p_sys->p_playlist ); + playlist_Clear( p_sys->p_playlist, false ); msg_Dbg( p_intf, "requested playlist empty" ); } else if( !strcmp( s, "playlist_delete" ) ) { - int i_id = E_(SSPopN)( st, vars ); - playlist_LockDelete( p_sys->p_playlist, i_id ); - msg_Dbg( p_intf, "requested playlist delete: %d", i_id ); + int i_id = SSPopN( st, vars ); + playlist_item_t *p_item = playlist_ItemGetById( p_sys->p_playlist, + i_id, false ); + if( p_item ) + { + playlist_DeleteFromInput( p_sys->p_playlist, + p_item->p_input->i_id, false ); + msg_Dbg( p_intf, "requested playlist delete: %d", i_id ); + } + else + { + msg_Dbg( p_intf, "couldn't find playlist item to delete (%d)", + i_id ); + } } else if( !strcmp( s, "playlist_move" ) ) { - int i_newpos = E_(SSPopN)( st, vars ); - int i_pos = E_(SSPopN)( st, vars ); + /*int i_newpos =*/ SSPopN( st, vars ); + /*int i_pos =*/ SSPopN( st, vars ); + /* FIXME FIXME TODO TODO XXX XXX + do not release before fixing this if ( i_pos < i_newpos ) { playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 ); @@ -921,10 +895,47 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, } msg_Dbg( p_intf, "requested to move playlist item %d to %d", i_pos, i_newpos); + FIXME FIXME TODO TODO XXX XXX */ + msg_Err( p_intf, "moving using indexes is obsolete. We need to update this function" ); + } + else if( !strcmp( s, "playlist_sort" ) ) + { + int i_order = SSPopN( st, vars ); + int i_sort = SSPopN( st, vars ); + i_order = i_order % 2; + i_sort = i_sort % 9; + /* FIXME FIXME TODO TODO XXX XXX + do not release before fixing this + playlist_RecursiveNodeSort( p_sys->p_playlist, + p_sys->p_playlist->p_general, + i_sort, i_order ); + msg_Dbg( p_intf, "requested sort playlist by : %d in order : %d", + i_sort, i_order ); + FIXME FIXME TODO TODO XXX XXX */ + msg_Err( p_intf, "this needs to be fixed to use the new playlist framework" ); + } + else if( !strcmp( s, "services_discovery_add" ) ) + { + char *psz_sd = SSPop( st ); + playlist_ServicesDiscoveryAdd( p_sys->p_playlist, psz_sd ); + free( psz_sd ); + } + else if( !strcmp( s, "services_discovery_remove" ) ) + { + char *psz_sd = SSPop( st ); + playlist_ServicesDiscoveryRemove( p_sys->p_playlist, psz_sd ); + free( psz_sd ); + } + else if( !strcmp( s, "services_discovery_is_loaded" ) ) + { + char *psz_sd = SSPop( st ); + SSPushN( st, + playlist_IsServicesDiscoveryLoaded( p_sys->p_playlist, psz_sd ) ); + free( psz_sd ); } else if( !strcmp( s, "vlc_volume_set" ) ) { - char *psz_vol = E_(SSPop)( st ); + char *psz_vol = SSPop( st ); int i_value; audio_volume_t i_volume; aout_VolumeGet( p_intf, &i_volume ); @@ -959,10 +970,113 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars, aout_VolumeSet( p_intf, i_value ); } aout_VolumeGet( p_intf, &i_volume ); + free( psz_vol ); + } + else if( !strcmp( s, "vlc_get_meta" ) ) + { + char *psz_meta = SSPop( st ); + char *psz_val = NULL; + if( p_sys->p_input && input_GetItem(p_sys->p_input) ) + { +#define p_item input_GetItem( p_sys->p_input ) + if( !strcmp( psz_meta, "ARTIST" ) ) + { + psz_val = input_item_GetArtist( p_item ); + } + else if( !strcmp( psz_meta, "TITLE" ) ) + { + psz_val = input_item_GetTitle( p_item ); + if( !psz_val ) + psz_val = input_item_GetName( p_item ); + } + else if( !strcmp( psz_meta, "ALBUM" ) ) + { + psz_val = input_item_GetAlbum( p_item ); + } + else if( !strcmp( psz_meta, "GENRE" ) ) + { + psz_val = input_item_GetGenre( p_item ); + } +#undef p_item + } + if( psz_val == NULL ) psz_val = strdup( "" ); + SSPush( st, psz_val ); + free( psz_meta ); + free( psz_val ); + } +#ifdef ENABLE_VLM + else if( !strcmp( s, "vlm_command" ) || !strcmp( s, "vlm_cmd" ) ) + { + char *psz_elt; + char *psz_cmd = strdup( "" ); + char *psz_error; + vlm_message_t *vlm_answer; + + /* make sure that we have a vlm object */ + if( p_intf->p_sys->p_vlm == NULL ) + p_intf->p_sys->p_vlm = vlm_New( p_intf ); + + + /* vlm command uses the ';' delimiter + * (else we can't know when to stop) */ + while( strcmp( psz_elt = SSPop( st ), "" ) + && strcmp( psz_elt, ";" ) ) + { + char *psz_buf = + (char *)malloc( strlen( psz_cmd ) + strlen( psz_elt ) + 2 ); + sprintf( psz_buf, "%s %s", psz_cmd, psz_elt ); + free( psz_cmd ); + free( psz_elt ); + psz_cmd = psz_buf; + } + + msg_Dbg( p_intf, "executing vlm command: %s", psz_cmd ); + vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz_cmd, &vlm_answer ); + + if( vlm_answer->psz_value == NULL ) + { + psz_error = strdup( "" ); + } + else + { + psz_error = malloc( strlen(vlm_answer->psz_name) + + strlen(vlm_answer->psz_value) + + strlen( " : ") + 1 ); + sprintf( psz_error , "%s : %s" , vlm_answer->psz_name, + vlm_answer->psz_value ); + } + + mvar_AppendNewVar( vars, "vlm_error", psz_error ); + /* this is kind of a duplicate but we need to have the message + * without the command name for the "export" command */ + mvar_AppendNewVar( vars, "vlm_value", vlm_answer->psz_value ); + vlm_MessageDelete( vlm_answer ); + + free( psz_cmd ); + free( psz_error ); + } +#endif /* ENABLE_VLM */ + else if( !strcmp( s, "snapshot" ) ) + { + if( p_sys->p_input ) + { + vout_thread_t *p_vout; + p_vout = vlc_object_find( p_sys->p_input, + VLC_OBJECT_VOUT, FIND_CHILD ); + + if( p_vout ) + { + vout_Control( p_vout, VOUT_SNAPSHOT ); + vlc_object_release( p_vout ); + msg_Dbg( p_intf, "requested snapshot" ); + } + } + break; + } else { - E_(SSPush)( st, s ); + SSPush( st, s ); } } }