[ovs-dev,PATCHv4,01/11] ofp-actions: Refactor set_field tokenization.
diff mbox

Message ID 1443820578-9287-2-git-send-email-joestringer@nicira.com
State Accepted
Headers show

Commit Message

Joe Stringer Oct. 2, 2015, 9:16 p.m. UTC
Combine the codepaths for splitting "set_field" and "reg_load" string
arguments into the value, key, and delimiter component. The only
user-visible change is that reg_load will now provide a more meaningful
error message when parsing input such as "reg_load:1".

Signed-off-by: Joe Stringer <joestringer@nicira.com>
---
v4: Reduce refactor to identifying key,delim,value.
v3: Initial post.
---
 lib/ofp-actions.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 12 deletions(-)

Comments

Ben Pfaff Oct. 5, 2015, 10:23 p.m. UTC | #1
On Fri, Oct 02, 2015 at 02:16:08PM -0700, Joe Stringer wrote:
> Combine the codepaths for splitting "set_field" and "reg_load" string
> arguments into the value, key, and delimiter component. The only
> user-visible change is that reg_load will now provide a more meaningful
> error message when parsing input such as "reg_load:1".
> 
> Signed-off-by: Joe Stringer <joestringer@nicira.com>
> ---
> v4: Reduce refactor to identifying key,delim,value.
> v3: Initial post.

I think I reviewed this piece of code before and it seemed fine.
Assuming this didn't change significantly,
Acked-by: Ben Pfaff <blp@nicira.com>

Patch
diff mbox

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 88f0f85..6c9e1cb 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -2476,6 +2476,39 @@  encode_SET_FIELD(const struct ofpact_set_field *sf,
     }
 }
 
+/* Parses the input argument 'arg' into the key, value, and delimiter
+ * components that are common across the reg_load and set_field action format.
+ *
+ * With an argument like "1->metadata", sets the following pointers to
+ * point within 'arg':
+ * key: "metadata"
+ * value: "1"
+ * delim: "->"
+ *
+ * Returns NULL if successful, otherwise a malloc()'d string describing the
+ * error.  The caller is responsible for freeing the returned string. */
+static char * OVS_WARN_UNUSED_RESULT
+set_field_split_str(char *arg, char **key, char **value, char **delim)
+{
+    char *value_end;
+
+    *value = arg;
+    value_end = strstr(arg, "->");
+    *key = value_end + strlen("->");
+    if (delim) {
+        *delim = value_end;
+    }
+
+    if (!value_end) {
+        return xasprintf("%s: missing `->'", arg);
+    }
+    if (strlen(value_end) <= strlen("->")) {
+        return xasprintf("%s: missing field name following `->'", arg);
+    }
+
+    return NULL;
+}
+
 /* Parses a "set_field" action with argument 'arg', appending the parsed
  * action to 'ofpacts'.
  *
@@ -2492,16 +2525,11 @@  set_field_parse__(char *arg, struct ofpbuf *ofpacts,
     const struct mf_field *mf;
     char *error;
 
-    value = arg;
-    delim = strstr(arg, "->");
-    if (!delim) {
-        return xasprintf("%s: missing `->'", arg);
-    }
-    if (strlen(delim) <= strlen("->")) {
-        return xasprintf("%s: missing field name following `->'", arg);
+    error = set_field_split_str(arg, &key, &value, &delim);
+    if (error) {
+        return error;
     }
 
-    key = delim + strlen("->");
     mf = mf_from_name(key);
     if (!mf) {
         return xasprintf("%s is not a valid OXM field name", key);
@@ -2546,13 +2574,15 @@  parse_reg_load(char *arg, struct ofpbuf *ofpacts)
     const char *full_arg = arg;
     uint64_t value = strtoull(arg, (char **) &arg, 0);
     struct mf_subfield dst;
+    char *key, *value_str;
     char *error;
 
-    if (strncmp(arg, "->", 2)) {
-        return xasprintf("%s: missing `->' following value", full_arg);
+    error = set_field_split_str(arg, &key, &value_str, NULL);
+    if (error) {
+        return error;
     }
-    arg += 2;
-    error = mf_parse_subfield(&dst, arg);
+
+    error = mf_parse_subfield(&dst, key);
     if (error) {
         return error;
     }