static ESExpResult *
message_func_system_flag (ESExp *f,
                          gint argc,
                          ESExpResult **argv,
                          gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argv[0]->type == ESEXP_RES_STRING) {
		const gchar *name;
		name = argv[0]->value.string;
		if (!g_ascii_strcasecmp (name, "Attachments")) {
			WRITE_EXISTS_MESSAGE (msg, "item:HasAttachments");
		} else if (!g_ascii_strcasecmp (name, "deleted") || !g_ascii_strcasecmp (name, "junk")) {
			r = e_sexp_result_new (f, ESEXP_RES_BOOL);
			r->value.boolean = FALSE;
			return r;
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;

}
/*
 * (occurrences-count? START END)
 * (occurrences-count?)
 *
 * Counts occurrences either in the given time range (the first variant)
 * or in the time range defined by the expression itself (the second variant).
 * If the time range cannot be determined, then -1 is returned.
 */
static ESExpResult *
func_occurrences_count (ESExp *esexp,
                        gint argc,
                        ESExpResult **argv,
                        gpointer data)
{
	SearchContext *ctx = data;
	time_t start, end;
	ESExpResult *result;
	icaltimezone *default_zone;

	/* Check argument types */

	if (argc != 2 && argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects none or two arguments"),
			"occurrences-count");
		return NULL;
	}

	if (argc == 2) {
		if (argv[0]->type != ESEXP_RES_TIME) {
			e_sexp_fatal_error (
				esexp, _("\"%s\" expects the first argument to be a time_t"),
				"occurrences-count");
			return NULL;
		}
		start = argv[0]->value.time;

		if (argv[1]->type != ESEXP_RES_TIME) {
			e_sexp_fatal_error (
				esexp, _("\"%s\" expects the second argument to be a time_t"),
				"occurrences-count");
			return NULL;
		}
		end = argv[1]->value.time;
	} else if (ctx->expr_range_set) {
		start = ctx->expr_range_start;
		end = ctx->expr_range_end;
	} else {
		result = e_sexp_result_new (esexp, ESEXP_RES_INT);
		result->value.number = -1;

		return result;
	}

	default_zone = icaltimezone_get_utc_timezone ();

	ctx->occurrences_count = 0;
	e_cal_recur_generate_instances (
		ctx->comp, start, end,
		count_instances_time_range_cb, ctx,
		resolve_tzid, ctx, default_zone);

	result = e_sexp_result_new (esexp, ESEXP_RES_INT);
	result->value.number = ctx->occurrences_count;

	return result;
}
/* (has-start?)
 *
 * A boolean value for components that have/don't have filled start date/time.
 *
 * Returns: whether the component has start date/time filled
 */
static ESExpResult *
func_has_start (ESExp *esexp,
                gint argc,
                ESExpResult **argv,
                gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result;
	ECalComponentDateTime dt;

	/* Check argument types */

	if (argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects no arguments"),
			"has-start");
		return NULL;
	}

	e_cal_component_get_dtstart (ctx->comp, &dt);
	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = dt.value != NULL;
	e_cal_component_free_datetime (&dt);

	return result;
}
/* (has-recurrences?)
 *
 * A boolean value for components that have/dont have recurrences.
 *
 * Returns: a boolean indicating whether the component has recurrences or not.
 */
static ESExpResult *
func_has_recurrences (ESExp *esexp,
                      gint argc,
                      ESExpResult **argv,
                      gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result;

	/* Check argument types */

	if (argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects no arguments"),
			"has-recurrences");
		return NULL;
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean =
		e_cal_component_has_recurrences (ctx->comp) ||
		e_cal_component_is_instance (ctx->comp);

	return result;
}
/* (is-completed?)
 *
 * Returns a boolean indicating whether the component is completed (i.e. has
 * a COMPLETED property. This is really only useful for TODO components.
 */
