X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mm.c;h=358783a193a2366fdf402506ffe3eb91a699b0d8;hp=82b6fe60aaea5b22fff01f8f36fa4c66c70cdbdf;hb=HEAD;hpb=abfb661f35e99e99c09a94d84839356d905af080 diff --git a/mm.c b/mm.c deleted file mode 100644 index 82b6fe60..00000000 --- a/mm.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2007-2014 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ - -/** \file mm.c Paraslash's mood methods. */ - -#include -#include -#include -#include - -#include "para.h" -#include "error.h" -#include "string.h" -#include "afh.h" -#include "afs.h" -#include "mm.h" - -#define MOOD_COMPARATORS \ - MC(LESS, <) \ - MC(LESS_OR_EQUAL, <=) \ - MC(EQUAL, =) \ - MC(EQUAL2, ==) \ - MC(NOT_EQUAL, !=) \ - MC(NOT_EQUAL2, <>) \ - MC(GREATER, >) \ - MC(GREATER_OR_EQUAL, >=) \ - -#define MC(a, b) MC_ ## a, -enum mood_comparator_id {MOOD_COMPARATORS NUM_MOOD_COMPARATORS}; -#undef MC -#define MC(a, b) # b, -static const char *mood_comparators[] = {MOOD_COMPARATORS}; -#undef MC - -static int parse_mood_comparator(const char *word) -{ - int i; - - for (i = 0; i < NUM_MOOD_COMPARATORS; i++) - if (!strcmp(word, mood_comparators[i])) - return i; - return -E_MOOD_SYNTAX; -} - -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 (cnd->id) { - case MC_LESS: - res = val < arg; break; - case MC_LESS_OR_EQUAL: - res = val <= arg; break; - case MC_EQUAL: - case MC_EQUAL2: - res = val == arg; break; - case MC_NOT_EQUAL: - case MC_NOT_EQUAL2: - res = val != arg; break; - case MC_GREATER: - res = val > arg; break; - case MC_GREATER_OR_EQUAL: - res = val >= arg; break; - default: - PARA_EMERG_LOG("BUG: invalid mood comparator\n"); - exit(EXIT_FAILURE); - } - 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; - 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); -} - -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 { - /** Comparator and year given at the mood line. */ - struct mm_compare_num_data *cnd; - /** Used to detect Y2K issues. */ - int32_t current_year; -}; - -static int mm_year_parser(int argc, char **argv, void **private) -{ - int ret = -E_MOOD_SYNTAX; - struct mm_year_data *mmyd = para_malloc(sizeof(*mmyd)); - time_t current_time; - struct tm *gmt; - - ret = mm_compare_num_parser(argc, argv, (void **)&mmyd->cnd); - if (ret < 0) - goto err; - current_time = time(NULL); - gmt = gmtime(¤t_time); - /* tm_year is the number of years since 1900 */ - mmyd->current_year = gmt->tm_year + 1900; - *private = mmyd; - return 1; -err: - free(mmyd); - return ret; -} - -static int mm_year_score_function(__a_unused const char *path, - __a_unused const struct afs_info *afsi, - const struct afh_info *afhi, - const void *private) -{ - const struct mm_year_data *mmyd = private; - int32_t tag_year; - int ret = para_atoi32(afhi->tags.year, &tag_year); - - if (ret < 0) /* year tag not present or not a number */ - return -100; - if (tag_year < 0) - return -100; - /* try to work around Y2K issues */ - if (tag_year < 100) { - tag_year += 1900; - if (tag_year + 100 <= mmyd->current_year) - tag_year += 100; /* assume tag_year >= 2000 */ - } - return mm_compare_num_score_function(tag_year, mmyd->cnd); -} - -static void mm_year_cleanup(void *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, - __a_unused void **ignored) -{ - return argc? -E_MOOD_SYNTAX : 1; -} - -static int mm_no_attributes_set_score_function(__a_unused const char *path, - const struct afs_info *afsi, - __a_unused const struct afh_info *afhi, - __a_unused const void *data) -{ - if (!afsi->attributes) - return 100; - return -100; -} - -static int mm_path_matches_score_function(const char *path, - __a_unused const struct afs_info *afsi, - __a_unused const struct afh_info *afhi, - const void *data) -{ - if (fnmatch(data, path, 0)) - return -100; - return 100; -} - -static int mm_path_matches_parser(int argc, char **argv, void **data) -{ - if (argc != 1) - return -E_MOOD_SYNTAX; - *data = para_strdup(argv[1]); - return 1; -} - -static void mm_path_matches_cleanup(void *data) -{ - free(data); -} - -static int mm_is_set_parser(int argc, char **argv, void **bitnum) -{ - int ret; - unsigned char c, *res; - - if (argc != 1) - return -E_MOOD_SYNTAX; - ret = get_attribute_bitnum_by_name(argv[1], &c); - if (ret < 0) - return ret; - res = para_malloc(1); - *res = c; - *bitnum = res; - return 1; -} - -static int mm_is_set_score_function(__a_unused const char *path, - __a_unused const struct afs_info *afsi, - __a_unused const struct afh_info *afhi, - const void *data) -{ - const unsigned char *bn = data; - if (afsi->attributes & (1ULL << *bn)) - return 100; - return -100; -} - -#define DEFINE_MOOD_METHOD(_name) \ -.parser = mm_ ## _name ## _parser, \ -.score_function = mm_ ## _name ## _score_function, \ -.name = #_name - -#define DEFINE_MOOD_METHOD_WITH_CLEANUP(_name) \ - 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 - -#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)}, - {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)}, - {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} -};