]> git.sesse.net Git - vlc/blobdiff - src/text/strings.c
Revert "Fixed warning for uninitialized variable"
[vlc] / src / text / strings.c
index 712116ddd2fb2a458539535ee70fb8a11c7ca72e..9cc150aee4a62a05253fb2977ea631cabfecd21f 100644 (file)
@@ -42,7 +42,7 @@
 /* Needed by str_format_meta */
 #include <vlc_input.h>
 #include <vlc_meta.h>
-#include <vlc_playlist.h>
+#include <vlc_aout.h>
 
 #include <vlc_strings.h>
 #include <vlc_charset.h>
@@ -202,9 +202,15 @@ void resolve_xml_special_chars( char *psz_value )
         if( *psz_value == '&' )
         {
             if( psz_value[1] == '#' )
-            {   /* &#xxx; Unicode code point */
+            {   /* &#DDD; or &#xHHHH; Unicode code point */
                 char *psz_end;
-                unsigned long cp = strtoul( psz_value+2, &psz_end, 10 );
+                unsigned long cp;
+
+                if( psz_value[2] == 'x' ) /* The x must be lower-case. */
+                    cp = strtoul( psz_value + 3, &psz_end, 16 );
+                else
+                    cp = strtoul( psz_value + 2, &psz_end, 10 );
+
                 if( *psz_end == ';' )
                 {
                     psz_value = psz_end + 1;
@@ -493,312 +499,331 @@ char *str_format_time( const char *tformat )
         }
         free (str);
     }
-    assert (0);
+    vlc_assert_unreachable ();
 }
 
-static void format_duration (char *buf, size_t len, int64_t duration)
+static void write_duration(FILE *stream, int64_t duration)
 {
     lldiv_t d;
-    int sec;
+    long long sec;
 
     duration /= CLOCK_FREQ;
-    d = lldiv (duration, 60);
+    d = lldiv(duration, 60);
     sec = d.rem;
-    d = lldiv (d.quot, 60);
-    snprintf (buf, len, "%02lld:%02d:%02d", d.quot, (int)d.rem, sec);
+    d = lldiv(d.quot, 60);
+    fprintf(stream, "%02lld:%02lld:%02lld", d.quot, d.rem, sec);
 }
 
-#define INSERT_STRING( string )                                     \
-                    if( string != NULL )                            \
-                    {                                               \
-                        size_t len = strlen( string );              \
-                        dst = xrealloc( dst, i_size = i_size + len );\
-                        memcpy( (dst+d), string, len );             \
-                        d += len;                                   \
-                        free( string );                             \
-                    }
+static int write_meta(FILE *stream, input_item_t *item, vlc_meta_type_t type)
+{
+    if (item == NULL)
+        return EOF;
 
-/* same than INSERT_STRING, except that string won't be freed */
-#define INSERT_STRING_NO_FREE( string )                             \
-                    {                                               \
-                        size_t len = strlen( string );              \
-                        dst = xrealloc( dst, i_size = i_size + len );\
-                        memcpy( dst+d, string, len );               \
-                        d += len;                                   \
-                    }
-char *str_format_meta( playlist_t *p_playlist, const char *s )
+    char *value = input_item_GetMeta(item, type);
+    if (value == NULL)
+        return EOF;
+
+    int ret = fputs(value, stream);
+    free(value);
+    return ret;
+}
+
+char *str_format_meta(input_thread_t *input, const char *s)
 {
-    char *dst = strdup( s );
-    if( unlikely(dst == NULL) )
+    char *str;
+    size_t len;
+#ifdef HAVE_OPEN_MEMSTREAM
+    FILE *stream = open_memstream(&str, &len);
+#elif defined( _WIN32 )
+    FILE *stream = vlc_win32_tmpfile();
+#else
+    FILE *stream = tmpfile();
+#endif
+    if (stream == NULL)
         return NULL;
 
-    input_thread_t *p_input = playlist_CurrentInput( p_playlist );
-    input_item_t *p_item = p_input ? input_GetItem(p_input) : NULL;
-    size_t i_size = strlen( s ) + 1; /* +1 to store '\0' */
-    size_t d = 0;
+    input_item_t *item = (input != NULL) ? input_GetItem(input) : NULL;
 
+    char c;
     bool b_is_format = false;
     bool b_empty_if_na = false;
-    char buf[10];
 
-    while( *s )
+    while ((c = *s) != '\0')
     {
-        if( b_is_format )
+        s++;
+
+        if (!b_is_format)
         {
-            switch( *s )
+            if (c == '$')
             {
-                case 'a':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetArtist( p_item ) );
-                    break;
-                case 'b':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetAlbum( p_item ) );
-                    break;
-                case 'c':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetCopyright( p_item ) );
-                    break;
-                case 'd':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetDescription( p_item ) );
-                    break;
-                case 'e':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetEncodedBy( p_item ) );
-                    break;
-                case 'f':
-                    if( p_item && p_item->p_stats )
-                    {
-                        vlc_mutex_lock( &p_item->p_stats->lock );
-                        snprintf( buf, 10, "%"PRIi64,
-                                  p_item->p_stats->i_displayed_pictures );
-                        vlc_mutex_unlock( &p_item->p_stats->lock );
-                    }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'g':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetGenre( p_item ) );
-                    break;
-                case 'l':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetLanguage( p_item ) );
-                    break;
-                case 'n':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetTrackNum( p_item ) );
-                    break;
-                case 'p':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetNowPlaying( p_item ) );
-                    break;
-                case 'r':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetRating( p_item ) );
+                b_is_format = true;
+                b_empty_if_na = false;
+                continue;
+            }
+
+            fputc(c, stream);
+            continue;
+        }
+
+        b_is_format = false;
+
+        switch (c)
+        {
+            case 'a':
+                write_meta(stream, item, vlc_meta_Artist);
+                break;
+            case 'b':
+                write_meta(stream, item, vlc_meta_Album);
+                break;
+            case 'c':
+                write_meta(stream, item, vlc_meta_Copyright);
+                break;
+            case 'd':
+                write_meta(stream, item, vlc_meta_Description);
+                break;
+            case 'e':
+                write_meta(stream, item, vlc_meta_EncodedBy);
+                break;
+            case 'f':
+                if (item != NULL && item->p_stats != NULL)
+                {
+                    vlc_mutex_lock(&item->p_stats->lock);
+                    fprintf(stream, "%"PRIi64,
+                            item->p_stats->i_displayed_pictures);
+                    vlc_mutex_unlock(&item->p_stats->lock);
+                }
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'g':
+                write_meta(stream, item, vlc_meta_Genre);
+                break;
+            case 'l':
+                write_meta(stream, item, vlc_meta_Language);
+                break;
+            case 'n':
+                write_meta(stream, item, vlc_meta_TrackNumber);
+                break;
+            case 'p':
+                if (item == NULL)
                     break;
-                case 's':
-                    {
-                        char *psz_lang = NULL;
-                        if( p_input )
-                            psz_lang = var_GetNonEmptyString( p_input, "sub-language" );
-                        if( psz_lang == NULL )
-                            psz_lang = strdup( b_empty_if_na ? "" : "-" );
-                        INSERT_STRING( psz_lang );
+                {
+                    char *value = input_item_GetNowPlayingFb(item);
+                    if (value == NULL)
                         break;
-                    }
-                case 't':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetTitle( p_item ) );
-                    break;
-                case 'u':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetURL( p_item ) );
-                    break;
-                case 'A':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetDate( p_item ) );
-                    break;
-                case 'B':
-                    if( p_input )
-                        snprintf( buf, 10, "%"PRId64,
-                                  var_GetInteger( p_input, "bit-rate" )/1000 );
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'C':
-                    if( p_input )
-                        snprintf( buf, 10, "%"PRId64,
-                                  var_GetInteger( p_input, "chapter" ) );
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'D':
-                    if( p_item )
-                    {
-                        mtime_t i_duration = input_item_GetDuration( p_item );
-                        format_duration (buf, sizeof (buf), i_duration);
-                    }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "--:--:--" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'F':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetURI( p_item ) );
-                    break;
-                case 'I':
-                    if( p_input )
-                        snprintf( buf, 10, "%"PRId64,
-                                  var_GetInteger( p_input, "title" ) );
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'L':
-                    if( p_item && p_input )
-                    {
-                        mtime_t i_duration = input_item_GetDuration( p_item );
-                        int64_t i_time = var_GetTime( p_input, "time" );
-                        format_duration( buf, sizeof(buf),
-                                         i_duration - i_time );
-                    }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "--:--:--" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'N':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetName( p_item ) );
-                    break;
-                case 'O':
+
+                    fputs(value, stream);
+                    free(value);
+                }
+                break;
+            case 'r':
+                write_meta(stream, item, vlc_meta_Rating);
+                break;
+            case 's':
+            {
+                char *lang = NULL;
+
+                if (input != NULL)
+                    lang = var_GetNonEmptyString(input, "sub-language");
+                if (lang != NULL)
                 {
-                    char *lang = NULL;
-                    if( p_input )
-                        lang = var_GetNonEmptyString( p_input,
-                                                      "audio-language" );
-                    if( lang == NULL )
-                        lang = strdup( b_empty_if_na ? "" : "-" );
-                    INSERT_STRING( lang );
-                    break;
+                    fputs(lang, stream);
+                    free(lang);
                 }
-                case 'P':
-                    if( p_input )
-                        snprintf( buf, 10, "%2.1lf",
-                                  var_GetFloat( p_input, "position" ) * 100. );
-                    else
-                        snprintf( buf, 10, b_empty_if_na ? "" : "--.-%%" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'R':
-                    if( p_input )
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            }
+            case 't':
+                write_meta(stream, item, vlc_meta_Title);
+                break;
+            case 'u':
+                write_meta(stream, item, vlc_meta_URL);
+                break;
+            case 'A':
+                write_meta(stream, item, vlc_meta_Date);
+                break;
+            case 'B':
+                if (input != NULL)
+                    fprintf(stream, "%"PRId64,
+                            var_GetInteger(input, "bit-rate") / 1000);
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'C':
+                if (input != NULL)
+                    fprintf(stream, "%"PRId64,
+                            var_GetInteger(input, "chapter"));
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'D':
+                if (item != NULL)
+                    write_duration(stream, input_item_GetDuration(item));
+                else if (!b_empty_if_na)
+                    fputs("--:--:--", stream);
+                break;
+            case 'F':
+                if (item != NULL)
+                {
+                    char *uri = input_item_GetURI(item);
+                    if (uri != NULL)
                     {
-                        float f = var_GetFloat( p_input, "rate" );
-                        snprintf( buf, 10, "%.3f", f );
+                        fputs(uri, stream);
+                        free(uri);
                     }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'S':
-                    if( p_input )
+                }
+                break;
+            case 'I':
+                if (input != NULL)
+                    fprintf(stream, "%"PRId64, var_GetInteger(input, "title"));
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'L':
+                if (item != NULL)
+                {
+                    assert(input != NULL);
+                    write_duration(stream, input_item_GetDuration(item)
+                                   - var_GetTime(input, "time"));
+                }
+                else if (!b_empty_if_na)
+                    fputs("--:--:--", stream);
+                break;
+            case 'N':
+                if (item != NULL)
+                {
+                    char *name = input_item_GetName(item);
+                    if (name != NULL)
                     {
-                        int r = var_GetInteger( p_input, "sample-rate" );
-                        snprintf( buf, 10, "%d.%d", r/1000, (r/100)%10 );
+                        fputs(name, stream);
+                        free(name);
                     }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "-" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'T':
-                    if( p_input )
+                }
+                break;
+            case 'O':
+            {
+                char *lang = NULL;
+
+                if (input != NULL)
+                    lang = var_GetNonEmptyString(input, "audio-language");
+                if (lang != NULL)
+                {
+                    fputs(lang, stream);
+                    free(lang);
+                }
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            }
+            case 'P':
+                if (input != NULL)
+                    fprintf(stream, "%2.1f",
+                            var_GetFloat(input, "position") * 100.f);
+                else if (!b_empty_if_na)
+                    fputs("--.-%", stream);
+                break;
+            case 'R':
+                if (input != NULL)
+                    fprintf(stream, "%.3f", var_GetFloat(input, "rate"));
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'S':
+                if (input != NULL)
+                {
+                    int rate = var_GetInteger(input, "sample-rate");
+                    div_t dr = div((rate + 50) / 100, 10);
+
+                    fprintf(stream, "%d.%01d", dr.quot, dr.rem);
+                }
+                else if (!b_empty_if_na)
+                    fputc('-', stream);
+                break;
+            case 'T':
+                if (input != NULL)
+                    write_duration(stream, var_GetTime(input, "time"));
+                else if (!b_empty_if_na)
+                    fputs("--:--:--", stream);
+                break;
+            case 'U':
+                write_meta(stream, item, vlc_meta_Publisher);
+                break;
+            case 'V':
+            {
+                float vol = 0.f;
+
+                if (input != NULL)
+                {
+                    audio_output_t *aout = input_GetAout(input);
+                    if (aout != NULL)
                     {
-                        int64_t i_time = var_GetTime( p_input, "time" );
-                        format_duration( buf, sizeof(buf), i_time );
+                        vol = aout_VolumeGet(aout);
+                        vlc_object_release(aout);
                     }
-                    else
-                        strcpy( buf, b_empty_if_na ? "" : "--:--:--" );
-                    INSERT_STRING_NO_FREE( buf );
-                    break;
-                case 'U':
-                    if( p_item )
-                        INSERT_STRING( input_item_GetPublisher( p_item ) );
+                }
+                if (vol >= 0.f)
+                    fprintf(stream, "%ld", lroundf(vol * 256.f));
+                else if (!b_empty_if_na)
+                    fputs("---", stream);
+                break;
+            }
+            case '_':
+                fputc('\n', stream);
+                break;
+            case 'Z':
+                if (item == NULL)
                     break;
-                case 'V':
                 {
-                    float vol = playlist_VolumeGet( p_object );
-                    if( vol >= 0.f )
+                    char *value = input_item_GetNowPlayingFb(item);
+                    if (value != NULL)
                     {
-                        snprintf( buf, 10, "%ld",
-                                  lroundf(vol * AOUT_VOLUME_DEFAULT ) );
-                        INSERT_STRING_NO_FREE( buf );
+                        fputs(value, stream);
+                        free(value);
                     }
                     else
-                         INSERT_STRING_NO_FREE( "---" );
-                    break;
-                }
-                case '_':
-                    *(dst+d) = '\n';
-                    d++;
-                    break;
-                case 'Z':
-                    if( p_item )
                     {
-                        char *psz_now_playing = input_item_GetNowPlaying( p_item );
-                        if( EMPTY_STR( psz_now_playing ) )
+                        char *title = input_item_GetTitleFbName(item);
+
+                        if (write_meta(stream, item, vlc_meta_Artist) >= 0
+                            && title != NULL)
+                            fputs(" - ", stream);
+
+                        if (title != NULL)
                         {
-                            char *psz_temp = input_item_GetTitleFbName( p_item );
-                            char *psz_artist = input_item_GetArtist( p_item );
-                            if( !EMPTY_STR( psz_artist ) )
-                            {
-                                INSERT_STRING( psz_artist );
-                                if ( !EMPTY_STR( psz_temp ) )
-                                    INSERT_STRING_NO_FREE( " - " );
-                            }
-                            INSERT_STRING( psz_temp );
+                            fputs(title, stream);
+                            free(title);
                         }
-                        else
-                            INSERT_STRING( psz_now_playing );
                     }
-                    break;
-
-                case ' ':
-                    b_empty_if_na = true;
-                    break;
-
-                default:
-                    *(dst+d) = *s;
-                    d++;
-                    break;
-            }
-            if( *s != ' ' )
-                b_is_format = false;
-        }
-        else if( *s == '$' )
-        {
-            b_is_format = true;
-            b_empty_if_na = false;
-        }
-        else
-        {
-            *(dst+d) = *s;
-            d++;
+                }
+                break;
+            case ' ':
+                b_empty_if_na = true;
+                b_is_format = true;
+                break;
+            default:
+                fputc(c, stream);
+                break;
         }
-        s++;
     }
-    *(dst+d) = '\0';
-
-    if( p_input )
-        vlc_object_release( p_input );
 
-    return dst;
+#ifdef HAVE_OPEN_MEMSTREAM
+    return (fclose(stream) == 0) ? str : NULL;
+#else
+    len = ftell(stream);
+    if (len != (size_t)-1)
+    {
+        rewind(stream);
+        str = xmalloc(len + 1);
+        fread(str, len, 1, stream);
+        str[len] = '\0';
+    }
+    else
+        str = NULL;
+    fclose(stream);
+    return str;
+#endif
 }
-#undef INSERT_STRING
-#undef INSERT_STRING_NO_FREE
 
 /**
  * Remove forbidden, potentially forbidden and otherwise evil characters from
@@ -903,7 +928,7 @@ time_t str_duration( const char *psz_duration )
         return -1;
     do
     {
-        double number = strtod( psz_duration, &end_ptr );
+        double number = us_strtod( psz_duration, &end_ptr );
         double      mul = 0;
         if ( psz_duration != end_ptr )
             psz_duration = end_ptr;