- /* Arguments are separated by colons */
- arg = strchr(act, ':');
- if (arg) {
- *arg = '\0';
- arg++;
+ act = pos;
+ actlen = strcspn(pos, ":(, \t\r\n");
+ if (act[actlen] == ':') {
+ /* The argument can be separated by a colon. */
+ size_t arglen;
+
+ arg = act + actlen + 1;
+ arglen = strcspn(arg, ", \t\r\n");
+ pos = arg + arglen + (arg[arglen] != '\0');
+ arg[arglen] = '\0';
+ } else if (act[actlen] == '(') {
+ /* The argument can be surrounded by balanced parentheses. The
+ * outermost set of parentheses is removed. */
+ int level = 1;
+ size_t arglen;
+
+ arg = act + actlen + 1;
+ for (arglen = 0; level > 0; arglen++) {
+ switch (arg[arglen]) {
+ case '\0':
+ ovs_fatal(0, "unbalanced parentheses in argument to %s "
+ "action", act);
+
+ case '(':
+ level++;
+ break;
+
+ case ')':
+ level--;
+ break;
+ }
+ }
+ arg[arglen - 1] = '\0';
+ pos = arg + arglen;
+ } else {
+ /* There might be no argument at all. */
+ arg = NULL;
+ pos = act + actlen + (act[actlen] != '\0');