* // t= means current time, in seconds, as integer
* if (streq(alt->fieldname, "t")) {
* struct timeval now;
- * s64 t;
* gettimeofday(&now, NULL);
- * t = now.tv_sec;
- * return rune_alt_single(ctx, alt, NULL, &t);
+ * return rune_alt_single_int(ctx, alt, now.tv_sec);
* }
* if (streq(alt->fieldname, "uid")) {
- * return rune_alt_single(ctx, alt, uid, NULL);
+ * return rune_alt_single_str(ctx, alt, uid, strlen(uid));
* }
* // Otherwise, field is missing
- * return rune_alt_single(ctx, alt, NULL, NULL);
+ * return rune_alt_single_missing(ctx, alt);
* }
*
* int main(int argc, char *argv[])
printf("ccan/base64\n");
printf("ccan/crypto/sha256\n");
printf("ccan/endian\n");
+ printf("ccan/mem\n");
printf("ccan/short_types\n");
printf("ccan/str/hex\n");
printf("ccan/tal/str\n");
#include <inttypes.h>
#include <stdio.h>
#include <ccan/endian/endian.h>
+#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <ccan/rune/rune.h>
#include <ccan/rune/internal.h>
return NULL;
}
-const char *rune_alt_single(const tal_t *ctx,
- const struct rune_altern *alt,
- const char *fieldval_str,
- const s64 *fieldval_int)
+static int lexo_order(const char *fieldval_str,
+ size_t fieldval_strlen,
+ const char *alt)
+{
+ int ret = strncmp(fieldval_str, alt, fieldval_strlen);
+
+ /* If alt is same but longer, fieldval is < */
+ if (ret == 0 && strlen(alt) > fieldval_strlen)
+ ret = -1;
+ return ret;
+}
+
+static const char *rune_alt_single(const tal_t *ctx,
+ const struct rune_altern *alt,
+ const char *fieldval_str,
+ size_t fieldval_strlen,
+ const s64 *fieldval_int)
{
char strfield[STR_MAX_CHARS(s64) + 1];
s64 runeval_int;
const char *err;
-
+
/* Caller can't set both! */
if (fieldval_int) {
assert(!fieldval_str);
sprintf(strfield, "%"PRIi64, *fieldval_int);
fieldval_str = strfield;
+ fieldval_strlen = strlen(strfield);
}
switch (alt->condition) {
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "is not equal to",
- streq(fieldval_str, alt->value));
+ memeqstr(fieldval_str, fieldval_strlen, alt->value));
case RUNE_COND_NOT_EQUAL:
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "is equal to",
- !streq(fieldval_str, alt->value));
+ !memeqstr(fieldval_str, fieldval_strlen, alt->value));
case RUNE_COND_BEGINS:
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "does not start with",
- strstarts(fieldval_str, alt->value));
+ memstarts_str(fieldval_str, fieldval_strlen, alt->value));
case RUNE_COND_ENDS:
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "does not end with",
- strends(fieldval_str, alt->value));
+ memends_str(fieldval_str, fieldval_strlen, alt->value));
case RUNE_COND_CONTAINS:
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "does not contain",
- strstr(fieldval_str, alt->value));
+ memmem(fieldval_str, fieldval_strlen,
+ alt->value, strlen(alt->value)));
case RUNE_COND_INT_LESS:
err = integer_compare_valid(ctx, fieldval_int,
alt, &runeval_int);
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "is equal to or ordered after",
- strcmp(fieldval_str, alt->value) < 0);
+ lexo_order(fieldval_str, fieldval_strlen, alt->value) < 0);
case RUNE_COND_LEXO_AFTER:
if (!fieldval_str)
return tal_fmt(ctx, "%s not present", alt->fieldname);
return cond_test(ctx, alt, "is equal to or ordered before",
- strcmp(fieldval_str, alt->value) > 0);
+ lexo_order(fieldval_str, fieldval_strlen, alt->value) > 0);
case RUNE_COND_COMMENT:
return NULL;
}
abort();
}
+const char *rune_alt_single_str(const tal_t *ctx,
+ const struct rune_altern *alt,
+ const char *fieldval_str,
+ size_t fieldval_strlen)
+{
+ return rune_alt_single(ctx, alt, fieldval_str, fieldval_strlen, NULL);
+}
+
+const char *rune_alt_single_int(const tal_t *ctx,
+ const struct rune_altern *alt,
+ s64 fieldval_int)
+{
+ return rune_alt_single(ctx, alt, NULL, 0, &fieldval_int);
+}
+
+const char *rune_alt_single_missing(const tal_t *ctx,
+ const struct rune_altern *alt)
+{
+ return rune_alt_single(ctx, alt, NULL, 0, NULL);
+}
+
const char *rune_meets_criteria_(const tal_t *ctx,
const struct rune *rune,
const char *(*check)(const tal_t *ctx,
bool rune_eq(const struct rune *rune1, const struct rune *rune2);
/**
- * rune_alt_single - helper to implement check().
+ * rune_alt_single_str - helper to implement check().
* @ctx: context to allocate any error return from.
* @alt: alternative to test.
* @fieldval_str: field value as a string.
+ * @fieldval_strlen: length of @fieldval_str
+ */
+const char *rune_alt_single_str(const tal_t *ctx,
+ const struct rune_altern *alt,
+ const char *fieldval_str,
+ size_t fieldval_strlen);
+
+/**
+ * rune_alt_single_int - helper to implement check().
+ * @ctx: context to allocate any error return from.
+ * @alt: alternative to test.
* @fieldval_int: field value as an integer.
+ */
+const char *rune_alt_single_int(const tal_t *ctx,
+ const struct rune_altern *alt,
+ s64 fieldval_int);
+
+/**
+ * rune_alt_single_missing - helper to implement check().
+ * @ctx: context to allocate any error return from.
+ * @alt: alternative to test.
*
- * If the field value is missing, set neither fieldval_str nor fieldval_int,
- * otherwise you must set exactly one.
+ * Use this if alt->fieldname is unknown (it could still pass, if
+ * the test is that the fieldname is missing).
*/
-const char *rune_alt_single(const tal_t *ctx,
- const struct rune_altern *alt,
- const char *fieldval_str,
- const s64 *fieldval_int);
+const char *rune_alt_single_missing(const tal_t *ctx,
+ const struct rune_altern *alt);
+
/**
* rune_is_derived - is a rune derived from this other rune?