static ESExpResult *
func_is_completed (ESExp *esexp,
                   gint argc,
                   ESExpResult **argv,
                   gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result;
	struct icaltimetype *t;
	gboolean complete = FALSE;

	/* Check argument types */

	if (argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects no arguments"),
			"is-completed");
		return NULL;
	}

	e_cal_component_get_completed (ctx->comp, &t);
	if (t) {
		complete = TRUE;
		e_cal_component_free_icaltimetype (t);
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = complete;

	return result;
}
static ESExpResult *
func_exists_vcard (struct _ESExp *f,
                   gint argc,
                   struct _ESExpResult **argv,
                   gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *r;
	gint truth = FALSE;

	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
		const gchar *attr_name;
		EVCardAttribute *attr;
		GList *values;
		gchar *s;

		attr_name = argv[0]->value.string;
		attr = e_vcard_get_attribute (E_VCARD (ctx->contact), attr_name);
		if (attr) {
			values = e_vcard_attribute_get_values (attr);
			if (g_list_length (values) > 0) {
				s = values->data;
				if (s[0] != '\0') {
					truth = TRUE;
				}
			}
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_BOOL);
	r->value.boolean = truth;

	return r;
}
static ESExpResult *
func_percent_complete (ESExp *esexp,
                       gint argc,
                       ESExpResult **argv,
                       gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result = NULL;
	gint *percent;

	if (argc != 0) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects no arguments"),
				"percent-completed");
		return NULL;
	}

	e_cal_component_get_percent (ctx->comp, &percent);

	if (percent && *percent) {
		result = e_sexp_result_new (esexp, ESEXP_RES_INT);
		result->value.number = *percent;

	}

	return result;
}
/**
 * e_cal_backend_sexp_func_time_day_end:
 * @esexp: An #ESExp object.
 * @argc: Number of arguments.
 * @argv: The arguments.
 * @data: Closure data.
 *
 * (time-day-end TIME)
 * TIME - time_t, base time
 *
 * Returns the end of the day, according to the local time.
 *
 * FIXME: TIMEZONES - this uses the current Unix timezone.
 *
 * Returns: The result of the function.
 */
ESExpResult *
e_cal_backend_sexp_func_time_day_end (ESExp *esexp,
                                      gint argc,
                                      ESExpResult **argv,
                                      gpointer data)
{
	time_t t;
	ESExpResult *result;

	if (argc != 1) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects one argument"),
				    "time-day-end");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be a time_t"),
				    "time-day-end");
		return NULL;
	}
	t = argv[0]->value.time;

	result = e_sexp_result_new (esexp, ESEXP_RES_TIME);
	result->value.time = time_day_end (t);

	return result;
}
static ESExpResult *
func_lt (ESExp *f,
         gint argc,
         ESExpResult **argv,
         gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argc != 2) {
		e_sexp_fatal_error (f, "two arguments are required for this operation");
		return NULL;
	}

	if (argv[0]->type == ESEXP_RES_STRING) {
		const gchar *name;
		gchar *field_uri = NULL;
		gboolean is_time = FALSE;
		name = argv[0]->value.string;

		if (!g_strcmp0 (name, "sent-date")) {
			field_uri = g_strdup ("item:DateTimeSent");
			is_time = TRUE;
		} else if (!g_strcmp0 (name, "received-date")) {
			field_uri = g_strdup ("item:DateTimeReceived");
			is_time = TRUE;
		} else if (!g_strcmp0 (name, "message-size")) {
			field_uri = g_strdup ("item:Size");
			is_time = FALSE;
		}

		if (field_uri && argv[1]->type == ESEXP_RES_INT && argv[1]->value.number != 0) {
			if (is_time) {
				time_t time;
				gchar *date;
				time = argv[1]->value.number;
				date = e_ews_make_timestamp (time);

				WRITE_LESS_THAN_MESSAGE (msg, field_uri, date);
				g_free (date);
			} else {
				gint value;
				gchar val_str[16];

				value = argv[1]->value.number;
				value = value * (1024); //conver kB to Bytes.
				g_sprintf (val_str, "%d", value);

				WRITE_LESS_THAN_MESSAGE (msg, field_uri, val_str);
			}
		}
		g_free (field_uri);
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
static ESExpResult *
message_func_header_exists (ESExp *f,
                            gint argc,
                            ESExpResult **argv,
                            gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argv[0]->type == ESEXP_RES_STRING) {
		const gchar *headername;
		headername = argv[0]->value.string;

		if (!g_ascii_strcasecmp (headername, "subject")) {
			WRITE_EXISTS_MESSAGE (msg, "item:Subject");
		} else if (!g_ascii_strcasecmp (headername, "from")) {
			WRITE_EXISTS_MESSAGE (msg, "message:From");
		} else if (!g_ascii_strcasecmp (headername, "to")) {
			WRITE_EXISTS_MESSAGE (msg, "message:ToRecipients");
		} else if (!g_ascii_strcasecmp (headername, "cc")) {
			WRITE_EXISTS_MESSAGE (msg, "message:CcRecipients");
		} else if (!g_ascii_strcasecmp (headername, "bcc")) {
			WRITE_EXISTS_MESSAGE (msg, "message:BccRecipients");
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
/* (has-alarms-in-range? START END)
 *
 * START - time_t, start of the time range
 * END - time_t, end of the time range
 *
 * Returns: a boolean indicating whether the component has alarms in the given
 * time range or not.
 */
static ESExpResult *
func_has_alarms_in_range (ESExp *esexp,
                          gint argc,
                          ESExpResult **argv,
                          gpointer data)
{
	time_t start, end;
	ESExpResult *result;
	icaltimezone *default_zone;
	ECalComponentAlarms *alarms;
	ECalComponentAlarmAction omit[] = {-1};
	SearchContext *ctx = data;

	/* Check argument types */

	if (argc != 2) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects two arguments"),
			"has-alarms-in-range");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects the first "
			"argument to be a time_t"),
			"has-alarms-in-range");
		return NULL;
	}
	start = argv[0]->value.time;

	if (argv[1]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects the second "
			"argument to be a time_t"),
			"has-alarms-in-range");
		return NULL;
	}
	end = argv[1]->value.time;

	/* See if the object has alarms in the given time range */
	default_zone = icaltimezone_get_utc_timezone ();

	alarms = e_cal_util_generate_alarms_for_comp (
		ctx->comp, start, end,
		omit, resolve_tzid,
		ctx, default_zone);

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	if (alarms) {
		result->value.boolean = TRUE;
		e_cal_component_alarms_free (alarms);
	} else
		result->value.boolean = FALSE;

	return result;
}
/* (completed-before? TIME)
 *
 * TIME - time_t
 *
 * Returns a boolean indicating whether the component was completed on or
 * before the given time (i.e. it checks the COMPLETED property).
 * This is really only useful for TODO components.
 */
