+#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,
+const char const *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;
+}
+
+static int compare_int32(int32_t a, int32_t b, enum mood_comparator_id id)
+{
+ int res;
+
+ switch (id) {
+ case MC_LESS:
+ res = a < b; break;
+ case MC_LESS_OR_EQUAL:
+ res = a <= b; break;
+ case MC_EQUAL:
+ case MC_EQUAL2:
+ res = a == b; break;
+ case MC_NOT_EQUAL:
+ case MC_NOT_EQUAL2:
+ res = a != b; break;
+ case MC_GREATER:
+ res = a > b; break;
+ case MC_GREATER_OR_EQUAL:
+ res = a >= b; break;
+ default:
+ PARA_EMERG_LOG("BUG: invalid mood comparator\n");
+ exit(EXIT_FAILURE);
+ }
+ return res? 100 : -100;
+}
+
+struct mm_year_data {
+ /** The year given at the mood line. */
+ int32_t year;
+ /** 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)