Browse Source

add new command del_list

Luka Perkov 11 years ago
parent
commit
ec8cbbbe0f
4 changed files with 67 additions and 1 deletions
  1. 14 1
      cli.c
  2. 12 0
      delta.c
  3. 32 0
      list.c
  4. 9 0
      uci.h

+ 14 - 1
cli.c

@@ -38,6 +38,7 @@ enum {
 	CMD_GET,
 	CMD_SET,
 	CMD_ADD_LIST,
+	CMD_DEL_LIST,
 	CMD_DEL,
 	CMD_RENAME,
 	CMD_REVERT,
@@ -133,6 +134,7 @@ static void uci_usage(void)
 		"\tcommit     [<config>]\n"
 		"\tadd        <config> <section-type>\n"
 		"\tadd_list   <config>.<section>.<option>=<string>\n"
+		"\tdel_list   <config>.<section>.<option>=<string>\n"
 		"\tshow       [<config>[.<section>[.<option>]]]\n"
 		"\tget        <config>.<section>[.<option>]\n"
 		"\tset        <config>.<section>[.<option>]=<value>\n"
@@ -242,6 +244,9 @@ static void uci_show_changes(struct uci_package *p)
 		case UCI_CMD_LIST_ADD:
 			op = "+=";
 			break;
+		case UCI_CMD_LIST_DEL:
+			op = "-=";
+			break;
 		default:
 			break;
 		}
@@ -418,7 +423,9 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv)
 		return 1;
 	}
 
-	if (ptr.value && (cmd != CMD_SET) && (cmd != CMD_ADD_LIST) && (cmd != CMD_RENAME) && (cmd != CMD_REORDER))
+	if (ptr.value && (cmd != CMD_SET) &&
+	    (cmd != CMD_ADD_LIST) && (cmd != CMD_DEL_LIST) &&
+	    (cmd != CMD_RENAME) && (cmd != CMD_REORDER))
 		return 1;
 
 	e = ptr.last;
@@ -453,6 +460,9 @@ static int uci_do_section_cmd(int cmd, int argc, char **argv)
 	case CMD_ADD_LIST:
 		ret = uci_add_list(ctx, &ptr);
 		break;
+	case CMD_DEL_LIST:
+		ret = uci_del_list(ctx, &ptr);
+		break;
 	case CMD_REORDER:
 		if (!ptr.s || !ptr.value) {
 			ctx->err = UCI_ERR_NOTFOUND;
@@ -585,11 +595,14 @@ static int uci_cmd(int argc, char **argv)
 		cmd = CMD_ADD;
 	else if (!strcasecmp(argv[0], "add_list"))
 		cmd = CMD_ADD_LIST;
+	else if (!strcasecmp(argv[0], "del_list"))
+		cmd = CMD_DEL_LIST;
 	else
 		cmd = -1;
 
 	switch(cmd) {
 		case CMD_ADD_LIST:
+		case CMD_DEL_LIST:
 		case CMD_GET:
 		case CMD_SET:
 		case CMD_DEL:

+ 12 - 0
delta.c

@@ -114,6 +114,9 @@ static inline int uci_parse_delta_tuple(struct uci_context *ctx, char **buf, str
 	case '|':
 		c = UCI_CMD_LIST_ADD;
 		break;
+	case '_':
+		c = UCI_CMD_LIST_DEL;
+		break;
 	}
 
 	if (c != UCI_CMD_CHANGE)
@@ -138,6 +141,9 @@ static inline int uci_parse_delta_tuple(struct uci_context *ctx, char **buf, str
 	case UCI_CMD_LIST_ADD:
 		if (!ptr->option)
 			goto error;
+	case UCI_CMD_LIST_DEL:
+		if (!ptr->option)
+			goto error;
 	}
 
 	return c;
@@ -176,6 +182,9 @@ static void uci_parse_delta_line(struct uci_context *ctx, struct uci_package *p,
 	case UCI_CMD_LIST_ADD:
 		UCI_INTERNAL(uci_add_list, ctx, &ptr);
 		break;
+	case UCI_CMD_LIST_DEL:
+		UCI_INTERNAL(uci_del_list, ctx, &ptr);
+		break;
 	case UCI_CMD_ADD:
 	case UCI_CMD_CHANGE:
 		UCI_INTERNAL(uci_set, ctx, &ptr);
@@ -460,6 +469,9 @@ int uci_save(struct uci_context *ctx, struct uci_package *p)
 		case UCI_CMD_LIST_ADD:
 			prefix = "|";
 			break;
+		case UCI_CMD_LIST_DEL:
+			prefix = "_";
+			break;
 		default:
 			break;
 		}

+ 32 - 0
list.c

@@ -612,6 +612,38 @@ int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)
 	return 0;
 }
 
+int uci_del_list(struct uci_context *ctx, struct uci_ptr *ptr)
+{
+	/* NB: pass on internal flag to uci_del_element */
+	bool internal = ctx && ctx->internal;
+	struct uci_element *e, *tmp;
+	struct uci_package *p;
+
+	UCI_HANDLE_ERR(ctx);
+
+	uci_expand_ptr(ctx, ptr, false);
+	UCI_ASSERT(ctx, ptr->s);
+	UCI_ASSERT(ctx, ptr->value);
+
+	if (!(ptr->o && ptr->option))
+		return 0;
+
+	if ((ptr->o->type != UCI_TYPE_LIST))
+		return 0;
+
+	p = ptr->p;
+	if (!internal && p->has_delta)
+		uci_add_delta(ctx, &p->delta, UCI_CMD_LIST_DEL, ptr->section, ptr->option, ptr->value);
+
+	uci_foreach_element_safe(&ptr->o->v.list, tmp, e) {
+		if (!strcmp(ptr->value, uci_to_option(e)->e.name)) {
+			uci_free_option(uci_to_option(e));
+		}
+	}
+
+	return 0;
+}
+
 int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
 {
 	/* NB: UCI_INTERNAL use means without delta tracking */

+ 9 - 0
uci.h

@@ -187,6 +187,14 @@ extern int uci_set(struct uci_context *ctx, struct uci_ptr *ptr);
  */
 extern int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr);
 
+/**
+ * uci_del_list: Remove a string from an element list
+ * @ctx: uci context
+ * @ptr: uci pointer (with value)
+ *
+ */
+extern int uci_del_list(struct uci_context *ctx, struct uci_ptr *ptr);
+
 /**
  * uci_reorder: Reposition a section
  * @ctx: uci context
@@ -489,6 +497,7 @@ enum uci_command {
 	UCI_CMD_RENAME,
 	UCI_CMD_REORDER,
 	UCI_CMD_LIST_ADD,
+	UCI_CMD_LIST_DEL,
 };
 
 struct uci_delta