2 * Copyright (C) 2007-2009 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file mm.c Paraslash's mood methods. */
21 #define MOOD_COMPARATORS \
23 MC(LESS_OR_EQUAL, <=) \
29 MC(GREATER_OR_EQUAL, >=) \
31 #define MC(a, b) MC_ ## a,
32 enum mood_comparator_id {MOOD_COMPARATORS NUM_MOOD_COMPARATORS};
35 const char const *mood_comparators[] = {MOOD_COMPARATORS};
38 static int parse_mood_comparator(const char *word)
42 for (i = 0; i < NUM_MOOD_COMPARATORS; i++)
43 if (!strcmp(word, mood_comparators[i]))
45 return -E_MOOD_SYNTAX;
48 static int compare_int32(int32_t a, int32_t b, enum mood_comparator_id id)
55 case MC_LESS_OR_EQUAL:
65 case MC_GREATER_OR_EQUAL:
68 PARA_EMERG_LOG("BUG: invalid mood comparator\n");
71 return res? 100 : -100;
75 /** The year given at the mood line. */
77 /** Used to detect Y2K issues. */
79 /** <, <=, =, !=, >=, or >. */
80 enum mood_comparator_id id;
83 static int mm_year_parser(int argc, char **argv, void **private)
85 int ret = -E_MOOD_SYNTAX;
86 struct mm_year_data *mmyd = para_malloc(sizeof(*mmyd));
92 ret = parse_mood_comparator(argv[1]);
96 ret = para_atoi32(argv[2], &mmyd->year);
99 current_time = time(NULL);
100 gmt = gmtime(¤t_time);
101 /* tm_year is the number of years since 1900 */
102 mmyd->current_year = gmt->tm_year + 1900;
110 static int mm_year_score_function(__a_unused const char *path,
111 __a_unused const struct afs_info *afsi,
112 const struct afh_info *afhi,
115 const struct mm_year_data *mmyd = private;
117 int ret = para_atoi32(afhi->tags.year, &tag_year);
119 if (ret < 0) /* year tag not present or not a number */
123 /* try to work around Y2K issues */
124 if (tag_year < 100) {
126 if (tag_year + 100 <= mmyd->current_year)
127 tag_year += 100; /* assume tag_year >= 2000 */
129 return compare_int32(tag_year, mmyd->year, mmyd->id);
132 static void mm_year_cleanup(void *private)
137 static int mm_no_attributes_set_parser(int argc, __a_unused char **argv,
138 __a_unused void **ignored)
140 return argc? -E_MOOD_SYNTAX : 1;
143 static int mm_no_attributes_set_score_function(__a_unused const char *path,
144 const struct afs_info *afsi,
145 __a_unused const struct afh_info *afhi,
146 __a_unused const void *data)
148 if (!afsi->attributes)
153 static int mm_path_matches_score_function(const char *path,
154 __a_unused const struct afs_info *afsi,
155 __a_unused const struct afh_info *afhi,
158 if (fnmatch(data, path, 0))
163 static int mm_path_matches_parser(int argc, char **argv, void **data)
166 return -E_MOOD_SYNTAX;
167 *data = para_strdup(argv[1]);
171 static void mm_path_matches_cleanup(void *data)
176 static int mm_is_set_parser(int argc, char **argv, void **bitnum)
179 unsigned char c, *res;
182 return -E_MOOD_SYNTAX;
183 ret = get_attribute_bitnum_by_name(argv[1], &c);
186 res = para_malloc(1);
192 static int mm_is_set_score_function(__a_unused const char *path,
193 __a_unused const struct afs_info *afsi,
194 __a_unused const struct afh_info *afhi,
197 const unsigned char *bn = data;
198 if (afsi->attributes & (1ULL << *bn))
203 #define DEFINE_MOOD_METHOD(_name) \
204 .parser = mm_ ## _name ## _parser, \
205 .score_function = mm_ ## _name ## _score_function, \
208 #define DEFINE_MOOD_METHOD_WITH_CLEANUP(_name) \
209 DEFINE_MOOD_METHOD(_name), \
210 .cleanup = mm_ ## _name ## _cleanup
212 const struct mood_method mood_methods[] = {
213 {DEFINE_MOOD_METHOD(no_attributes_set)},
214 {DEFINE_MOOD_METHOD(is_set)},
215 {DEFINE_MOOD_METHOD_WITH_CLEANUP(path_matches)},
216 {DEFINE_MOOD_METHOD_WITH_CLEANUP(year)},