]> git.sesse.net Git - vlc/blob - modules/control/http/rpn.c
* modules/control/http/rpn.c: vlc_var_* now take an extra argument to
[vlc] / modules / control / http / rpn.c
1 /*****************************************************************************
2  * rpn.c : RPN evaluator for the HTTP Interface
3  *****************************************************************************
4  * Copyright (C) 2001-2005 the VideoLAN team
5  * $Id: http.c 12225 2005-08-18 10:01:30Z massiot $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *          Christophe Massiot <massiot@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 #include "http.h"
27
28 static vlc_object_t *GetVLCObject( intf_thread_t *p_intf,
29                                    const char *psz_object,
30                                    vlc_bool_t *pb_need_release )
31 {
32     intf_sys_t    *p_sys = p_intf->p_sys;
33     int i_object_type = 0;
34     vlc_object_t *p_object = NULL;
35     *pb_need_release = VLC_FALSE;
36
37     if( !strcmp( psz_object, "VLC_OBJECT_ROOT" ) )
38         i_object_type = VLC_OBJECT_ROOT;
39     else if( !strcmp( psz_object, "VLC_OBJECT_VLC" ) )
40         p_object = VLC_OBJECT(p_intf->p_vlc);
41     else if( !strcmp( psz_object, "VLC_OBJECT_INTF" ) )
42         p_object = VLC_OBJECT(p_intf);
43     else if( !strcmp( psz_object, "VLC_OBJECT_PLAYLIST" ) )
44         p_object = VLC_OBJECT(p_sys->p_playlist);
45     else if( !strcmp( psz_object, "VLC_OBJECT_INPUT" ) )
46         p_object = VLC_OBJECT(p_sys->p_input);
47     else if( !strcmp( psz_object, "VLC_OBJECT_VOUT" ) )
48         i_object_type = VLC_OBJECT_VOUT;
49     else if( !strcmp( psz_object, "VLC_OBJECT_AOUT" ) )
50         i_object_type = VLC_OBJECT_AOUT;
51     else if( !strcmp( psz_object, "VLC_OBJECT_SOUT" ) )
52         i_object_type = VLC_OBJECT_SOUT;
53     else
54         msg_Warn( p_intf, "unknown object type (%s)", psz_object );
55
56     if( p_object == NULL && i_object_type )
57     {
58         *pb_need_release = VLC_TRUE;
59         p_object = vlc_object_find( p_intf, i_object_type, FIND_ANYWHERE );
60     }
61
62     return p_object;
63 }
64
65 void SSInit( rpn_stack_t *st )
66 {
67     st->i_stack = 0;
68 }
69
70 void SSClean( rpn_stack_t *st )
71 {
72     while( st->i_stack > 0 )
73     {
74         free( st->stack[--st->i_stack] );
75     }
76 }
77
78 void SSPush( rpn_stack_t *st, const char *s )
79 {
80     if( st->i_stack < STACK_MAX )
81     {
82         st->stack[st->i_stack++] = strdup( s );
83     }
84 }
85
86 char * SSPop( rpn_stack_t *st )
87 {
88     if( st->i_stack <= 0 )
89     {
90         return strdup( "" );
91     }
92     else
93     {
94         return st->stack[--st->i_stack];
95     }
96 }
97
98 int SSPopN( rpn_stack_t *st, mvar_t  *vars )
99 {
100     char *name;
101     char *value;
102
103     char *end;
104     int  i;
105
106     name = SSPop( st );
107     i = strtol( name, &end, 0 );
108     if( end == name )
109     {
110         value = mvar_GetValue( vars, name );
111         i = atoi( value );
112     }
113     free( name );
114
115     return( i );
116 }
117
118 void SSPushN( rpn_stack_t *st, int i )
119 {
120     char v[512];
121
122     sprintf( v, "%d", i );
123     SSPush( st, v );
124 }
125
126 void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
127                    rpn_stack_t *st, char *exp )
128 {
129     intf_sys_t    *p_sys = p_intf->p_sys;
130
131     while( exp != NULL && *exp != '\0' )
132     {
133         char *p, *s;
134
135         /* skip space */
136         while( *exp == ' ' )
137         {
138             exp++;
139         }
140
141         if( *exp == '\'' )
142         {
143             /* extract string */
144             p = E_(FirstWord)( exp, exp );
145             SSPush( st, exp );
146             exp = p;
147             continue;
148         }
149
150         /* extract token */
151         p = E_(FirstWord)( exp, exp );
152         s = exp;
153         if( p == NULL )
154         {
155             exp += strlen( exp );
156         }
157         else
158         {
159             exp = p;
160         }
161
162         if( *s == '\0' )
163         {
164             break;
165         }
166
167         /* 1. Integer function */
168         if( !strcmp( s, "!" ) )
169         {
170             SSPushN( st, ~SSPopN( st, vars ) );
171         }
172         else if( !strcmp( s, "^" ) )
173         {
174             SSPushN( st, SSPopN( st, vars ) ^ SSPopN( st, vars ) );
175         }
176         else if( !strcmp( s, "&" ) )
177         {
178             SSPushN( st, SSPopN( st, vars ) & SSPopN( st, vars ) );
179         }
180         else if( !strcmp( s, "|" ) )
181         {
182             SSPushN( st, SSPopN( st, vars ) | SSPopN( st, vars ) );
183         }
184         else if( !strcmp( s, "+" ) )
185         {
186             SSPushN( st, SSPopN( st, vars ) + SSPopN( st, vars ) );
187         }
188         else if( !strcmp( s, "-" ) )
189         {
190             int j = SSPopN( st, vars );
191             int i = SSPopN( st, vars );
192             SSPushN( st, i - j );
193         }
194         else if( !strcmp( s, "*" ) )
195         {
196             SSPushN( st, SSPopN( st, vars ) * SSPopN( st, vars ) );
197         }
198         else if( !strcmp( s, "/" ) )
199         {
200             int i, j;
201
202             j = SSPopN( st, vars );
203             i = SSPopN( st, vars );
204
205             SSPushN( st, j != 0 ? i / j : 0 );
206         }
207         else if( !strcmp( s, "%" ) )
208         {
209             int i, j;
210
211             j = SSPopN( st, vars );
212             i = SSPopN( st, vars );
213
214             SSPushN( st, j != 0 ? i % j : 0 );
215         }
216         /* 2. integer tests */
217         else if( !strcmp( s, "=" ) )
218         {
219             SSPushN( st, SSPopN( st, vars ) == SSPopN( st, vars ) ? -1 : 0 );
220         }
221         else if( !strcmp( s, "!=" ) )
222         {
223             SSPushN( st, SSPopN( st, vars ) != SSPopN( st, vars ) ? -1 : 0 );
224         }
225         else if( !strcmp( s, "<" ) )
226         {
227             int j = SSPopN( st, vars );
228             int i = SSPopN( st, vars );
229
230             SSPushN( st, i < j ? -1 : 0 );
231         }
232         else if( !strcmp( s, ">" ) )
233         {
234             int j = SSPopN( st, vars );
235             int i = SSPopN( st, vars );
236
237             SSPushN( st, i > j ? -1 : 0 );
238         }
239         else if( !strcmp( s, "<=" ) )
240         {
241             int j = SSPopN( st, vars );
242             int i = SSPopN( st, vars );
243
244             SSPushN( st, i <= j ? -1 : 0 );
245         }
246         else if( !strcmp( s, ">=" ) )
247         {
248             int j = SSPopN( st, vars );
249             int i = SSPopN( st, vars );
250
251             SSPushN( st, i >= j ? -1 : 0 );
252         }
253         /* 3. string functions */
254         else if( !strcmp( s, "strcat" ) )
255         {
256             char *s2 = SSPop( st );
257             char *s1 = SSPop( st );
258             char *str = malloc( strlen( s1 ) + strlen( s2 ) + 1 );
259
260             strcpy( str, s1 );
261             strcat( str, s2 );
262
263             SSPush( st, str );
264             free( s1 );
265             free( s2 );
266             free( str );
267         }
268         else if( !strcmp( s, "strcmp" ) )
269         {
270             char *s2 = SSPop( st );
271             char *s1 = SSPop( st );
272
273             SSPushN( st, strcmp( s1, s2 ) );
274             free( s1 );
275             free( s2 );
276         }
277         else if( !strcmp( s, "strncmp" ) )
278         {
279             int n = SSPopN( st, vars );
280             char *s2 = SSPop( st );
281             char *s1 = SSPop( st );
282
283             SSPushN( st, strncmp( s1, s2 , n ) );
284             free( s1 );
285             free( s2 );
286         }
287         else if( !strcmp( s, "strsub" ) )
288         {
289             int n = SSPopN( st, vars );
290             int m = SSPopN( st, vars );
291             int i_len;
292             char *s = SSPop( st );
293             char *str;
294
295             if( n >= m )
296             {
297                 i_len = n - m + 1;
298             }
299             else
300             {
301                 i_len = 0;
302             }
303
304             str = malloc( i_len + 1 );
305
306             memcpy( str, s + m - 1, i_len );
307             str[ i_len ] = '\0';
308
309             SSPush( st, str );
310             free( s );
311             free( str );
312         }
313         else if( !strcmp( s, "strlen" ) )
314         {
315             char *str = SSPop( st );
316
317             SSPushN( st, strlen( str ) );
318             free( str );
319         }
320         else if( !strcmp( s, "str_replace" ) )
321         {
322             char *psz_to = SSPop( st );
323             char *psz_from = SSPop( st );
324             char *psz_in = SSPop( st );
325             char *psz_in_current = psz_in;
326             char *psz_out = malloc( strlen(psz_in) * strlen(psz_to) + 1 );
327             char *psz_out_current = psz_out;
328
329             while( (p = strstr( psz_in_current, psz_from )) != NULL )
330             {
331                 memcpy( psz_out_current, psz_in_current, p - psz_in_current );
332                 psz_out_current += p - psz_in_current;
333                 strcpy( psz_out_current, psz_to );
334                 psz_out_current += strlen(psz_to);
335                 psz_in_current = p + strlen(psz_from);
336             }
337             strcpy( psz_out_current, psz_in_current );
338             psz_out_current += strlen(psz_in_current);
339             *psz_out_current = '\0';
340
341             SSPush( st, psz_out );
342             free( psz_to );
343             free( psz_from );
344             free( psz_in );
345             free( psz_out );
346         }
347         else if( !strcmp( s, "url_extract" ) )
348         {
349             char *url = mvar_GetValue( vars, "url_value" );
350             char *name = SSPop( st );
351             char value[512];
352             char *tmp;
353
354             E_(ExtractURIValue)( url, name, value, 512 );
355             E_(DecodeEncodedURI)( value );
356             tmp = E_(FromUTF8)( p_intf, value );
357             SSPush( st, tmp );
358             free( tmp );
359             free( name );
360         }
361         else if( !strcmp( s, "url_encode" ) )
362         {
363             char *url = SSPop( st );
364             char *value;
365
366             value = E_(ToUTF8)( p_intf, url );
367             free( url );
368             url = value;
369             value = vlc_UrlEncode( url );
370             free( url );
371             SSPush( st, value );
372             free( value );
373         }
374         else if( !strcmp( s, "addslashes" ) )
375         {
376             char *psz_src = SSPop( st );
377             char *psz_dest;
378             char *str = psz_src;
379
380             p = psz_dest = malloc( strlen( str ) * 2 + 1 );
381
382             while( *str != '\0' )
383             {
384                 if( *str == '"' || *str == '\'' || *str == '\\' )
385                 {
386                     *p++ = '\\';
387                 }
388                 *p++ = *str;
389                 str++;
390             }
391             *p = '\0';
392
393             SSPush( st, psz_dest );
394             free( psz_src );
395             free( psz_dest );
396         }
397         else if( !strcmp( s, "stripslashes" ) )
398         {
399             char *psz_src = SSPop( st );
400             char *psz_dest;
401
402             p = psz_dest = strdup( psz_src );
403
404             while( *psz_src != '\0' )
405             {
406                 if( *psz_src == '\\' )
407                 {
408                     *psz_src++;
409                 }
410                 *p++ = *psz_src;
411                 psz_src++;
412             }
413             *p = '\0';
414
415             SSPush( st, psz_dest );
416             free( psz_src );
417             free( psz_dest );
418         }
419         else if( !strcmp( s, "htmlspecialchars" ) )
420         {
421             char *psz_src = SSPop( st );
422             char *psz_dest;
423             char *str = psz_src;
424
425             p = psz_dest = malloc( strlen( str ) * 6 + 1 );
426
427             while( *str != '\0' )
428             {
429                 if( *str == '&' )
430                 {
431                     strcpy( p, "&amp;" );
432                     p += 5;
433                 }
434                 else if( *str == '\"' )
435                 {
436                     strcpy( p, "&quot;" );
437                     p += 6;
438                 }
439                 else if( *str == '\'' )
440                 {
441                     strcpy( p, "&#039;" );
442                     p += 6;
443                 }
444                 else if( *str == '<' )
445                 {
446                     strcpy( p, "&lt;" );
447                     p += 4;
448                 }
449                 else if( *str == '>' )
450                 {
451                     strcpy( p, "&gt;" );
452                     p += 4;
453                 }
454                 else
455                 {
456                     *p++ = *str;
457                 }
458                 str++;
459             }
460             *p = '\0';
461
462             SSPush( st, psz_dest );
463             free( psz_src );
464             free( psz_dest );
465         }
466         else if( !strcmp( s, "realpath" ) )
467         {
468             char *psz_src = SSPop( st );
469             char *psz_dir = E_(RealPath)( p_intf, psz_src );
470             char sep;
471
472             SSPush( st, psz_dir );
473             free( psz_src );
474             free( psz_dir );
475         }
476         /* 4. stack functions */
477         else if( !strcmp( s, "dup" ) )
478         {
479             char *str = SSPop( st );
480             SSPush( st, str );
481             SSPush( st, str );
482             free( str );
483         }
484         else if( !strcmp( s, "drop" ) )
485         {
486             char *str = SSPop( st );
487             free( str );
488         }
489         else if( !strcmp( s, "swap" ) )
490         {
491             char *s1 = SSPop( st );
492             char *s2 = SSPop( st );
493
494             SSPush( st, s1 );
495             SSPush( st, s2 );
496             free( s1 );
497             free( s2 );
498         }
499         else if( !strcmp( s, "flush" ) )
500         {
501             SSClean( st );
502             SSInit( st );
503         }
504         else if( !strcmp( s, "store" ) )
505         {
506             char *value = SSPop( st );
507             char *name  = SSPop( st );
508
509             mvar_PushNewVar( vars, name, value );
510             free( name );
511             free( value );
512         }
513         else if( !strcmp( s, "value" ) )
514         {
515             char *name  = SSPop( st );
516             char *value = mvar_GetValue( vars, name );
517
518             SSPush( st, value );
519
520             free( name );
521         }
522         /* 5. player control */
523         else if( !strcmp( s, "vlc_play" ) )
524         {
525             int i_id = SSPopN( st, vars );
526             int i_ret;
527
528             i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_ITEMPLAY,
529                                       playlist_ItemGetById( p_sys->p_playlist,
530                                       i_id ) );
531             msg_Dbg( p_intf, "requested playlist item: %i", i_id );
532             SSPushN( st, i_ret );
533         }
534         else if( !strcmp( s, "vlc_stop" ) )
535         {
536             playlist_Control( p_sys->p_playlist, PLAYLIST_STOP );
537             msg_Dbg( p_intf, "requested playlist stop" );
538         }
539         else if( !strcmp( s, "vlc_pause" ) )
540         {
541             playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE );
542             msg_Dbg( p_intf, "requested playlist pause" );
543         }
544         else if( !strcmp( s, "vlc_next" ) )
545         {
546             playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, 1 );
547             msg_Dbg( p_intf, "requested playlist next" );
548         }
549         else if( !strcmp( s, "vlc_previous" ) )
550         {
551             playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, -1 );
552             msg_Dbg( p_intf, "requested playlist previous" );
553         }
554         else if( !strcmp( s, "vlc_seek" ) )
555         {
556             char *psz_value = SSPop( st );
557             E_(HandleSeek)( p_intf, psz_value );
558             msg_Dbg( p_intf, "requested playlist seek: %s", psz_value );
559             free( psz_value );
560         }
561         else if( !strcmp( s, "vlc_var_type" )
562                   || !strcmp( s, "vlc_config_type" ) )
563         {
564             vlc_object_t *p_object;
565             const char *psz_type = NULL;
566             int i_type = 0;
567
568             if( !strcmp( s, "vlc_var_type" ) )
569             {
570                 char *psz_object = SSPop( st );
571                 char *psz_variable = SSPop( st );
572                 vlc_bool_t b_need_release;
573
574                 p_object = GetVLCObject( p_intf, psz_object, &b_need_release );
575
576                 if( p_object != NULL )
577                     i_type = var_Type( p_object, psz_variable );
578                 free( psz_variable );
579                 free( psz_object );
580                 if( b_need_release && p_object != NULL )
581                     vlc_object_release( p_object );
582             }
583             else
584             {
585                 char *psz_variable = SSPop( st );
586                 p_object = VLC_OBJECT(p_intf);
587                 i_type = config_GetType( p_object, psz_variable );
588                 free( psz_variable );
589             }
590
591             if( p_object != NULL )
592             {
593                 switch( i_type & VLC_VAR_TYPE )
594                 {
595                 case VLC_VAR_BOOL:
596                     psz_type = "VLC_VAR_BOOL";
597                     break;
598                 case VLC_VAR_INTEGER:
599                     psz_type = "VLC_VAR_INTEGER";
600                     break;
601                 case VLC_VAR_HOTKEY:
602                     psz_type = "VLC_VAR_HOTKEY";
603                     break;
604                 case VLC_VAR_STRING:
605                     psz_type = "VLC_VAR_STRING";
606                     break;
607                 case VLC_VAR_MODULE:
608                     psz_type = "VLC_VAR_MODULE";
609                     break;
610                 case VLC_VAR_FILE:
611                     psz_type = "VLC_VAR_FILE";
612                     break;
613                 case VLC_VAR_DIRECTORY:
614                     psz_type = "VLC_VAR_DIRECTORY";
615                     break;
616                 case VLC_VAR_VARIABLE:
617                     psz_type = "VLC_VAR_VARIABLE";
618                     break;
619                 case VLC_VAR_FLOAT:
620                     psz_type = "VLC_VAR_FLOAT";
621                     break;
622                 default:
623                     psz_type = "UNDEFINED";
624                 }
625             }
626             else
627                 psz_type = "INVALID";
628
629             SSPush( st, psz_type );
630         }
631         else if( !strcmp( s, "vlc_var_set" ) )
632         {
633             char *psz_object = SSPop( st );
634             char *psz_variable = SSPop( st );
635             vlc_bool_t b_need_release;
636
637             vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
638                                                    &b_need_release );
639
640             if( p_object != NULL )
641             {
642                 vlc_bool_t b_error = VLC_FALSE;
643                 char *psz_value = NULL;
644                 vlc_value_t val;
645                 int i_type;
646
647                 i_type = var_Type( p_object, psz_variable );
648
649                 switch( i_type & VLC_VAR_TYPE )
650                 {
651                 case VLC_VAR_BOOL:
652                     val.b_bool = SSPopN( st, vars );
653                     msg_Dbg( p_intf, "requested %s var change: %s->%d",
654                              psz_object, psz_variable, val.b_bool );
655                     break;
656                 case VLC_VAR_INTEGER:
657                 case VLC_VAR_HOTKEY:
658                     val.i_int = SSPopN( st, vars );
659                     msg_Dbg( p_intf, "requested %s var change: %s->%d",
660                              psz_object, psz_variable, val.i_int );
661                     break;
662                 case VLC_VAR_STRING:
663                 case VLC_VAR_MODULE:
664                 case VLC_VAR_FILE:
665                 case VLC_VAR_DIRECTORY:
666                 case VLC_VAR_VARIABLE:
667                     val.psz_string = psz_value = SSPop( st );
668                     msg_Dbg( p_intf, "requested %s var change: %s->%s",
669                              psz_object, psz_variable, psz_value );
670                     break;
671                 case VLC_VAR_FLOAT:
672                     psz_value = SSPop( st );
673                     val.f_float = atof( psz_value );
674                     msg_Dbg( p_intf, "requested %s var change: %s->%f",
675                              psz_object, psz_variable, val.f_float );
676                     break;
677                 default:
678                     SSPopN( st, vars );
679                     msg_Warn( p_intf, "invalid %s variable type %d (%s)",
680                               psz_object, i_type & VLC_VAR_TYPE, psz_variable );
681                     b_error = VLC_TRUE;
682                 }
683
684                 if( !b_error )
685                     var_Set( p_object, psz_variable, val );
686                 if( psz_value != NULL )
687                     free( psz_value );
688             }
689             else
690                 msg_Warn( p_intf, "vlc_var_set called without an object" );
691             free( psz_variable );
692             free( psz_object );
693
694             if( b_need_release && p_object != NULL )
695                 vlc_object_release( p_object );
696         }
697         else if( !strcmp( s, "vlc_var_get" ) )
698         {
699             char *psz_object = SSPop( st );
700             char *psz_variable = SSPop( st );
701             vlc_bool_t b_need_release;
702
703             vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
704                                                    &b_need_release );
705
706             if( p_object != NULL )
707             {
708                 vlc_value_t val;
709                 int i_type;
710
711                 i_type = var_Type( p_object, psz_variable );
712                 var_Get( p_object, psz_variable, &val );
713
714                 switch( i_type & VLC_VAR_TYPE )
715                 {
716                 case VLC_VAR_BOOL:
717                     SSPushN( st, val.b_bool );
718                     break;
719                 case VLC_VAR_INTEGER:
720                 case VLC_VAR_HOTKEY:
721                     SSPushN( st, val.i_int );
722                     break;
723                 case VLC_VAR_STRING:
724                 case VLC_VAR_MODULE:
725                 case VLC_VAR_FILE:
726                 case VLC_VAR_DIRECTORY:
727                 case VLC_VAR_VARIABLE:
728                     SSPush( st, val.psz_string );
729                     free( val.psz_string );
730                     break;
731                 case VLC_VAR_FLOAT:
732                 {
733                     char psz_value[20];
734                     snprintf( psz_value, sizeof(psz_value), "%f", val.f_float );
735                     SSPush( st, psz_value );
736                     break;
737                 }
738                 default:
739                     msg_Warn( p_intf, "invalid %s variable type %d (%s)",
740                               psz_object, i_type & VLC_VAR_TYPE, psz_variable );
741                     SSPush( st, "" );
742                 }
743             }
744             else
745             {
746                 msg_Warn( p_intf, "vlc_var_get called without an object" );
747                 SSPush( st, "" );
748             }
749             free( psz_variable );
750             free( psz_object );
751
752             if( b_need_release && p_object != NULL )
753                 vlc_object_release( p_object );
754         }
755         else if( !strcmp( s, "vlc_config_set" ) )
756         {
757             char *psz_variable = SSPop( st );
758             int i_type = config_GetType( p_intf, psz_variable );
759
760             switch( i_type & VLC_VAR_TYPE )
761             {
762             case VLC_VAR_BOOL:
763             case VLC_VAR_INTEGER:
764                 config_PutInt( p_intf, psz_variable, SSPopN( st, vars ) );
765                 break;
766             case VLC_VAR_STRING:
767             case VLC_VAR_MODULE:
768             case VLC_VAR_FILE:
769             case VLC_VAR_DIRECTORY:
770             {
771                 char *psz_string = SSPop( st );
772                 config_PutPsz( p_intf, psz_variable, psz_string );
773                 free( psz_string );
774                 break;
775             }
776             case VLC_VAR_FLOAT:
777             {
778                 char *psz_string = SSPop( st );
779                 config_PutFloat( p_intf, psz_variable, atof(psz_string) );
780                 free( psz_string );
781                 break;
782             }
783             default:
784                 msg_Warn( p_intf, "vlc_config_set called on unknown var (%s)",
785                           psz_variable );
786             }
787             free( psz_variable );
788         }
789         else if( !strcmp( s, "vlc_config_get" ) )
790         {
791             char *psz_variable = SSPop( st );
792             int i_type = config_GetType( p_intf, psz_variable );
793
794             switch( i_type & VLC_VAR_TYPE )
795             {
796             case VLC_VAR_BOOL:
797             case VLC_VAR_INTEGER:
798                 SSPushN( st, config_GetInt( p_intf, psz_variable ) );
799                 break;
800             case VLC_VAR_STRING:
801             case VLC_VAR_MODULE:
802             case VLC_VAR_FILE:
803             case VLC_VAR_DIRECTORY:
804             {
805                 char *psz_string = config_GetPsz( p_intf, psz_variable );
806                 SSPush( st, psz_string );
807                 free( psz_string );
808                 break;
809             }
810             case VLC_VAR_FLOAT:
811             {
812                 char psz_string[20];
813                 snprintf( psz_string, sizeof(psz_string), "%f",
814                           config_GetFloat( p_intf, psz_variable ) );
815                 SSPush( st, psz_string );
816                 break;
817             }
818             default:
819                 msg_Warn( p_intf, "vlc_config_get called on unknown var (%s)",
820                           psz_variable );
821             }
822             free( psz_variable );
823         }
824         else if( !strcmp( s, "vlc_config_save" ) )
825         {
826             char *psz_module = SSPop( st );
827             int i_result;
828
829             if( !*psz_module )
830             {
831                 free( psz_module );
832                 psz_module = NULL;
833             }
834             i_result = config_SaveConfigFile( p_intf, psz_module );
835
836             if( psz_module != NULL )
837                 free( psz_module );
838             SSPushN( st, i_result );
839         }
840         else if( !strcmp( s, "vlc_config_reset" ) )
841         {
842             config_ResetAll( p_intf );
843         }
844         /* 6. playlist functions */
845         else if( !strcmp( s, "playlist_add" ) )
846         {
847             char *psz_name = SSPop( st );
848             char *mrl = SSPop( st );
849             char *tmp;
850             playlist_item_t *p_item;
851             int i_id;
852
853             tmp = E_(ToUTF8)( p_intf, psz_name );
854             free( psz_name );
855             psz_name = tmp;
856             tmp = E_(ToUTF8)( p_intf, mrl );
857             free( mrl );
858             mrl = tmp;
859
860             if( !*psz_name )
861             {
862                 p_item = E_(MRLParse)( p_intf, mrl, mrl );
863             }
864             else
865             {
866                 p_item = E_(MRLParse)( p_intf, mrl, psz_name );
867             }
868
869             if( p_item == NULL || p_item->input.psz_uri == NULL ||
870                  !*p_item->input.psz_uri )
871             {
872                 i_id = VLC_EGENERIC;
873                 msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
874             }
875             else
876             {
877                 i_id = playlist_AddItem( p_sys->p_playlist, p_item,
878                                          PLAYLIST_APPEND, PLAYLIST_END );
879                 msg_Dbg( p_intf, "requested mrl add: %s", mrl );
880             }
881             SSPushN( st, i_id );
882
883             free( mrl );
884             free( psz_name );
885         }
886         else if( !strcmp( s, "playlist_empty" ) )
887         {
888             playlist_LockClear( p_sys->p_playlist );
889             msg_Dbg( p_intf, "requested playlist empty" );
890         }
891         else if( !strcmp( s, "playlist_delete" ) )
892         {
893             int i_id = SSPopN( st, vars );
894             playlist_LockDelete( p_sys->p_playlist, i_id );
895             msg_Dbg( p_intf, "requested playlist delete: %d", i_id );
896         }
897         else if( !strcmp( s, "playlist_move" ) )
898         {
899             int i_newpos = SSPopN( st, vars );
900             int i_pos = SSPopN( st, vars );
901             if ( i_pos < i_newpos )
902             {
903                 playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
904             }
905             else
906             {
907                 playlist_Move( p_sys->p_playlist, i_pos, i_newpos );
908             }
909             msg_Dbg( p_intf, "requested to move playlist item %d to %d",
910                      i_pos, i_newpos);
911         }
912         else
913         {
914             SSPush( st, s );
915         }
916     }
917 }