X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mood.c;h=26d68dc558512380f20f0f45990b268614118381;hp=24d1de29056812973d33a18a5ed7df378a9f72ad;hb=aef566e9c8680629bac1ea84893b8b3ccd13da77;hpb=2a4d7bb5f5cecdbcbda6b9f9b531c919ecc6b161 diff --git a/mood.c b/mood.c index 24d1de29..26d68dc5 100644 --- a/mood.c +++ b/mood.c @@ -6,7 +6,9 @@ /** \file mood.c Paraslash's mood handling functions. */ -#include +#include +#include + #include "para.h" #include "error.h" #include "string.h" @@ -14,6 +16,7 @@ #include "afs.h" #include "list.h" #include "ipc.h" +#include "mm.h" /** * Contains statistical data of the currently admissible audio files. @@ -34,66 +37,6 @@ struct afs_statistics { }; struct afs_statistics statistics; -/** - * Assign scores according to a mood_method. - * - * Each mood_method has its own mood_score_function. The first three parameters - * passed to that function are informations about the audio file whose score is - * to be computed. The data argument depends on the mood method this function - * is used for. It usually is the argument given at the end of a mood line. - * - * Mood score functions must return values between -100 and +100 inclusively. - * Boolean score functions should always return either -100 or +100. - * - * \sa struct mood_method, mood_parser. - */ -typedef int mood_score_function(const char *path, const struct afs_info *afsi, - const struct afh_info *afhi, const void *data); - -/** - * Pre-process a mood line. - * - * The mood_parser of a mood_method is called once at mood open time for each - * line of the current mood definition that contains the mood_method's name as - * a keyword. The line is passed to the mood_parser as the first argument. The - * mood_parser must determine whether the line is syntactically correct and - * return a positive value if so and a negative value otherwise. - * - * Some mood parsers pre-process the data given in the mood line to compute a - * structure which depends of the particular mood_method and which is used - * later in the mood_score_function of the mood_method. The mood_parser may - * store a pointer to its structure via the second argument. - * - * \sa mood_open(), mood_cleanup_function, mood_score_function. - */ -typedef int mood_parser(const char *, void **); - -/** - * Deallocate resources which were allocated by the mood_parser. - * - * This optional function of a mood_method is used to free any resources - * allocated in mood_open() by the mood_parser. The argument passed is a - * pointer to the mood_method specific data structure that was returned by the - * mood_parser. - * - * \sa mood_parser. - */ -typedef void mood_cleanup_function(void *); - -/** - * Used for scoring and to determine whether a file is admissible. - */ -struct mood_method { - /** The name of the method. */ - const char *name; - /** Pointer to the mood parser. */ - mood_parser *parser; - /** Pointer to the score function */ - mood_score_function *score_function; - /** Optional cleanup function. */ - mood_cleanup_function *cleanup; -}; - /** * Each line of the current mood corresponds to a mood_item. */ @@ -164,90 +107,6 @@ static uint64_t int_sqrt(uint64_t x) return res; } -static int mm_no_attributes_set_parser(const char *arg, __a_unused void **ignored) -{ - if (arg && *arg) - PARA_WARNING_LOG("ignored junk at eol: %s\n", arg); - return 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_played_rarely_score_function(__a_unused const char *path, - const struct afs_info *afsi, - __a_unused const struct afh_info *afhi, - __a_unused const void *data) -{ - unsigned num; - int ret = get_num_admissible_files(&num); - - if (ret < 0) - return 0; - if (statistics.num_played_sum - num * afsi->num_played - > int_sqrt(statistics.num_played_qd * num)) - return 100; - return -100; -} - -static int mm_played_rarely_parser(const char *arg, __a_unused void **ignored) -{ - if (arg && *arg) - PARA_WARNING_LOG("ignored junk at eol: %s\n", arg); - return 1; -} - -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(const char *arg, void **data) -{ - *data = para_strdup(arg); - return 1; -} - -static void mm_path_matches_cleanup(void *data) -{ - free(data); -} - -static int mm_is_set_parser(const char *arg, void **bitnum) -{ - unsigned char *c = para_malloc(1); - int ret = get_attribute_bitnum_by_name(arg, c); - - if (ret >= 0) - *bitnum = c; - else - free(c); - return ret; -} - -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; -} - /* returns 1 if row matches score item, 0 if not, negative on errors */ static int get_item_score(const struct osl_row *row, struct mood_item *item, long *score, long *score_arg_sum) @@ -266,7 +125,6 @@ static int get_item_score(const struct osl_row *row, struct mood_item *item, ret = get_afhi_of_row(row, &afhi); if (ret< 0) return ret; - free(afhi.info_string); /* don't need the tag info */ ret = get_audio_file_path_of_row(row, &path); if (ret< 0) return ret; @@ -328,23 +186,6 @@ static int compute_mood_score(const struct osl_row *aft_row, struct mood *m, return 1; } -#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 - -static const struct mood_method mood_methods[] = { - {DEFINE_MOOD_METHOD(no_attributes_set)}, - {DEFINE_MOOD_METHOD(played_rarely)}, - {DEFINE_MOOD_METHOD(is_set)}, - {DEFINE_MOOD_METHOD_WITH_CLEANUP(path_matches)}, - {.parser = NULL} -}; - static void cleanup_list_entry(struct mood_item *item) { if (item->method && item->method->cleanup) @@ -412,17 +253,17 @@ static int parse_mood_line(char *mood_line, void *data) { struct mood_line_parser_data *mlpd = data; char **argv; - char *delim = " \t"; unsigned num_words; char **w; int i, ret; enum mood_line_type mlt = ML_INVALID; struct mood_item *mi = NULL; - char *buf = para_strdup(mood_line); mlpd->line_num++; - num_words = split_args(buf, &argv, delim); - ret = 1; + ret = create_argv(mood_line, " \t", &argv); + if (ret < 0) + return ret; + num_words = ret; if (!num_words) /* empty line */ goto out; w = argv; @@ -495,8 +336,8 @@ check_for_if: ret = -E_MOOD_SYNTAX; if (!mood_methods[i].parser) goto out; - w++; - ret = mood_methods[i].parser(*w, &mi->parser_data); + ret = mood_methods[i].parser(num_words - 1 - (w - argv), w, + &mi->parser_data); if (ret < 0) goto out; mi->method = &mood_methods[i]; @@ -513,8 +354,7 @@ success: (mlt == ML_DENY? "deny" : "score"), mi->method); ret = 1; out: - free(argv); - free(buf); + free_argv(argv); if (ret >= 0) return ret; if (mi) { @@ -961,7 +801,6 @@ void close_current_mood(void) memset(&statistics, 0, sizeof(statistics)); } - /** * Change the current mood. * @@ -993,7 +832,7 @@ int change_current_mood(char *mood_name) .data = mood_name, .size = strlen(mood_name) + 1 }; - ret = osl_get_row(moods_table, BLOBCOL_NAME, &obj, &row); + ret = osl(osl_get_row(moods_table, BLOBCOL_NAME, &obj, &row)); if (ret < 0) { PARA_NOTICE_LOG("no such mood: %s\n", mood_name); return ret;