static ESExpResult *
func_completed_before (ESExp *esexp,
                       gint argc,
                       ESExpResult **argv,
                       gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result;
	struct icaltimetype *tt;
	icaltimezone *zone;
	gboolean retval = FALSE;
	time_t before_time, completed_time;

	/* Check argument types */

	if (argc != 1) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects one argument"),
				    "completed-before");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be a time_t"),
				    "completed-before");
		return NULL;
	}
	before_time = argv[0]->value.time;

	e_cal_component_get_completed (ctx->comp, &tt);
	if (tt) {
		/* COMPLETED must be in UTC. */
		zone = icaltimezone_get_utc_timezone ();
		completed_time = icaltime_as_timet_with_zone (*tt, zone);

#if 0
		g_print ("Query Time    : %s", ctime (&before_time));
		g_print ("Completed Time: %s", ctime (&completed_time));
#endif

		/* We want to return TRUE if before_time is after
		 * completed_time. */
		if (difftime (before_time, completed_time) > 0) {
#if 0
			g_print ("  Returning TRUE\n");
#endif
			retval = TRUE;
		}

		e_cal_component_free_icaltimetype (tt);
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = retval;

	return result;
}
static ESExpResult *
message_func_relative_months (ESExp *f,
                              gint argc,
                              ESExpResult **argv,
                              gpointer data)
{
	ESExpResult *r;

	if (argc != 1 || argv[0]->type != ESEXP_RES_INT) {
		r = e_sexp_result_new (f, ESEXP_RES_BOOL);
		r->value.boolean = FALSE;

	} else {
		r = e_sexp_result_new (f, ESEXP_RES_INT);
		r->value.number = camel_folder_search_util_add_months (time (NULL), argv[0]->value.number);
	}

	return r;
}
static ESExpResult *
message_func_match_all (ESExp *f,
                        gint argc,
                        ESExpResult **argv,
                        gpointer data)
{
	ESExpResult *r;

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
static ESExpResult *
message_func_current_date (ESExp *f,
                           gint argc,
                           ESExpResult **argv,
                           gpointer data)
{
	ESExpResult *r;

	r = e_sexp_result_new (f, ESEXP_RES_INT);
	r->value.time = time (NULL);
	return r;
}
static ESExpResult *
message_func_get_size (ESExp *f,
                       gint argc,
                       ESExpResult **argv,
                       gpointer data)
{
	ESExpResult *r;

	r = e_sexp_result_new (f, ESEXP_RES_STRING);
	r->value.string = g_strdup ("message-size");

	return r;
}
static ESExpResult *
calendar_func_occurrences_count (ESExp *f,
                                 gint argc,
                                 ESExpResult **argv,
                                 gpointer data)
{
	ESExpResult *r;

	/*ews doesn't support restriction based on number of occurrences*/
	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
static ESExpResult *
common_message_func_header_contains (ESExp *f,
                                     gint argc,
                                     ESExpResult **argv,
                                     gpointer data,
                                     match_type type)

{
	ESExpResult *r;
	ESoapMessage *msg;
	gchar *mode;

	msg = (ESoapMessage *) data;

	if (type == MATCH_CONTAINS || type == MATCH_ENDS_WITH)
		mode = g_strdup ("Substring");
	else if (type == MATCH_BEGINS_WITH)
		mode = g_strdup ("Prefixed");
	else if (type == MATCH_IS)
		mode = g_strdup ("FullString");
	else
		mode = g_strdup ("Substring");

	if (argv[0]->type == ESEXP_RES_STRING) {
		const gchar *headername;
		headername = argv[0]->value.string;

		if (argv[1]->type == ESEXP_RES_STRING) {
			const gchar *value;
			value = argv[1]->value.string;

			if (!g_ascii_strcasecmp (headername, "subject")) {
				WRITE_CONTAINS_MESSAGE (msg, mode, "IgnoreCase", "item:Subject", value);
			} else if (!g_ascii_strcasecmp (headername, "from")) {
				WRITE_CONTAINS_MESSAGE (msg, mode, "IgnoreCase", "message:From", value);
			} else if (!g_ascii_strcasecmp (headername, "to")) {
				WRITE_CONTAINS_MESSAGE (msg, mode, "IgnoreCase", "message:ToRecipients", value);
			} else if (!g_ascii_strcasecmp (headername, "cc")) {
				WRITE_CONTAINS_MESSAGE (msg, mode, "IgnoreCase", "message:CcRecipients", value);
			} else if (!g_ascii_strcasecmp (headername, "bcc")) {
				WRITE_CONTAINS_MESSAGE (msg, mode, "IgnoreCase", "message:BccRecipients", value);
			}
		}
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	g_free (mode);

	return r;
}
Ejemplo n.º 19
0
static ESExpResult *
term_eval_and (struct _ESExp *f,
               gint argc,
               struct _ESExpTerm **argv,
               gpointer data)
{
	struct _ESExpResult *r, *r1;
	GHashTable *ht = g_hash_table_new (g_str_hash, g_str_equal);
	struct IterData lambdafoo;
	gint type=-1;
	gint bool = TRUE;
	gint i;
	const gchar *oper;

	r (printf ("( and\n"));

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	oper = "AND";
	f->operators = g_slist_prepend (f->operators, (gpointer) oper);

	for (i = 0; bool && i < argc; i++) {
		r1 = e_sexp_term_eval (f, argv[i]);
		if (type == -1)
			type = r1->type;
		if (type != r1->type) {
			e_sexp_result_free (f, r);
			e_sexp_result_free (f, r1);
			g_hash_table_destroy (ht);
			e_sexp_fatal_error (f, "Invalid types in AND");
		} else if (r1->type == ESEXP_RES_ARRAY_PTR) {
			gchar **a1;
			gint l1, j;

			a1 = (gchar **) r1->value.ptrarray->pdata;
			l1 = r1->value.ptrarray->len;
			for (j = 0; j < l1; j++) {
				gpointer ptr;
				gint n;
				ptr = g_hash_table_lookup (ht, a1[j]);
				n = GPOINTER_TO_INT (ptr);
				g_hash_table_insert (ht, a1[j], GINT_TO_POINTER (n + 1));
			}
		} else if (r1->type == ESEXP_RES_BOOL) {
			bool = bool && r1->value.boolean;
		}
		e_sexp_result_free (f, r1);
	}
/* (uid? UID)
 *
 * UID - the uid of the component
 *
 * Returns a boolean indicating whether the component has the given UID
 */
static ESExpResult *
func_uid (ESExp *esexp,
          gint argc,
          ESExpResult **argv,
          gpointer data)
{
	SearchContext *ctx = data;
	const gchar *uid = NULL, *arg_uid;
	gboolean equal;
	ESExpResult *result;

	/* Check argument types */

	if (argc != 1) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects one argument"),
			"uid");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_STRING) {
		e_sexp_fatal_error (
			esexp, _("\"%s\" expects the first "
			"argument to be a string"),
			"uid");
		return NULL;
	}

	arg_uid = argv[0]->value.string;
	e_cal_component_get_uid (ctx->comp, &uid);

	if (!arg_uid && !uid)
		equal = TRUE;
	else if ((!arg_uid || !uid) && arg_uid != uid)
		equal = FALSE;
	else if (e_util_utf8_strstrcase (arg_uid, uid) != NULL && strlen (arg_uid) == strlen (uid))
		equal = TRUE;
	else
		equal = FALSE;

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = equal;

	return result;
}
static ESExpResult *
func_eq (ESExp *f,
         gint argc,
         ESExpResult **argv,
         gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argc != 2) {
		e_sexp_fatal_error (f, "two arguments are required for this operation");
		return NULL;
	}

	if (argv[0]->type == ESEXP_RES_STRING) {
		const gchar *name;
		gchar *field_uri = NULL;

		name = argv[0]->value.string;

		if (!g_strcmp0 (name, "sent-date")) {
			field_uri = g_strdup ("item:DateTimeSent");
		} else if (!g_strcmp0 (name, "received-date")) {
			field_uri = g_strdup ("item:DateTimeReceived");
		}

		if (field_uri && argv[1]->type == ESEXP_RES_INT && argv[1]->value.number != 0) {
			time_t time;
			gchar *date;
			time = argv[1]->value.number;
			date = e_ews_make_timestamp (time);

			WRITE_IS_EQUAL_TO_MESSAGE (msg, field_uri, date);
			g_free (date);
		}
		g_free (field_uri);
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
/**
 * e_cal_backend_sexp_func_make_time:
 * @esexp: An #ESExp object.
 * @argc: Number of arguments.
 * @argv: The arguments.
 * @data: Closure data.
 *
 * (make-time ISODATE)
 * ISODATE - string, ISO 8601 date/time representation
 *
 * Constructs a time_t value for the specified date.
 *
 * Returns: The result of the function.
 */
ESExpResult *
e_cal_backend_sexp_func_make_time (ESExp *esexp,
                                   gint argc,
                                   ESExpResult **argv,
                                   gpointer data)
{
	const gchar *str;
	time_t t;
	ESExpResult *result;

	if (argc != 1) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects one argument"),
				    "make-time");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_STRING) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be a string"),
				    "make-time");
		return NULL;
	}
	str = argv[0]->value.string;
	if (!str || !*str) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be a string"),
				    "make-time");
		return NULL;
	}

	t = time_from_isodate (str);
	if (t == -1) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be an ISO 8601 "
					     "date/time string"),
				    "make-time");
		return NULL;
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_TIME);
	result->value.time = t;

	return result;
}
static ESExpResult *
calendar_func_has_recurrence (ESExp *f,
                              gint argc,
                              ESExpResult **argv,
                              gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argc == 0) {
		WRITE_EXISTS_MESSAGE (msg, "calendar:IsRecurring");
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
static ESExpResult *
calendar_func_has_attachment (ESExp *f,
                              gint argc,
                              ESExpResult **argv,
                              gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argc == 0) {
		WRITE_EXISTS_MESSAGE (msg, "item:HasAttachments");
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
/**
 * e_cal_backend_sexp_func_time_now:
 * @esexp: An #ESExp object.
 * @argc: Number of arguments.
 * @argv: The arguments.
 * @data: Closure data.
 *
 * Processes the (time-now) sexp expression.
 *
 * Returns: The result of the function.
 */
ESExpResult *
e_cal_backend_sexp_func_time_now (ESExp *esexp,
                                  gint argc,
                                  ESExpResult **argv,
                                  gpointer data)
{
	ESExpResult *result;

	if (argc != 0) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects no arguments"),
				    "time-now");
		return NULL;
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_TIME);
	result->value.time = time (NULL);

	return result;
}
static ESExpResult *
e_ews_func_and_or_not (ESExp *f,
                       gint argc,
                       ESExpTerm **argv,
                       gpointer data,
                       match_type type)
{
	ESExpResult *r, *r1;
	ESoapMessage *msg;
	gint i;

	msg = (ESoapMessage *) data;

	/* "and" and "or" expects atleast two arguments */

	if (argc == 0)
		goto result;

	if (type == MATCH_AND) {
		if (argc >= 2)
			e_soap_message_start_element (msg, "And", NULL, NULL);

	} else if (type == MATCH_OR) {
		if (argc >= 2)
			e_soap_message_start_element (msg, "Or", NULL, NULL);

	} else if (type == MATCH_NOT)
		e_soap_message_start_element (msg, "Not", NULL, NULL);

	for (i = 0; i < argc; i++) {
		r1 = e_sexp_term_eval (f, argv[i]);
		e_sexp_result_free (f, r1);
	}

	if (argc >= 2 || type == MATCH_NOT)
		e_soap_message_end_element (msg);

result:
	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
static ESExpResult *
func_has_attachment (ESExp *esexp,
                     gint argc,
                     ESExpResult **argv,
                     gpointer data)
{
	SearchContext *ctx = data;
	ESExpResult *result;

	if (argc != 0) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects no arguments"),
				"has-attachments?");
		return NULL;
	}

	result = e_sexp_result_new (esexp, ESEXP_RES_BOOL);
	result->value.boolean = e_cal_component_has_attachments (ctx->comp);

	return result;
}
static ESExpResult *
calendar_func_occur_in_time_range (ESExp *f,
                                   gint argc,
                                   ESExpResult **argv,
                                   gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;
	gchar *start, *end;

	msg = (ESoapMessage *) data;

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			f, "occur-in-time-range? expects argument 1 "
			"to be a time_t");
		return NULL;
	}

	if (argv[1]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (
			f, "occur-in-time-range? expects argument 2 "
			"to be a time_t");
		return NULL;
	}

	start = e_ews_make_timestamp (argv[0]->value.time);
	end = e_ews_make_timestamp (argv[1]->value.time);

	e_soap_message_start_element (msg, "And", NULL, NULL);
	WRITE_GREATER_THAN_OR_EQUAL_TO_MESSAGE (msg, "calendar:Start", start);
	WRITE_LESS_THAN_OR_EQUAL_TO_MESSAGE (msg, "calendar:End", end);
	e_soap_message_end_element (msg);

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	g_free (start);
	g_free (end);

	return r;
}
static ESExpResult *
calendar_func_has_categories (ESExp *f,
                              gint argc,
                              ESExpResult **argv,
                              gpointer data)
{
	ESExpResult *r;
	ESoapMessage *msg;

	msg = (ESoapMessage *) data;

	if (argc == 1 && argv[0]->type == ESEXP_RES_STRING) {
		const gchar *value;
		value = argv[0]->value.string;

		WRITE_CONTAINS_MESSAGE (msg, "Substring", "IgnoreCase", "item:Categories", value);
	}

	r = e_sexp_result_new (f, ESEXP_RES_UNDEFINED);

	return r;
}
/**
 * e_cal_backend_sexp_func_time_add_day:
 * @esexp: An #ESExp object.
 * @argc: Number of arguments.
 * @argv: The arguments.
 * @data: Closure data.
 *
 * (time-add-day TIME N)
 * TIME - time_t, base time
 * N - int, number of days to add
 *
 * Adds the specified number of days to a time value.
 *
 * FIXME: TIMEZONES - need to use a timezone or daylight saving changes will
 * make the result incorrect.
 *
 * Returns: The result of the function.
 */
ESExpResult *
e_cal_backend_sexp_func_time_add_day (ESExp *esexp,
                                      gint argc,
                                      ESExpResult **argv,
                                      gpointer data)
{
	ESExpResult *result;
	time_t t;
	gint n;

	if (argc != 2) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects two arguments"),
				    "time-add-day");
		return NULL;
	}

	if (argv[0]->type != ESEXP_RES_TIME) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the first "
					     "argument to be a time_t"),
				    "time-add-day");
		return NULL;
	}
	t = argv[0]->value.time;

	if (argv[1]->type != ESEXP_RES_INT) {
		e_sexp_fatal_error (esexp, _("\"%s\" expects the second "
					     "argument to be an integer"),
				    "time-add-day");
		return NULL;
	}
	n = argv[1]->value.number;

	result = e_sexp_result_new (esexp, ESEXP_RES_TIME);
	result->value.time = time_add_day (t, n);

	return result;
}