]> git.ozlabs.org Git - ccan/blobdiff - ccan/rune/rune.c
ccan/rune: simplify check helper interfaces, allow explicit string lengths.
[ccan] / ccan / rune / rune.c
index 36eaab92ab689a6c5d25b2c2d696d58f53b32d03..0ff7968b4aa9b093f42bb5febdd6fb4b455b8e25 100644 (file)
@@ -5,6 +5,7 @@
 #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>
@@ -66,7 +67,7 @@ struct rune *rune_dup(const tal_t *ctx, const struct rune *rune TAKES)
        struct rune *dup;
 
        if (taken(rune))
-               return (struct rune *)rune;
+               return tal_steal(ctx, (struct rune *)rune);
 
        dup = tal_dup(ctx, struct rune, rune);
        dup->restrs = tal_arr(dup, struct rune_restr *, tal_count(rune->restrs));
@@ -86,7 +87,7 @@ struct rune *rune_derive_start(const tal_t *ctx,
         /* If they provide a unique_id, it goes first. */
        if (unique_id) {
                if (taken(unique_id))
-                       rune->unique_id = unique_id;
+                       rune->unique_id = tal_steal(rune, unique_id);
                else
                        rune->unique_id = tal_strdup(rune, unique_id);
                
@@ -117,7 +118,7 @@ struct rune_altern *rune_altern_dup(const tal_t *ctx,
        struct rune_altern *dup;
 
        if (taken(altern))
-               return (struct rune_altern *)altern;;
+               return tal_steal(ctx, (struct rune_altern *)altern);
        dup = tal(ctx, struct rune_altern);
        dup->condition = altern->condition;
        dup->fieldname = tal_strdup(dup, altern->fieldname);
@@ -132,7 +133,7 @@ struct rune_restr *rune_restr_dup(const tal_t *ctx,
        size_t num_altern;
 
        if (taken(restr))
-               return (struct rune_restr *)restr;
+               return tal_steal(ctx, (struct rune_restr *)restr);
 
        num_altern = tal_count(restr->alterns);
        dup = tal(ctx, struct rune_restr);
@@ -282,20 +283,34 @@ static const char *integer_compare_valid(const tal_t *ctx,
        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) {
@@ -307,27 +322,28 @@ const char *rune_alt_single(const tal_t *ctx,
                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);
@@ -346,12 +362,12 @@ const char *rune_alt_single(const tal_t *ctx,
                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;
        }
@@ -359,6 +375,27 @@ const char *rune_alt_single(const tal_t *ctx,
        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,