X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mm.c;h=af99a36f824ff533278ddbec219e10c6bff9a46b;hp=4ed72ad861384fa556a1e9a98b06929de6a6d82e;hb=53077ea78f01e197e84529ae42558af5c3a68429;hpb=08aa4b386c981292aec04fc35fe37133047fb946 diff --git a/mm.c b/mm.c index 4ed72ad8..af99a36f 100644 --- a/mm.c +++ b/mm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 Andre Noll + * Copyright (C) 2007-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -32,7 +32,7 @@ enum mood_comparator_id {MOOD_COMPARATORS NUM_MOOD_COMPARATORS}; #undef MC #define MC(a, b) # b, -const char const *mood_comparators[] = {MOOD_COMPARATORS}; +static const char *mood_comparators[] = {MOOD_COMPARATORS}; #undef MC static int parse_mood_comparator(const char *word) @@ -45,25 +45,34 @@ static int parse_mood_comparator(const char *word) return -E_MOOD_SYNTAX; } -static int compare_int32(int32_t a, int32_t b, enum mood_comparator_id id) +struct mm_compare_num_data { + /** <, <=, =, !=, >=, or >. */ + enum mood_comparator_id id; + /** The value given at the mood line. */ + int32_t arg; +}; + +static int mm_compare_num_score_function(int32_t val, + const struct mm_compare_num_data *cnd) { int res; + int32_t arg = cnd->arg; - switch (id) { + switch (cnd->id) { case MC_LESS: - res = a < b; break; + res = val < arg; break; case MC_LESS_OR_EQUAL: - res = a <= b; break; + res = val <= arg; break; case MC_EQUAL: case MC_EQUAL2: - res = a == b; break; + res = val == arg; break; case MC_NOT_EQUAL: case MC_NOT_EQUAL2: - res = a != b; break; + res = val != arg; break; case MC_GREATER: - res = a > b; break; + res = val > arg; break; case MC_GREATER_OR_EQUAL: - res = a >= b; break; + res = val >= arg; break; default: PARA_EMERG_LOG("BUG: invalid mood comparator\n"); exit(EXIT_FAILURE); @@ -71,6 +80,28 @@ static int compare_int32(int32_t a, int32_t b, enum mood_comparator_id id) return res? 100 : -100; } +static int mm_compare_num_parser(int argc, char **argv, void **private) +{ + int ret; + enum mood_comparator_id id; + int32_t arg; + struct mm_compare_num_data *cnd; + if (argc != 2) + return -E_MOOD_SYNTAX; + ret = parse_mood_comparator(argv[1]); + if (ret < 0) + return ret; + id = ret; + ret = para_atoi32(argv[2], &arg); + if (ret < 0) + return ret; + cnd = para_malloc(sizeof(struct mm_compare_num_data)); + cnd->id = id; + cnd->arg = arg; + *private = cnd; + return 1; +} + static int mm_regex_parser(int argc, char **argv, void **private) { regex_t *preg; @@ -132,13 +163,43 @@ static int mm_comment_matches_score_function(__a_unused const char *path, return mm_regex_score_function(private, afhi->tags.comment); } +static int mm_bitrate_score_function(__a_unused const char *path, + __a_unused const struct afs_info *afsi, + const struct afh_info *afhi, + const void *private) +{ + return mm_compare_num_score_function(afhi->bitrate, private); +} + +static int mm_frequency_score_function(__a_unused const char *path, + __a_unused const struct afs_info *afsi, + const struct afh_info *afhi, + const void *private) +{ + return mm_compare_num_score_function(afhi->frequency, private); +} + +static int mm_channels_score_function(__a_unused const char *path, + __a_unused const struct afs_info *afsi, + const struct afh_info *afhi, + const void *private) +{ + return mm_compare_num_score_function(afhi->channels, private); +} + +static int mm_num_played_score_function(__a_unused const char *path, + const struct afs_info *afsi, + __a_unused const struct afh_info *afhi, + const void *private) +{ + return mm_compare_num_score_function(afsi->num_played, private); +} + struct mm_year_data { - /** The year given at the mood line. */ - int32_t year; + /** Comparator and year given at the mood line. */ + struct mm_compare_num_data *cnd; /** Used to detect Y2K issues. */ int32_t current_year; - /** <, <=, =, !=, >=, or >. */ - enum mood_comparator_id id; }; static int mm_year_parser(int argc, char **argv, void **private) @@ -148,13 +209,7 @@ static int mm_year_parser(int argc, char **argv, void **private) time_t current_time; struct tm *gmt; - if (argc != 2) - goto err; - ret = parse_mood_comparator(argv[1]); - mmyd->id = ret; - if (ret < 0) - goto err; - ret = para_atoi32(argv[2], &mmyd->year); + ret = mm_compare_num_parser(argc, argv, (void **)&mmyd->cnd); if (ret < 0) goto err; current_time = time(NULL); @@ -187,12 +242,15 @@ static int mm_year_score_function(__a_unused const char *path, if (tag_year + 100 <= mmyd->current_year) tag_year += 100; /* assume tag_year >= 2000 */ } - return compare_int32(tag_year, mmyd->year, mmyd->id); + return mm_compare_num_score_function(tag_year, mmyd->cnd); } static void mm_year_cleanup(void *private) { - free(private); + struct mm_year_data *mmyd = private; + + free(mmyd->cnd); + free(mmyd); } static int mm_no_attributes_set_parser(int argc, __a_unused char **argv, @@ -276,6 +334,11 @@ static int mm_is_set_score_function(__a_unused const char *path, .score_function = mm_ ## _name ## _score_function, \ .cleanup = mm_regex_cleanup +#define DEFINE_COMPARE_NUM_MOOD_METHOD(_name) \ + .name = #_name, \ + .parser = mm_compare_num_parser, \ + .score_function = mm_ ## _name ## _score_function + const struct mood_method mood_methods[] = { {DEFINE_MOOD_METHOD(no_attributes_set)}, {DEFINE_MOOD_METHOD(is_set)}, @@ -285,5 +348,9 @@ const struct mood_method mood_methods[] = { {DEFINE_REGEX_MOOD_METHOD(title_matches)}, {DEFINE_REGEX_MOOD_METHOD(album_matches)}, {DEFINE_REGEX_MOOD_METHOD(comment_matches)}, + {DEFINE_COMPARE_NUM_MOOD_METHOD(bitrate)}, + {DEFINE_COMPARE_NUM_MOOD_METHOD(frequency)}, + {DEFINE_COMPARE_NUM_MOOD_METHOD(channels)}, + {DEFINE_COMPARE_NUM_MOOD_METHOD(num_played)}, {.parser = NULL} };