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
)},