Mercurial > audlegacy
changeset 3513:d74a68871159 trunk
Automated merge with ssh://hg.atheme.org//hg/audacious-tc
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Tue, 11 Sep 2007 09:14:15 -0500 |
parents | 69be01c2f6b6 (current diff) 6f8005df972f (diff) |
children | 331bfc72ef66 |
files | |
diffstat | 13 files changed, 436 insertions(+), 289 deletions(-) [+] |
line wrap: on
line diff
--- a/src/audacious/dbus.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/dbus.c Tue Sep 11 09:14:15 2007 -0500 @@ -178,16 +178,16 @@ GValue *tuple_value_to_gvalue(Tuple *tuple, const gchar *key) { GValue *val; TupleValueType type; - type = tuple_get_value_type(tuple, key); + type = tuple_get_value_type(tuple, -1, key); if (type == TUPLE_STRING) { val = g_new0(GValue, 1); g_value_init(val, G_TYPE_STRING); - g_value_set_string(val, tuple_get_string(tuple, key)); + g_value_set_string(val, tuple_get_string(tuple, -1, key)); return val; } else if (type == TUPLE_INT) { val = g_new0(GValue, 1); g_value_init(val, G_TYPE_INT); - g_value_set_int(val, tuple_get_int(tuple, key)); + g_value_set_int(val, tuple_get_int(tuple, -1, key)); return val; } return NULL; @@ -709,17 +709,17 @@ if (!tuple) { return FALSE; } else { - TupleValueType type = tuple_get_value_type(tuple, field); + TupleValueType type = tuple_get_value_type(tuple, -1, field); switch(type) { case TUPLE_STRING: g_value_init(value, G_TYPE_STRING); - g_value_set_string(value, tuple_get_string(tuple, field)); + g_value_set_string(value, tuple_get_string(tuple, -1, field)); break; case TUPLE_INT: g_value_init(value, G_TYPE_INT); - g_value_set_int(value, tuple_get_int(tuple, field)); + g_value_set_int(value, tuple_get_int(tuple, -1, field)); break; default: return FALSE;
--- a/src/audacious/input.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/input.c Tue Sep 11 09:14:15 2007 -0500 @@ -433,7 +433,7 @@ pr = g_new0(ProbeResult, 1); pr->ip = ip; pr->tuple = tuple; - tuple_associate_int(pr->tuple, "mtime", input_get_mtime(filename_proxy)); + tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy)); return pr; } @@ -511,7 +511,7 @@ pr = g_new0(ProbeResult, 1); pr->ip = ip; pr->tuple = tuple; - tuple_associate_int(pr->tuple, "mtime", input_get_mtime(filename_proxy)); + tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy)); return pr; } @@ -574,6 +574,7 @@ playback->plugin->set_eq(on, preamp, bands); } + Tuple * input_get_song_tuple(const gchar * filename) { @@ -609,13 +610,13 @@ if ((ext = strrchr(tmp, '.'))) *ext = '\0'; - tuple_associate_string(input, "file-name", g_path_get_basename(tmp)); + tuple_associate_string(input, FIELD_FILE_NAME, NULL, g_path_get_basename(tmp)); if (ext) - tuple_associate_string(input, "file-ext", ext + 1); + tuple_associate_string(input, FIELD_FILE_EXT, NULL, ext + 1); - tuple_associate_string(input, "file-path", g_path_get_dirname(tmp)); - tuple_associate_int(input, "length", -1); + tuple_associate_string(input, FIELD_FILE_PATH, NULL, g_path_get_dirname(tmp)); + tuple_associate_int(input, FIELD_LENGTH, NULL, -1); g_free(tmp); }
--- a/src/audacious/playlist.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/playlist.c Tue Sep 11 09:14:15 2007 -0500 @@ -180,12 +180,8 @@ entry->tuple = NULL; } - if (entry->filename != NULL) - g_free(entry->filename); - - if (entry->title != NULL) - g_free(entry->title); - + g_free(entry->filename); + g_free(entry->title); mowgli_heap_free(playlist_entry_heap, entry); } @@ -199,7 +195,8 @@ g_return_val_if_fail(entry != NULL, FALSE); - if (entry->tuple == NULL || tuple_get_int(entry->tuple, "mtime") > 0 || tuple_get_int(entry->tuple, "mtime") == -1) + if (entry->tuple == NULL || tuple_get_int(entry->tuple, FIELD_MTIME, NULL) > 0 || + tuple_get_int(entry->tuple, FIELD_MTIME, NULL) == -1) modtime = playlist_get_mtime(entry->filename); else modtime = 0; /* URI -nenolod */ @@ -217,7 +214,7 @@ /* renew tuple if file mtime is newer than tuple mtime. */ if(entry->tuple){ - if(tuple_get_int(entry->tuple, "mtime") == modtime) + if(tuple_get_int(entry->tuple, FIELD_MTIME, NULL) == modtime) return TRUE; else { mowgli_object_unref(entry->tuple); @@ -234,13 +231,13 @@ return FALSE; /* attach mtime */ - tuple_associate_int(tuple, "mtime", modtime); + tuple_associate_int(tuple, FIELD_MTIME, NULL, modtime); /* entry is still around */ - formatter = tuple_get_string(tuple, "formatter"); + formatter = tuple_get_string(tuple, FIELD_FORMATTER, NULL); entry->title = tuple_formatter_make_title_string(tuple, formatter ? formatter : get_gentitle_format()); - entry->length = tuple_get_int(tuple, "length"); + entry->length = tuple_get_int(tuple, FIELD_LENGTH, NULL); entry->tuple = tuple; g_free(pr); @@ -675,7 +672,10 @@ g_return_if_fail(playlist != NULL); g_return_if_fail(filename != NULL); - entry = playlist_entry_new(filename, tuple ? tuple_get_string(tuple, "title") : NULL, tuple ? tuple_get_int(tuple, "length") : -1, dec); + entry = playlist_entry_new(filename, + tuple ? tuple_get_string(tuple, FIELD_TITLE, NULL) : NULL, + tuple ? tuple_get_int(tuple, FIELD_LENGTH, NULL) : -1, dec); + if(!playlist->tail) playlist->tail = g_list_last(playlist->entries); @@ -705,14 +705,14 @@ PLAYLIST_UNLOCK(playlist); if (tuple != NULL) { - const gchar *formatter = tuple_get_string(tuple, "formatter"); + const gchar *formatter = tuple_get_string(tuple, FIELD_FORMATTER, NULL); entry->title = tuple_formatter_make_title_string(tuple, formatter ? formatter : get_gentitle_format()); - entry->length = tuple_get_int(tuple, "length"); + entry->length = tuple_get_int(tuple, FIELD_LENGTH, NULL); entry->tuple = tuple; } - if(tuple != NULL && tuple_get_int(tuple, "mtime") == -1) { // kick the scanner thread only if mtime = -1 (uninitialized). + if(tuple != NULL && tuple_get_int(tuple, FIELD_MTIME, NULL) == -1) { // kick the scanner thread only if mtime = -1 (uninitialized). g_mutex_lock(mutex_scan); playlist_get_info_scan_active = TRUE; g_mutex_unlock(mutex_scan); @@ -1078,9 +1078,9 @@ playlist->position->length = length; // overwrite tuple::title, mainly for streaming. it may incur side effects. --yaz - if(playlist->position->tuple && tuple_get_int(playlist->position->tuple, "length") == -1){ - tuple_disassociate(playlist->position->tuple, "title"); - tuple_associate_string(playlist->position->tuple, "title", title); + if(playlist->position->tuple && tuple_get_int(playlist->position->tuple, FIELD_LENGTH, NULL) == -1){ + tuple_disassociate(playlist->position->tuple, FIELD_TITLE, NULL); + tuple_associate_string(playlist->position->tuple, FIELD_TITLE, NULL, title); } } @@ -1893,7 +1893,7 @@ entry = node->data; if (entry->tuple) - mtime = tuple_get_int(entry->tuple, "mtime"); + mtime = tuple_get_int(entry->tuple, FIELD_MTIME, NULL); else mtime = 0; @@ -1941,7 +1941,7 @@ tuple = entry->tuple; if (tuple) - mtime = tuple_get_int(tuple, "mtime"); + mtime = tuple_get_int(tuple, FIELD_MTIME, NULL); else mtime = 0; @@ -1974,7 +1974,7 @@ entry = node->data; if (entry->tuple) - mtime = tuple_get_int(entry->tuple, "mtime"); + mtime = tuple_get_int(entry->tuple, FIELD_MTIME, NULL); else mtime = 0; @@ -2011,8 +2011,8 @@ if (b->tuple == NULL) return 0; - tracknumber_a = tuple_get_int(a->tuple, "track-number"); - tracknumber_b = tuple_get_int(b->tuple, "track-number"); + tracknumber_a = tuple_get_int(a->tuple, FIELD_TRACK_NUMBER, NULL); + tracknumber_b = tuple_get_int(b->tuple, FIELD_TRACK_NUMBER, NULL); return (tracknumber_a && tracknumber_b ? tracknumber_a - tracknumber_b : 0); @@ -2063,9 +2063,9 @@ playlist_entry_get_info(b); if (a->tuple != NULL) - a_title = tuple_get_string(a->tuple, "title"); + a_title = tuple_get_string(a->tuple, FIELD_TITLE, NULL); if (b->tuple != NULL) - b_title = tuple_get_string(b->tuple, "title"); + b_title = tuple_get_string(b->tuple, FIELD_TITLE, NULL); if (a_title != NULL && b_title != NULL) return strcasecmp(a_title, b_title); @@ -2107,13 +2107,13 @@ playlist_entry_get_info(b); if (a->tuple != NULL) { - a_artist = tuple_get_string(a->tuple, "artist"); + a_artist = tuple_get_string(a->tuple, FIELD_ARTIST, NULL); if (str_has_prefix_nocase(a_artist, "the ")) a_artist += 4; } if (b->tuple != NULL) { - b_artist = tuple_get_string(b->tuple, "artist"); + b_artist = tuple_get_string(b->tuple, FIELD_ARTIST, NULL); if (str_has_prefix_nocase(b_artist, "the ")) b_artist += 4; } @@ -2469,7 +2469,7 @@ PLAYLIST_UNLOCK(playlist); if (entry->tuple) - mtime = tuple_get_int(entry->tuple, "mtime"); + mtime = tuple_get_int(entry->tuple, FIELD_MTIME, NULL); else mtime = 0; @@ -2601,7 +2601,8 @@ entry = node->data; if(playlist->attribute & PLAYLIST_STATIC || - (entry->tuple && tuple_get_int(entry->tuple, "length") > -1 && tuple_get_int(entry->tuple, "mtime") != -1)) { + (entry->tuple && tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 && + tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1)) { update_playlistwin = TRUE; continue; } @@ -2643,7 +2644,8 @@ entry = node->data; if(playlist->attribute & PLAYLIST_STATIC || - (entry->tuple && tuple_get_int(entry->tuple, "length") > -1 && tuple_get_int(entry->tuple, "mtime") != -1)) { + (entry->tuple && tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 && + tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1)) { update_playlistwin = TRUE; continue; } @@ -2972,32 +2974,35 @@ GList *entry_list = NULL, *found_list = NULL, *sel_list = NULL; gboolean is_first_search = TRUE; gint num_of_entries_found = 0; - - #if defined(USE_REGEX_ONIGURUMA) + const gchar *regex_pattern; + const gchar *track_name = tuple_get_string( tuple, FIELD_TITLE, NULL ); + const gchar *album_name = tuple_get_string( tuple, FIELD_ALBUM, NULL ); + const gchar *performer = tuple_get_string( tuple, FIELD_PERFORMER, NULL ); + const gchar *file_name = tuple_get_string( tuple, FIELD_FILE_NAME, NULL ); + +#if defined(USE_REGEX_ONIGURUMA) /* set encoding for Oniguruma regex to UTF-8 */ reg_set_encoding( REG_POSIX_ENCODING_UTF8 ); onig_set_default_syntax( ONIG_SYNTAX_POSIX_BASIC ); - #endif +#endif PLAYLIST_LOCK(playlist); - if ( tuple_get_string(tuple, "title") != NULL ) + if ( (regex_pattern = tuple_get_string(tuple, FIELD_TITLE, NULL)) != NULL ) { /* match by track_name */ - const gchar *regex_pattern = tuple_get_string(tuple, "title"); regex_t regex; - #if defined(USE_REGEX_PCRE) +#if defined(USE_REGEX_PCRE) if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE | REG_UTF8 ) == 0 ) - #else +#else if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE ) == 0 ) - #endif +#endif { GList *tfound_list = NULL; if ( is_first_search == TRUE ) entry_list = playlist->entries; else entry_list = found_list; /* use found_list */ for ( ; entry_list ; entry_list = g_list_next(entry_list) ) { - const gchar *track_name = tuple_get_string( tuple, "title" ); PlaylistEntry *entry = entry_list->data; if ( ( entry->tuple != NULL ) && ( track_name != NULL ) && ( regexec( ®ex , track_name , 0 , NULL , 0 ) == 0 ) ) @@ -3012,23 +3017,21 @@ is_first_search = FALSE; } - if ( tuple_get_string(tuple, "album") != NULL ) + if ( (regex_pattern = tuple_get_string(tuple, FIELD_ALBUM, NULL)) != NULL ) { /* match by album_name */ - const gchar *regex_pattern = tuple_get_string(tuple, "album"); regex_t regex; - #if defined(USE_REGEX_PCRE) +#if defined(USE_REGEX_PCRE) if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE | REG_UTF8 ) == 0 ) - #else +#else if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE ) == 0 ) - #endif +#endif { GList *tfound_list = NULL; if ( is_first_search == TRUE ) entry_list = playlist->entries; else entry_list = found_list; /* use found_list */ for ( ; entry_list ; entry_list = g_list_next(entry_list) ) { - const gchar *album_name = tuple_get_string( tuple, "album" ); PlaylistEntry *entry = entry_list->data; if ( ( entry->tuple != NULL ) && ( album_name != NULL ) && ( regexec( ®ex , album_name , 0 , NULL , 0 ) == 0 ) ) @@ -3043,23 +3046,21 @@ is_first_search = FALSE; } - if ( tuple_get_string(tuple, "artist") != NULL ) + if ( (regex_pattern = tuple_get_string(tuple, FIELD_ARTIST, NULL)) != NULL ) { /* match by performer */ - const gchar *regex_pattern = tuple_get_string(tuple, "artist"); regex_t regex; - #if defined(USE_REGEX_PCRE) +#if defined(USE_REGEX_PCRE) if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE | REG_UTF8 ) == 0 ) - #else +#else if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE ) == 0 ) - #endif +#endif { GList *tfound_list = NULL; if ( is_first_search == TRUE ) entry_list = playlist->entries; else entry_list = found_list; /* use found_list */ for ( ; entry_list ; entry_list = g_list_next(entry_list) ) { - const gchar *performer = tuple_get_string( tuple, "performer" ); PlaylistEntry *entry = entry_list->data; if ( ( entry->tuple != NULL ) && ( performer != NULL ) && ( regexec( ®ex , performer , 0 , NULL , 0 ) == 0 ) ) @@ -3074,23 +3075,21 @@ is_first_search = FALSE; } - if ( tuple_get_string(tuple, "file-name") != NULL ) + if ( (regex_pattern = tuple_get_string(tuple, FIELD_FILE_NAME, NULL)) != NULL ) { /* match by file_name */ - const gchar *regex_pattern = tuple_get_string(tuple, "file-name"); regex_t regex; - #if defined(USE_REGEX_PCRE) +#if defined(USE_REGEX_PCRE) if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE | REG_UTF8 ) == 0 ) - #else +#else if ( regcomp( ®ex , regex_pattern , REG_NOSUB | REG_ICASE ) == 0 ) - #endif +#endif { GList *tfound_list = NULL; if ( is_first_search == TRUE ) entry_list = playlist->entries; else entry_list = found_list; /* use found_list */ for ( ; entry_list ; entry_list = g_list_next(entry_list) ) { - const gchar *file_name = tuple_get_string( tuple, "file-name" ); PlaylistEntry *entry = entry_list->data; if ( ( entry->tuple != NULL ) && ( file_name != NULL ) && ( regexec( ®ex , file_name , 0 , NULL , 0 ) == 0 ) ) @@ -3219,7 +3218,7 @@ /* invalidate mtime to reread */ if (entry->tuple != NULL) - tuple_associate_int(entry->tuple, "mtime", -1); /* -1 denotes "non-initialized". now 0 is for stream etc. yaz */ + tuple_associate_int(entry->tuple, FIELD_MTIME, NULL, -1); /* -1 denotes "non-initialized". now 0 is for stream etc. yaz */ if (!playlist_entry_get_info(entry)) { if (g_list_index(playlist->entries, entry) == -1)
--- a/src/audacious/plugin.h Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/plugin.h Tue Sep 11 09:14:15 2007 -0500 @@ -53,8 +53,8 @@ #define LOWLEVEL_PLUGIN(x) ((LowlevelPlugin *)(x)) #define __AUDACIOUS_NEWVFS__ -#define __AUDACIOUS_PLUGIN_API__ 5 -#define __AUDACIOUS_INPUT_PLUGIN_API__ 5 +#define __AUDACIOUS_PLUGIN_API__ 6 +#define __AUDACIOUS_INPUT_PLUGIN_API__ 6 typedef enum { FMT_U8,
--- a/src/audacious/tuple.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/tuple.c Tue Sep 11 09:14:15 2007 -0500 @@ -23,10 +23,37 @@ #include "tuple.h" +const TupleBasicType tuple_fields[FIELD_LAST] = { + { "artist", TUPLE_STRING }, + { "title", TUPLE_STRING }, + { "album", TUPLE_STRING }, + { "comment", TUPLE_STRING }, + { "genre", TUPLE_STRING }, + + { "track", TUPLE_STRING }, + { "track-number", TUPLE_INT }, + { "length", TUPLE_INT }, + { "year", TUPLE_INT }, + { "quality", TUPLE_STRING }, + + { "codec", TUPLE_STRING }, + { "file-name", TUPLE_STRING }, + { "file-path", TUPLE_STRING }, + { "file-ext", TUPLE_STRING }, + { "song-artist", TUPLE_STRING }, + + { "mtime", TUPLE_INT }, + { "formatter", TUPLE_STRING }, + { "performer", TUPLE_STRING }, + { "copyright", TUPLE_STRING }, + { "date", TUPLE_STRING }, +}; + static mowgli_heap_t *tuple_heap = NULL; static mowgli_heap_t *tuple_value_heap = NULL; static mowgli_object_class_t tuple_klass; + #define TUPLE_LOCKING //#define TUPLE_DEBUG @@ -92,12 +119,12 @@ /* FIXME: use mowgli_object_bless_from_class() in mowgli 0.4 when it is released --nenolod */ tuple = mowgli_heap_alloc(tuple_heap); + memset(tuple, 0, sizeof(Tuple)); mowgli_object_init(mowgli_object(tuple), NULL, &tuple_klass, NULL); tuple->dict = mowgli_dictionary_create(g_ascii_strcasecmp); TUPLE_UNLOCK_WRITE(); - return tuple; } @@ -116,11 +143,11 @@ realfn = g_filename_from_uri(filename, NULL, NULL); scratch = g_path_get_basename(realfn ? realfn : filename); - tuple_associate_string(tuple, "file-name", scratch); + tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, scratch); g_free(scratch); scratch = g_path_get_dirname(realfn ? realfn : filename); - tuple_associate_string(tuple, "file-path", scratch); + tuple_associate_string(tuple, FIELD_FILE_PATH, NULL, scratch); g_free(scratch); g_free(realfn); realfn = NULL; @@ -128,161 +155,227 @@ ext = strrchr(filename, '.'); if (ext != NULL) { ++ext; - tuple_associate_string(tuple, "file-ext", scratch); + tuple_associate_string(tuple, FIELD_FILE_EXT, NULL, scratch); } return tuple; } + +static gint tuple_get_nfield(const gchar *field) +{ + gint i; + for (i = 0; i < FIELD_LAST; i++) + if (!strcmp(field, tuple_fields[i].name)) + return i; + return -1; +} + + +static TupleValue * +tuple_associate_data(Tuple *tuple, const gint cnfield, const gchar *field, TupleValueType ftype) +{ + const gchar *tfield = field; + gint nfield = cnfield; + TupleValue *value = NULL; + + g_return_val_if_fail(tuple != NULL, NULL); + g_return_val_if_fail(cnfield < FIELD_LAST, NULL); + + /* Check for known fields */ + if (nfield < 0) { + nfield = tuple_get_nfield(field); + if (nfield >= 0) { + fprintf(stderr, "WARNING! FIELD_* not used for '%s'!\n", field); + } + } + + /* Check if field was known */ + if (nfield >= 0) { + tfield = tuple_fields[nfield].name; + value = tuple->values[nfield]; + + if (ftype != tuple_fields[nfield].type) { + /* FIXME! Convert values perhaps .. or not? */ + fprintf(stderr, "Invalid type for [%s](%d->%d), %d != %d\n", tfield, cnfield, nfield, ftype, tuple_fields[nfield].type); + //mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); + TUPLE_UNLOCK_WRITE(); + return NULL; + } + } else { + value = mowgli_dictionary_retrieve(tuple->dict, tfield); + } + + if (value != NULL) { + /* Value exists, just delete old associated data */ + if (value->type == TUPLE_STRING) { + g_free(value->value.string); + value->value.string = NULL; + } + } else { + /* Allocate a new value */ + value = mowgli_heap_alloc(tuple_value_heap); + value->type = ftype; + if (nfield >= 0) + tuple->values[nfield] = value; + else + mowgli_dictionary_add(tuple->dict, tfield, value); + } + + return value; +} + gboolean -tuple_associate_string(Tuple *tuple, const gchar *field, const gchar *string) +tuple_associate_string(Tuple *tuple, const gint nfield, const gchar *field, const gchar *string) { TupleValue *value; - g_return_val_if_fail(tuple != NULL, FALSE); - g_return_val_if_fail(field != NULL, FALSE); + TUPLE_LOCK_WRITE(); + if ((value = tuple_associate_data(tuple, nfield, field, TUPLE_STRING)) == NULL) + return FALSE; - TUPLE_LOCK_WRITE(); - if ((value = mowgli_dictionary_delete(tuple->dict, field))) - tuple_disassociate_now(value); - - if (string == NULL) { - TUPLE_UNLOCK_WRITE(); - return TRUE; - } + if (string == NULL) + value->value.string = NULL; + else + value->value.string = g_strdup(string); - value = mowgli_heap_alloc(tuple_value_heap); - value->type = TUPLE_STRING; - value->value.string = g_strdup(string); - - mowgli_dictionary_add(tuple->dict, field, value); TUPLE_UNLOCK_WRITE(); - return TRUE; } gboolean -tuple_associate_int(Tuple *tuple, const gchar *field, gint integer) +tuple_associate_int(Tuple *tuple, const gint nfield, const gchar *field, gint integer) { TupleValue *value; - - g_return_val_if_fail(tuple != NULL, FALSE); - g_return_val_if_fail(field != NULL, FALSE); - + TUPLE_LOCK_WRITE(); - if ((value = mowgli_dictionary_delete(tuple->dict, field))) - tuple_disassociate_now(value); + if ((value = tuple_associate_data(tuple, nfield, field, TUPLE_INT)) == NULL) + return FALSE; - value = mowgli_heap_alloc(tuple_value_heap); - value->type = TUPLE_INT; value->value.integer = integer; - - mowgli_dictionary_add(tuple->dict, field, value); + TUPLE_UNLOCK_WRITE(); - return TRUE; } void -tuple_disassociate_now(TupleValue *value) -{ - if (value->type == TUPLE_STRING) - g_free(value->value.string); - - mowgli_heap_free(tuple_value_heap, value); -} - -void -tuple_disassociate(Tuple *tuple, const gchar *field) +tuple_disassociate(Tuple *tuple, const gint cnfield, const gchar *field) { TupleValue *value; + gint nfield = cnfield; g_return_if_fail(tuple != NULL); - g_return_if_fail(field != NULL); + g_return_if_fail(nfield < FIELD_LAST); + + if (nfield < 0) + nfield = tuple_get_nfield(field); - /* why _delete()? because _delete() returns the dictnode's data on success */ TUPLE_LOCK_WRITE(); - value = mowgli_dictionary_delete(tuple->dict, field); - + if (nfield < 0) + /* why _delete()? because _delete() returns the dictnode's data on success */ + value = mowgli_dictionary_delete(tuple->dict, field); + else { + value = tuple->values[nfield]; + tuple->values[nfield] = NULL; + } + if (value == NULL) { TUPLE_UNLOCK_WRITE(); return; } - tuple_disassociate_now(value); + /* Free associated data */ + if (value->type == TUPLE_STRING) { + g_free(value->value.string); + value->value.string = NULL; + } + + mowgli_heap_free(tuple_value_heap, value); TUPLE_UNLOCK_WRITE(); } TupleValueType -tuple_get_value_type(Tuple *tuple, const gchar *field) +tuple_get_value_type(Tuple *tuple, const gint cnfield, const gchar *field) { - TupleValue *value; + TupleValueType type = TUPLE_UNKNOWN; + gint nfield = cnfield; g_return_val_if_fail(tuple != NULL, TUPLE_UNKNOWN); - g_return_val_if_fail(field != NULL, TUPLE_UNKNOWN); + g_return_val_if_fail(nfield < FIELD_LAST, TUPLE_UNKNOWN); + if (nfield < 0) + nfield = tuple_get_nfield(field); + TUPLE_LOCK_READ(); - value = mowgli_dictionary_retrieve(tuple->dict, field); + if (nfield < 0) { + TupleValue *value; + if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) != NULL) + type = value->type; + } else { + if (tuple->values[nfield]) + type = tuple->values[nfield]->type; + } + TUPLE_UNLOCK_READ(); - - if (value == NULL) - return TUPLE_UNKNOWN; - - return value->type; + return type; } const gchar * -tuple_get_string(Tuple *tuple, const gchar *field) +tuple_get_string(Tuple *tuple, const gint cnfield, const gchar *field) { TupleValue *value; - gchar *val; + gint nfield = cnfield; g_return_val_if_fail(tuple != NULL, NULL); - g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(nfield < FIELD_LAST, NULL); + if (nfield < 0) + nfield = tuple_get_nfield(field); + TUPLE_LOCK_READ(); - value = mowgli_dictionary_retrieve(tuple->dict, field); - - if (value == NULL) { + if (nfield < 0) + value = mowgli_dictionary_retrieve(tuple->dict, field); + else + value = tuple->values[nfield]; + + if (value) { + if (value->type != TUPLE_STRING) + mowgli_throw_exception_val(audacious.tuple.invalid_type_request, NULL); + + TUPLE_UNLOCK_READ(); + return value->value.string; + } else { TUPLE_UNLOCK_READ(); return NULL; } - - if (value->type != TUPLE_STRING) { - TUPLE_UNLOCK_READ(); - mowgli_throw_exception_val(audacious.tuple.invalid_type_request, NULL); - } - - val = value->value.string; - TUPLE_UNLOCK_READ(); - - return val; } -int -tuple_get_int(Tuple *tuple, const gchar *field) +gint +tuple_get_int(Tuple *tuple, const gint cnfield, const gchar *field) { TupleValue *value; - gint val; + gint nfield = cnfield; g_return_val_if_fail(tuple != NULL, 0); - g_return_val_if_fail(field != NULL, 0); + g_return_val_if_fail(nfield < FIELD_LAST, 0); + if (nfield < 0) + nfield = tuple_get_nfield(field); + TUPLE_LOCK_READ(); - value = mowgli_dictionary_retrieve(tuple->dict, field); - - if (value == NULL) { + if (nfield < 0) + value = mowgli_dictionary_retrieve(tuple->dict, field); + else + value = tuple->values[nfield]; + + if (value) { + if (value->type != TUPLE_INT) + mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); + + TUPLE_UNLOCK_READ(); + return value->value.integer; + } else { TUPLE_UNLOCK_READ(); return 0; } - - if (value->type != TUPLE_INT) { - TUPLE_UNLOCK_READ(); - mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); - } - - val = value->value.integer; - TUPLE_UNLOCK_READ(); - - return val; }
--- a/src/audacious/tuple.h Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/tuple.h Tue Sep 11 09:14:15 2007 -0500 @@ -24,11 +24,35 @@ #include <glib.h> #include <mowgli.h> -typedef struct _Tuple { - mowgli_object_t parent; - mowgli_dictionary_t *dict; -} Tuple; + +enum { + FIELD_ARTIST = 0, + FIELD_TITLE, + FIELD_ALBUM, + FIELD_COMMENT, + FIELD_GENRE, + + FIELD_TRACK, + FIELD_TRACK_NUMBER, + FIELD_LENGTH, + FIELD_YEAR, + FIELD_QUALITY, + FIELD_CODEC, + FIELD_FILE_NAME, + FIELD_FILE_PATH, + FIELD_FILE_EXT, + FIELD_SONG_ARTIST, + + FIELD_MTIME, + FIELD_FORMATTER, + FIELD_PERFORMER, + FIELD_COPYRIGHT, + FIELD_DATE, + + /* special field, must always be last */ + FIELD_LAST +}; typedef enum { TUPLE_STRING, @@ -37,6 +61,13 @@ } TupleValueType; typedef struct { + gchar *name; + TupleValueType type; +} TupleBasicType; + +extern const TupleBasicType tuple_fields[FIELD_LAST]; + +typedef struct { TupleValueType type; union { gchar *string; @@ -44,15 +75,22 @@ } value; } TupleValue; +typedef struct _Tuple { + mowgli_object_t parent; + mowgli_dictionary_t *dict; + TupleValue *values[FIELD_LAST]; +} Tuple; + + Tuple *tuple_new(void); Tuple *tuple_new_from_filename(const gchar *filename); -gboolean tuple_associate_string(Tuple *tuple, const gchar *field, const gchar *string); -gboolean tuple_associate_int(Tuple *tuple, const gchar *field, gint integer); -void tuple_disassociate(Tuple *tuple, const gchar *field); +gboolean tuple_associate_string(Tuple *tuple, const gint nfield, const gchar *field, const gchar *string); +gboolean tuple_associate_int(Tuple *tuple, const gint nfield, const gchar *field, gint integer); +void tuple_disassociate(Tuple *tuple, const gint nfield, const gchar *field); void tuple_disassociate_now(TupleValue *value); -TupleValueType tuple_get_value_type(Tuple *tuple, const gchar *field); -const gchar *tuple_get_string(Tuple *tuple, const gchar *field); -int tuple_get_int(Tuple *tuple, const gchar *field); +TupleValueType tuple_get_value_type(Tuple *tuple, const gint nfield, const gchar *field); +const gchar *tuple_get_string(Tuple *tuple, const gint nfield, const gchar *field); +gint tuple_get_int(Tuple *tuple, const gint nfield, const gchar *field); #define tuple_free(x) mowgli_object_unref(x); #endif
--- a/src/audacious/tuple_compiler.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/tuple_compiler.c Tue Sep 11 09:14:15 2007 -0500 @@ -19,28 +19,13 @@ */ /* - * What's this? - * ------------ - * Nothing really. A prototype / pseudo-C for an improved Tuple formatting - * system, where the format string is "compiled" into a tree structure, - * which can then be traversed fast while "evaluating". This file does - * not represent anything but some of my (ccr) ideas for the concept. - * - * The basic ideas are: - * 1) compiled structure for faster traversing - * 2) sub-expression removal / constant elimination - * 3) indexes and/or hashes for tuple entries for faster access - * 4) avoid expensive memory re-allocation - * - * and possibly 5) caching of certain things - * - * * TODO: * - implement definitions (${=foo,"baz"} ${=foo,1234}) * - implement functions * - implement handling of external expressions * - error handling issues? * - evaluation context: how local variables should REALLY work? + * currently there is just a single context, is a "global" context needed? */ #include "config.h" @@ -56,14 +41,14 @@ va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - exit(5); +// exit(5); } static void tuple_evalctx_free_var(TupleEvalVar *var) { assert(var != NULL); - + var->fieldidx = -1; g_free(var->defval); g_free(var->name); g_free(var); @@ -87,22 +72,19 @@ } -/* "Reset" the evaluation context, clean up locally set variables, - * but leave globals. +/* "Reset" the evaluation context, clean up temporary variables. */ void tuple_evalctx_reset(TupleEvalContext *ctx) { gint i; - /* Free local variables */ for (i = 0; i < ctx->nvariables; i++) if (ctx->variables[i]) { - ctx->variables[i]->dictref = NULL; + ctx->variables[i]->fieldref = NULL; - if (ctx->variables[i]->islocal) + if (ctx->variables[i]->istemp) tuple_evalctx_free_var(ctx->variables[i]); } - } @@ -133,15 +115,24 @@ } -gint tuple_evalctx_add_var(TupleEvalContext *ctx, gchar *name, gboolean islocal, gint type) +gint tuple_evalctx_add_var(TupleEvalContext *ctx, const gchar *name, const gboolean istemp, const gint type) { - gint i; + gint i, ref = -1; TupleEvalVar * tmp = g_new0(TupleEvalVar, 1); tmp->name = g_strdup(name); - tmp->islocal = islocal; + tmp->istemp = istemp; tmp->type = type; - + tmp->fieldidx = ref; + + /* Find fieldidx, if any */ + if (type == VAR_FIELD) { + for (i = 0; i < FIELD_LAST && ref < 0; i++) + if (strcmp(tuple_fields[i].name, name) == 0) ref = i; + + tmp->fieldidx = ref; + } + /* Find a free slot */ for (i = 0; i < ctx->nvariables; i++) if (!ctx->variables[i]) { @@ -379,7 +370,7 @@ /* Integer */ } - tuple_error("definitions not yet supported!\n"); + tuple_error("Definitions are not yet supported!\n"); goto ret_error; } else goto ret_error; @@ -421,6 +412,19 @@ case '(': c++; if (!strncmp(c, "empty)?", 7)) { c += 7; + literal = FALSE; + if (tc_get_item(&c, tmps1, MAX_STR, ':', &literal, "tag", item)) { + c++; + tmp = tuple_evalnode_new(); + tmp->opcode = OP_EXISTS; + if ((tmp->var[0] = tc_get_variable(ctx, tmps1, VAR_FIELD)) < 0) { + tuple_error("Invalid variable '%s' in '%s'.\n", tmps1, expr); + goto ret_error; + } + tmp->children = tuple_compiler_pass1(level, ctx, &c); + tuple_evalnode_insert(&res, tmp); + } else + goto ret_error; } else goto ext_expression; break; @@ -508,7 +512,6 @@ static TupleEvalNode *tuple_compiler_pass2(gboolean *changed, TupleEvalContext *ctx, TupleEvalNode *expr) { TupleEvalNode *curr = expr, *res = NULL; - *changed = FALSE; assert(ctx != NULL); assert(expr != NULL); @@ -543,17 +546,25 @@ } -/* Evaluate tuple in given TupleEval expression in given - * context and return resulting string. +/* Fetch a reference to a tuple field for given variable by fieldidx or dict. + * Return pointer to field, NULL if not available. */ -static TupleValue * tf_get_dictref(TupleEvalVar *var, Tuple *tuple) +static TupleValue * tf_get_fieldref(TupleEvalVar *var, Tuple *tuple) { - if (var->type == VAR_FIELD && var->dictref == NULL) - var->dictref = mowgli_dictionary_retrieve(tuple->dict, var->name); + if (var->type == VAR_FIELD && var->fieldref == NULL) { + if (var->fieldidx < 0) + var->fieldref = mowgli_dictionary_retrieve(tuple->dict, var->name); + else + var->fieldref = tuple->values[var->fieldidx]; + } - return var->dictref; + return var->fieldref; } + +/* Fetch string or int value of given variable, whatever type it might be. + * Return VAR_* type for the variable. + */ static TupleValueType tf_get_var(gchar **tmps, gint *tmpi, TupleEvalVar *var, Tuple *tuple) { TupleValueType type = TUPLE_UNKNOWN; @@ -562,12 +573,12 @@ case VAR_DEF: *tmps = var->defval; type = TUPLE_STRING; break; case VAR_CONST: *tmps = var->name; type = TUPLE_STRING; break; case VAR_FIELD: - if (tf_get_dictref(var, tuple)) { - if (var->dictref->type == TUPLE_STRING) - *tmps = var->dictref->value.string; + if (tf_get_fieldref(var, tuple)) { + if (var->fieldref->type == TUPLE_STRING) + *tmps = var->fieldref->value.string; else - *tmpi = var->dictref->value.integer; - type = var->dictref->type; + *tmpi = var->fieldref->value.integer; + type = var->fieldref->type; } break; default: @@ -579,6 +590,9 @@ } +/* Evaluate tuple in given TupleEval expression in given + * context and return resulting string. + */ static gboolean tuple_formatter_eval_do(TupleEvalContext *ctx, TupleEvalNode *expr, Tuple *tuple, gchar **res, size_t *resmax, size_t *reslen) { TupleEvalNode *curr = expr; @@ -609,14 +623,14 @@ break; case VAR_FIELD: - if (tf_get_dictref(var0, tuple)) { - switch (var0->dictref->type) { + if (tf_get_fieldref(var0, tuple)) { + switch (var0->fieldref->type) { case TUPLE_STRING: - str = var0->dictref->value.string; + str = var0->fieldref->value.string; break; case TUPLE_INT: - snprintf(tmps, sizeof(tmps), "%d", var0->dictref->value.integer); + snprintf(tmps, sizeof(tmps), "%d", var0->fieldref->value.integer); str = tmps; break; @@ -658,28 +672,29 @@ case OP_LTEQ: result = (resulti <= 0); break; case OP_GT: result = (resulti > 0); break; case OP_GTEQ: result = (resulti >= 0); break; - default: result = FALSE; + default: result = FALSE; } if (result && !tuple_formatter_eval_do(ctx, curr->children, tuple, res, resmax, reslen)) return FALSE; + } else { + /* FIXME?! Warn that types are not same? */ } break; case OP_IS_EMPTY: var0 = ctx->variables[curr->var[0]]; - if (var0->dictref == NULL) - var0->dictref = mowgli_dictionary_retrieve(tuple->dict, var0->name); + if (tf_get_fieldref(var0, tuple)) { - switch (var0->dictref->type) { + switch (var0->fieldref->type) { case TUPLE_INT: - result = (var0->dictref->value.integer == 0); + result = (var0->fieldref->value.integer == 0); break; case TUPLE_STRING: result = TRUE; - tmps2 = var0->dictref->value.string; + tmps2 = var0->fieldref->value.string; while (result && *tmps2 != '\0') { if (*tmps2 == ' ') @@ -691,12 +706,12 @@ default: result = TRUE; - } + } + } else + result = TRUE; - if (result) { - if (!tuple_formatter_eval_do(ctx, curr->children, tuple, res, resmax, reslen)) - return FALSE; - } + if (result && !tuple_formatter_eval_do(ctx, curr->children, tuple, res, resmax, reslen)) + return FALSE; break; default: @@ -739,10 +754,7 @@ if (!expr) return NULL; - if (!tuple_formatter_eval_do(ctx, expr, tuple, &res, &resmax, &reslen)) { - g_free(res); - return NULL; - } + tuple_formatter_eval_do(ctx, expr, tuple, &res, &resmax, &reslen); return res; }
--- a/src/audacious/tuple_compiler.h Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/tuple_compiler.h Tue Sep 11 09:14:15 2007 -0500 @@ -55,7 +55,7 @@ VAR_CONST, VAR_DEF }; - + /* Caching structure for deterministic functions */ @@ -68,10 +68,12 @@ typedef struct { gchar *name; - gboolean islocal; /* Local? true = will be cleaned with tuple_evalctx_reset() */ - gint type; /* Type of this "variable", see VAR_* */ - gchar *defval; - TupleValue *dictref; /* Cached tuple value ref */ + gboolean istemp; /* Scope of variable - TRUE = temporary */ + gint type; /* Type of variable, see VAR_* */ + gchar *defval; /* Defined value ${=foo,bar} */ + + gint fieldidx; /* if >= 0: Index # of "pre-defined" Tuple fields */ + TupleValue *fieldref; /* Cached tuple field ref */ } TupleEvalVar; @@ -95,14 +97,11 @@ TupleEvalContext * tuple_evalctx_new(void); void tuple_evalctx_reset(TupleEvalContext *ctx); void tuple_evalctx_free(TupleEvalContext *ctx); -gint tuple_evalctx_add_var(TupleEvalContext *ctx, gchar *name, gboolean islocal, gint type); +gint tuple_evalctx_add_var(TupleEvalContext *ctx, const gchar *name, const gboolean istemp, const gint type); void tuple_evalnode_free(TupleEvalNode *expr); TupleEvalNode *tuple_formatter_compile(TupleEvalContext *ctx, gchar *expr); gchar *tuple_formatter_eval(TupleEvalContext *ctx, TupleEvalNode *expr, Tuple *tuple); -/* -gchar *tuple_formatter_make_title_string(Tuple *tuple, const gchar *string); -*/ #endif
--- a/src/audacious/tuple_formatter.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/tuple_formatter.c Tue Sep 11 09:14:15 2007 -0500 @@ -271,15 +271,15 @@ /* ${artist} */ if (expr == NULL && argument == NULL) { - TupleValueType type = tuple_get_value_type(tuple, expression); + TupleValueType type = tuple_get_value_type(tuple, -1, expression); switch(type) { case TUPLE_STRING: - return g_strdup(tuple_get_string(tuple, expression)); + return g_strdup(tuple_get_string(tuple, -1, expression)); break; case TUPLE_INT: - return g_strdup_printf("%d", tuple_get_int(tuple, expression)); + return g_strdup_printf("%d", tuple_get_int(tuple, -1, expression)); break; case TUPLE_UNKNOWN: default: @@ -383,7 +383,7 @@ static gboolean tuple_formatter_expression_exists(Tuple *tuple, const gchar *expression) { - return (tuple_get_value_type(tuple, expression) != TUPLE_UNKNOWN) ? TRUE : FALSE; + return (tuple_get_value_type(tuple, -1, expression) != TUPLE_UNKNOWN) ? TRUE : FALSE; } /* builtin-keyword: ${==arg1,arg2}, returns TRUE if <arg1> and <arg2> match. @@ -406,7 +406,7 @@ else /* bad formatted arg */ return FALSE; } - else if (tuple_get_value_type(tuple, args[0]) == TUPLE_UNKNOWN) + else if (tuple_get_value_type(tuple, -1, args[0]) == TUPLE_UNKNOWN) { g_strfreev(args); return FALSE; @@ -423,7 +423,7 @@ else /* bad formatted arg */ return FALSE; } - else if (tuple_get_value_type(tuple, args[1]) == TUPLE_UNKNOWN) + else if (tuple_get_value_type(tuple, -1, args[1]) == TUPLE_UNKNOWN) { g_strfreev(args); return FALSE; @@ -431,18 +431,18 @@ if (!arg1) /* if arg1 is not "raw text", get the tuple value */ { - if (tuple_get_value_type(tuple, args[0]) == TUPLE_STRING) - arg1 = g_strdup(tuple_get_string(tuple, args[0])); + if (tuple_get_value_type(tuple, -1, args[0]) == TUPLE_STRING) + arg1 = g_strdup(tuple_get_string(tuple, -1, args[0])); else - arg1 = g_strdup_printf("%d", tuple_get_int(tuple, args[0])); + arg1 = g_strdup_printf("%d", tuple_get_int(tuple, -1, args[0])); } if (!arg2) /* if arg2 is not "raw text", get the tuple value */ { - if (tuple_get_value_type(tuple, args[1]) == TUPLE_STRING) - arg2 = g_strdup(tuple_get_string(tuple, args[1])); + if (tuple_get_value_type(tuple, -1, args[1]) == TUPLE_STRING) + arg2 = g_strdup(tuple_get_string(tuple, -1, args[1])); else - arg2 = g_strdup_printf("%d", tuple_get_int(tuple, args[1])); + arg2 = g_strdup_printf("%d", tuple_get_int(tuple, -1, args[1])); } ret = g_ascii_strcasecmp(arg1, arg2); @@ -467,15 +467,15 @@ { gboolean ret = TRUE; const gchar *iter; - TupleValueType type = tuple_get_value_type(tuple, expression); + TupleValueType type = tuple_get_value_type(tuple, -1, expression); if (type == TUPLE_UNKNOWN) return TRUE; - if (type == TUPLE_INT && tuple_get_int(tuple, expression) != 0) + if (type == TUPLE_INT && tuple_get_int(tuple, -1, expression) != 0) return FALSE; - iter = tuple_get_string(tuple, expression); + iter = tuple_get_string(tuple, -1, expression); while (ret && *iter != '\0') { @@ -529,7 +529,7 @@ if(!rv || !strcmp(rv, "")) { g_free(rv); - rv = g_strdup(tuple_get_string(tuple, "file-name")); + rv = g_strdup(tuple_get_string(tuple, FIELD_FILE_NAME, NULL)); } return rv;
--- a/src/audacious/ui_fileinfo.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/ui_fileinfo.c Tue Sep 11 09:14:15 2007 -0500 @@ -180,26 +180,32 @@ gtk_widget_realize(fileinfo_win); - fileinfo_entry_set_text("entry_title", tuple_get_string(tuple, "title")); - fileinfo_entry_set_text("entry_artist", tuple_get_string(tuple, "artist")); - fileinfo_entry_set_text("entry_album", tuple_get_string(tuple, "album")); - fileinfo_entry_set_text("entry_comment", tuple_get_string(tuple, "comment")); - fileinfo_entry_set_text("entry_genre", tuple_get_string(tuple, "genre")); + fileinfo_entry_set_text("entry_title", tuple_get_string(tuple, FIELD_TITLE, NULL)); + fileinfo_entry_set_text("entry_artist", tuple_get_string(tuple, FIELD_ARTIST, NULL)); + fileinfo_entry_set_text("entry_album", tuple_get_string(tuple, FIELD_ALBUM, NULL)); + fileinfo_entry_set_text("entry_comment", tuple_get_string(tuple, FIELD_COMMENT, NULL)); + fileinfo_entry_set_text("entry_genre", tuple_get_string(tuple, FIELD_GENRE, NULL)); - tmp = g_strdup_printf("%s/%s", tuple_get_string(tuple, "file-path"), tuple_get_string(tuple, "file-name")); + tmp = g_strdup_printf("%s/%s", + tuple_get_string(tuple, FIELD_FILE_PATH, NULL), + tuple_get_string(tuple, FIELD_FILE_NAME, NULL)); if(tmp){ fileinfo_entry_set_text_free("entry_location", str_to_utf8(tmp)); g_free(tmp); tmp = NULL; } - if (tuple_get_int(tuple, "year")) - fileinfo_entry_set_text_free("entry_year", g_strdup_printf("%d", tuple_get_int(tuple, "year"))); + if (tuple_get_int(tuple, FIELD_YEAR, NULL)) + fileinfo_entry_set_text_free("entry_year", + g_strdup_printf("%d", tuple_get_int(tuple, FIELD_YEAR, NULL))); - if (tuple_get_int(tuple, "track-number")) - fileinfo_entry_set_text_free("entry_track", g_strdup_printf("%d", tuple_get_int(tuple, "track-number"))); + if (tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL)) + fileinfo_entry_set_text_free("entry_track", + g_strdup_printf("%d", tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL))); - tmp = fileinfo_recursive_get_image(tuple_get_string(tuple, "file-path"), tuple_get_string(tuple, "file-name"), 0); + tmp = fileinfo_recursive_get_image( + tuple_get_string(tuple, FIELD_FILE_PATH, NULL), + tuple_get_string(tuple, FIELD_FILE_NAME, NULL), 0); if(tmp) {
--- a/src/audacious/ui_fileinfopopup.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/ui_fileinfopopup.c Tue Sep 11 09:14:15 2007 -0500 @@ -350,42 +350,42 @@ tmp = NULL; g_object_set_data(G_OBJECT(filepopup_win), "file", NULL); } - if (tuple_get_string(tuple, "file-path") && tuple_get_string(tuple, "file-name")) + if (tuple_get_string(tuple, FIELD_FILE_PATH, NULL) && tuple_get_string(tuple, FIELD_FILE_NAME, NULL)) g_object_set_data(G_OBJECT(filepopup_win), "file", - g_build_filename(tuple_get_string(tuple, "file-path"), - tuple_get_string(tuple, "file-name"), + g_build_filename(tuple_get_string(tuple, FIELD_FILE_PATH, NULL), + tuple_get_string(tuple, FIELD_FILE_NAME, NULL), NULL)); gtk_widget_realize(filepopup_win); - if (tuple_get_string(tuple, "title")) + if (tuple_get_string(tuple, FIELD_TITLE, NULL)) { gchar *markup = g_markup_printf_escaped("<span style=\"italic\">%s</span>", _("Title")); gtk_label_set_markup(GTK_LABEL(g_object_get_data(G_OBJECT(filepopup_win), "header_title")), markup); g_free(markup); - filepopup_entry_set_text(filepopup_win, "label_title", tuple_get_string(tuple, "title")); + filepopup_entry_set_text(filepopup_win, "label_title", tuple_get_string(tuple, FIELD_TITLE, NULL)); } else { /* display filename if track_name is not available */ gchar *markup = g_markup_printf_escaped("<span style=\"italic\">%s</span>", _("Filename")); - gchar *utf_filename = filename_to_utf8(tuple_get_string(tuple, "file-name")); + gchar *utf_filename = filename_to_utf8(tuple_get_string(tuple, FIELD_FILE_NAME, NULL)); gtk_label_set_markup(GTK_LABEL(g_object_get_data(G_OBJECT(filepopup_win), "header_title")), markup); g_free(markup); filepopup_entry_set_text(filepopup_win, "label_title", utf_filename); g_free(utf_filename); } - audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, "artist"), + audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, FIELD_ARTIST, NULL), "label_artist", "header_artist"); - audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, "album"), + audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, FIELD_ALBUM, NULL), "label_album", "header_album"); - audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, "genre"), + audacious_fileinfopupup_update_data(filepopup_win, tuple_get_string(tuple, FIELD_GENRE, NULL), "label_genre", "header_genre"); - length = tuple_get_int(tuple, "length"); + length = tuple_get_int(tuple, FIELD_LENGTH, NULL); length_string = (length > 0) ? g_strdup_printf("%d:%02d", length / 60000, (length / 1000) % 60) : NULL; audacious_fileinfopupup_update_data(filepopup_win, length_string, @@ -397,19 +397,18 @@ else g_object_set_data( G_OBJECT(filepopup_win), "length" , GINT_TO_POINTER(-1) ); - year_string = (tuple_get_int(tuple, "year") == 0) ? NULL : g_strdup_printf("%d", tuple_get_int(tuple, "year")); + year_string = (tuple_get_int(tuple, FIELD_YEAR, NULL) == 0) ? NULL : g_strdup_printf("%d", tuple_get_int(tuple, FIELD_YEAR, NULL)); audacious_fileinfopupup_update_data(filepopup_win, year_string, "label_year", "header_year"); g_free(year_string); - track_string = (tuple_get_int(tuple, "track-number") == 0) ? NULL : g_strdup_printf("%d", tuple_get_int(tuple, "track-number")); + track_string = (tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL) == 0) ? NULL : g_strdup_printf("%d", tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL)); audacious_fileinfopupup_update_data(filepopup_win, track_string, "label_tracknum", "header_tracknum"); g_free(track_string); - if (tuple_get_string(tuple, "file-name") && tuple_get_string(tuple, "file-path")) - { - tmp = fileinfo_recursive_get_image(tuple_get_string(tuple, "file-path"), tuple_get_string(tuple, "file-name"), 0); + if (tuple_get_string(tuple, FIELD_FILE_NAME, NULL) && tuple_get_string(tuple, FIELD_FILE_PATH, NULL)) { + tmp = fileinfo_recursive_get_image(tuple_get_string(tuple, FIELD_FILE_PATH, NULL), tuple_get_string(tuple, FIELD_FILE_NAME, NULL), 0); if (tmp) { // picture found if (!last_artwork || strcmp(last_artwork, tmp)) { // new picture filepopup_entry_set_image(filepopup_win, "image_artwork", tmp); @@ -454,7 +453,7 @@ audacious_fileinfopopup_show_from_title(GtkWidget *filepopup_win, gchar *title) { Tuple * tuple = tuple_new(); - tuple_associate_string(tuple, "title", title); + tuple_associate_string(tuple, FIELD_TITLE, NULL, title); audacious_fileinfopopup_show_from_tuple(filepopup_win, tuple); mowgli_object_unref(tuple); return;
--- a/src/audacious/ui_playlist.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/ui_playlist.c Tue Sep 11 09:14:15 2007 -0500 @@ -574,13 +574,13 @@ Tuple *tuple = tuple_new(); gchar *searchdata = NULL; searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) ); - tuple_associate_string(tuple, "title", searchdata); + tuple_associate_string(tuple, FIELD_TITLE, NULL, searchdata); searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) ); - tuple_associate_string(tuple, "album", searchdata); + tuple_associate_string(tuple, FIELD_ALBUM, NULL, searchdata); searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) ); - tuple_associate_string(tuple, "artist", searchdata); + tuple_associate_string(tuple, FIELD_ARTIST, NULL, searchdata); searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) ); - tuple_associate_string(tuple, "file-name", searchdata); + tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, searchdata); /* check if previous selection should be cleared before searching */ if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE ) playlistwin_select_none();
--- a/src/audacious/ui_skinned_playlist.c Tue Sep 11 06:54:00 2007 -0500 +++ b/src/audacious/ui_skinned_playlist.c Tue Sep 11 09:14:15 2007 -0500 @@ -1019,7 +1019,7 @@ GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup"); tuple = playlist_get_tuple(pl_active, pos); - if ((tuple == NULL) || (tuple_get_int(tuple, "length") < 1)) { + if ((tuple == NULL) || (tuple_get_int(tuple, FIELD_LENGTH, NULL) < 1)) { gchar *title = playlist_get_songtitle(pl_active, pos); audacious_fileinfopopup_show_from_title(popup, title); g_free(title);