+
+/****************************************************************************
+ * String formating functions
+ ****************************************************************************/
+char *str_format_time(char *tformat )
+{
+ char buffer[255];
+ time_t curtime;
+#if defined(HAVE_LOCALTIME_R)
+ struct tm loctime;
+#else
+ struct tm *loctime;
+#endif
+
+ /* Get the current time. */
+ curtime = time( NULL );
+
+ /* Convert it to local time representation. */
+#if defined(HAVE_LOCALTIME_R)
+ localtime_r( &curtime, &loctime );
+ strftime( buffer, 255, tformat, &loctime );
+#else
+ loctime = localtime( &curtime );
+ strftime( buffer, 255, tformat, loctime );
+#endif
+ return strdup( buffer );
+}
+
+#define INSERT_STRING( check, string ) \
+ if( check && string ) \
+ { \
+ int len = strlen( string ); \
+ dst = realloc( dst, \
+ i_size = i_size + len + 1 ); \
+ strncpy( d, string, len+1 ); \
+ d += len; \
+ } \
+ else \
+ { \
+ *d = '-'; \
+ d++; \
+ }
+char *__str_format_meta( vlc_object_t *p_object, char *string )
+{
+ char *s = string;
+ char *dst = malloc( 1000 );
+ char *d = dst;
+ int b_is_format = 0;
+ char buf[10];
+ int i_size = strlen( string );
+
+ playlist_t *p_playlist = pl_Yield( p_object );
+ input_thread_t *p_input = p_playlist->p_input;
+ input_item_t *p_item = NULL;
+ pl_Release( p_object );
+ if( p_input )
+ {
+ vlc_object_yield( p_input );
+ p_item = p_input->input.p_item;
+ if( p_item )
+ vlc_mutex_lock( &p_item->lock );
+ }
+
+ sprintf( dst, string );
+
+ while( *s )
+ {
+ if( b_is_format )
+ {
+ switch( *s )
+ {
+ case 'a':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_artist );
+ break;
+ case 'b':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_album );
+ break;
+ case 'c':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_copyright );
+ break;
+ case 'd':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_description );
+ break;
+ case 'e':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_encodedby );
+ break;
+ case 'g':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_genre );
+ break;
+ case 'l':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_language );
+ break;
+ case 'n':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_tracknum );
+ break;
+ case 'p':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_nowplaying );
+ break;
+ case 'r':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_rating );
+ break;
+ case 's':
+ {
+ char *lang;
+ if( p_input )
+ {
+ lang = var_GetString( p_input, "sub-language" );
+ }
+ else
+ {
+ lang = strdup( "-" );
+ }
+ INSERT_STRING( 1, lang );
+ free( lang );
+ break;
+ }
+ case 't':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_title );
+ break;
+ case 'u':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_url );
+ break;
+ case 'A':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_date );
+ break;
+ case 'B':
+ if( p_input )
+ {
+ snprintf( buf, 10, "%d",
+ var_GetInteger( p_input, "bit-rate" )/1000 );
+ }
+ else
+ {
+ sprintf( buf, "-" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'C':
+ if( p_input )
+ {
+ snprintf( buf, 10, "%d",
+ var_GetInteger( p_input, "chapter" ) );
+ }
+ else
+ {
+ sprintf( buf, "-" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'D':
+ if( p_item )
+ {
+ sprintf( buf, "%02d:%02d:%02d",
+ (int)(p_item->i_duration/(3600000000)),
+ (int)((p_item->i_duration/(60000000))%60),
+ (int)((p_item->i_duration/1000000)%60) );
+ }
+ else
+ {
+ sprintf( buf, "--:--:--" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'F':
+ INSERT_STRING( p_item, p_item->psz_uri );
+ break;
+ case 'I':
+ if( p_input )
+ {
+ snprintf( buf, 10, "%d",
+ var_GetInteger( p_input, "title" ) );
+ }
+ else
+ {
+ sprintf( buf, "-" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'L':
+ if( p_item && p_input )
+ {
+ sprintf( buf, "%02d:%02d:%02d",
+ (int)((p_item->i_duration-p_input->i_time)/(3600000000)),
+ (int)(((p_item->i_duration-p_input->i_time)/(60000000))%60),
+ (int)(((p_item->i_duration-p_input->i_time)/1000000)%60) );
+ }
+ else
+ {
+ sprintf( buf, "--:--:--" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'N':
+ INSERT_STRING( p_item, p_item->psz_name );
+ break;
+ case 'O':
+ {
+ char *lang;
+ if( p_input )
+ {
+ lang = var_GetString( p_input, "audio-language" );
+ }
+ else
+ {
+ lang = strdup( "-" );
+ }
+ INSERT_STRING( 1, lang );
+ free( lang );
+ break;
+ }
+ case 'P':
+ if( p_input )
+ {
+ snprintf( buf, 10, "%2.1lf",
+ var_GetFloat( p_input, "position" ) * 100. );
+ }
+ else
+ {
+ sprintf( buf, "--.-%%" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'R':
+ if( p_input )
+ {
+ int r = var_GetInteger( p_input, "rate" );
+ snprintf( buf, 10, "%d.%d", r/1000, r%1000 );
+ }
+ else
+ {
+ sprintf( buf, "-" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'S':
+ if( p_input )
+ {
+ int r = var_GetInteger( p_input, "sample-rate" );
+ snprintf( buf, 10, "%d.%d", r/1000, (r/100)%10 );
+ }
+ else
+ {
+ sprintf( buf, "-" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'T':
+ if( p_input )
+ {
+ sprintf( buf, "%02d:%02d:%02d",
+ (int)(p_input->i_time/(3600000000)),
+ (int)((p_input->i_time/(60000000))%60),
+ (int)((p_input->i_time/1000000)%60) );
+ }
+ else
+ {
+ sprintf( buf, "--:--:--" );
+ }
+ INSERT_STRING( 1, buf );
+ break;
+ case 'U':
+ INSERT_STRING( p_item && p_item->p_meta,
+ p_item->p_meta->psz_publisher );
+ break;
+ case 'V':
+ {
+ audio_volume_t volume;
+ aout_VolumeGet( p_object, &volume );
+ snprintf( buf, 10, "%d", volume );
+ INSERT_STRING( 1, buf );
+ break;
+ }
+ case '_':
+ *d = '\n';
+ d++;
+ break;
+
+ default:
+ *d = *s;
+ d++;
+ break;
+ }
+ b_is_format = 0;
+ }
+ else if( *s == '$' )
+ {
+ b_is_format = 1;
+ }
+ else
+ {
+ *d = *s;
+ d++;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ if( p_input )
+ {
+ vlc_object_release( p_input );
+ if( p_item )
+ vlc_mutex_unlock( &p_item->lock );
+ }
+
+ return dst;
+}