Add mood methods {artist, title, album, comment}_matches.
authorAndre Noll <maan@systemlinux.org>
Sun, 12 Jul 2009 10:28:26 +0000 (12:28 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 12 Jul 2009 10:28:26 +0000 (12:28 +0200)
Document the new mood methods and remove the documentation of the played_rarely
mood method that has been deleted recently.

README.afs
mm.c

index ef51c29..7889bda 100644 (file)
@@ -156,20 +156,30 @@ List of mood_methods
 Takes no arguments and matches an audio file if and only if no
 attributes are set.
 
-       played_rarely
-
-Takes no arguments and matches all audio files where the number of
-times this audio file was selected is below the average.
-
-       is_set attribute_name
+       is_set <attribute_name>
 
 Takes the name of an attribute and matches iff that attribute is set.
 
-       path_matches pattern
+       path_matches <pattern>
 
 Takes a filename pattern and matches iff the path of the audio file
 matches the pattern.
 
+       artist_matches <pattern>
+       album_matches <pattern>
+       title_matches <pattern>
+       comment_matches <pattern>
+
+Takes an extended regular expression and matches iff the text of the
+corresponding tag of the audio file matches the pattern. If the tag
+is not set, the empty string is matched against the pattern.
+
+       year
+
+Takes a comparator ~ of the set {<, =, <=, >, >=, !=} and a number
+N. Matches iff the year tag Y of the audio file is a number that
+satisfies the condition Y ~ N. If the audio file has no year tag,
+or if the tag is not a number, the file does not match.
 
 ----------
 Mood usage
diff --git a/mm.c b/mm.c
index 0130cbc..4ed72ad 100644 (file)
--- a/mm.c
+++ b/mm.c
@@ -71,6 +71,67 @@ static int compare_int32(int32_t a, int32_t b, enum mood_comparator_id id)
        return res? 100 : -100;
 }
 
+static int mm_regex_parser(int argc, char **argv, void **private)
+{
+       regex_t *preg;
+       int ret;
+
+       if (argc != 1)
+               return -E_MOOD_SYNTAX;
+       preg = para_malloc(sizeof(*preg));
+       ret = para_regcomp(preg, argv[1], REG_EXTENDED | REG_NOSUB);
+       if (ret < 0) {
+               free(preg);
+               return ret;
+       }
+       *private = preg;
+       return 1;
+}
+
+static int mm_regex_score_function(const regex_t *preg, const char *pattern)
+{
+       return regexec(preg, pattern, 0, NULL, 0) == 0? 100 : -100;
+}
+
+static void mm_regex_cleanup(void *private)
+{
+       regex_t *preg = private;
+       regfree(preg);
+       free(preg);
+}
+
+static int mm_artist_matches_score_function(__a_unused const char *path,
+               __a_unused const struct afs_info *afsi,
+               const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_regex_score_function(private, afhi->tags.artist);
+}
+
+static int mm_title_matches_score_function(__a_unused const char *path,
+               __a_unused const struct afs_info *afsi,
+               const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_regex_score_function(private, afhi->tags.title);
+}
+
+static int mm_album_matches_score_function(__a_unused const char *path,
+               __a_unused const struct afs_info *afsi,
+               const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_regex_score_function(private, afhi->tags.album);
+}
+
+static int mm_comment_matches_score_function(__a_unused const char *path,
+               __a_unused const struct afs_info *afsi,
+               const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_regex_score_function(private, afhi->tags.comment);
+}
+
 struct mm_year_data {
        /** The year given at the mood line. */
        int32_t year;
@@ -209,11 +270,20 @@ static int mm_is_set_score_function(__a_unused const char *path,
        DEFINE_MOOD_METHOD(_name), \
        .cleanup = mm_ ## _name ## _cleanup
 
+#define DEFINE_REGEX_MOOD_METHOD(_name) \
+       .name = #_name, \
+       .parser = mm_regex_parser, \
+       .score_function = mm_ ## _name ## _score_function, \
+       .cleanup = mm_regex_cleanup
+
 const struct mood_method mood_methods[] = {
        {DEFINE_MOOD_METHOD(no_attributes_set)},
        {DEFINE_MOOD_METHOD(is_set)},
        {DEFINE_MOOD_METHOD_WITH_CLEANUP(path_matches)},
        {DEFINE_MOOD_METHOD_WITH_CLEANUP(year)},
+       {DEFINE_REGEX_MOOD_METHOD(artist_matches)},
+       {DEFINE_REGEX_MOOD_METHOD(title_matches)},
+       {DEFINE_REGEX_MOOD_METHOD(album_matches)},
+       {DEFINE_REGEX_MOOD_METHOD(comment_matches)},
        {.parser = NULL}
 };
-