Browse Source

add section reordering to libuci and cli

Felix Fietkau 15 years ago
parent
commit
defdac4bf3
4 changed files with 69 additions and 1 deletions
  1. 14 1
      cli.c
  2. 16 0
      history.c
  3. 30 0
      list.c
  4. 9 0
      uci.h

+ 14 - 1
cli.c

@@ -40,6 +40,7 @@ enum {
 	CMD_DEL,
 	CMD_RENAME,
 	CMD_REVERT,
+	CMD_REORDER,
 	/* package cmds */
 	CMD_SHOW,
 	CMD_CHANGES,
@@ -131,6 +132,7 @@ static void uci_usage(void)
 		"\tdelete     <config>[.<section[.<option>]]\n"
 		"\trename     <config>.<section>[.<option>]=<name>\n"
 		"\trevert     <config>[.<section>[.<option>]]\n"
+		"\treorder    <config>.<section>=<position>\n"
 		"\n"
 		"Options:\n"
 		"\t-c <path>  set the search path for config files (default: /etc/config)\n"
@@ -404,7 +406,7 @@ 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))
+	if (ptr.value && (cmd != CMD_SET) && (cmd != CMD_ADD_LIST) && (cmd != CMD_RENAME) && (cmd != CMD_REORDER))
 		return 1;
 
 	e = ptr.last;
@@ -439,6 +441,14 @@ 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_REORDER:
+		if (!ptr.s) {
+			ctx->err = UCI_ERR_NOTFOUND;
+			cli_perror();
+			return 1;
+		}
+		ret = uci_reorder_section(ctx, ptr.s, strtoul(ptr.value, NULL, 10));
+		break;
 	case CMD_DEL:
 		ret = uci_delete(ctx, &ptr);
 		break;
@@ -550,6 +560,8 @@ static int uci_cmd(int argc, char **argv)
 		cmd = CMD_RENAME;
 	else if (!strcasecmp(argv[0], "revert"))
 		cmd = CMD_REVERT;
+	else if (!strcasecmp(argv[0], "reorder"))
+		cmd = CMD_REORDER;
 	else if (!strcasecmp(argv[0], "del") ||
 	         !strcasecmp(argv[0], "delete"))
 		cmd = CMD_DEL;
@@ -571,6 +583,7 @@ static int uci_cmd(int argc, char **argv)
 		case CMD_DEL:
 		case CMD_RENAME:
 		case CMD_REVERT:
+		case CMD_REORDER:
 			return uci_do_section_cmd(cmd, argc, argv);
 		case CMD_SHOW:
 		case CMD_EXPORT:

+ 16 - 0
history.c

@@ -93,6 +93,9 @@ static inline int uci_parse_history_tuple(struct uci_context *ctx, char **buf, s
 	int c = UCI_CMD_CHANGE;
 
 	switch(**buf) {
+	case '^':
+		c = UCI_CMD_REORDER;
+		break;
 	case '-':
 		c = UCI_CMD_REMOVE;
 		break;
@@ -119,6 +122,10 @@ static inline int uci_parse_history_tuple(struct uci_context *ctx, char **buf, s
 		goto error;
 
 	switch(c) {
+	case UCI_CMD_REORDER:
+		if (!ptr->value || ptr->option)
+			goto error;
+		break;
 	case UCI_CMD_RENAME:
 		if (!ptr->value || !uci_validate_name(ptr->value))
 			goto error;
@@ -149,6 +156,12 @@ static void uci_parse_history_line(struct uci_context *ctx, struct uci_package *
 		uci_add_history(ctx, &p->saved_history, cmd, ptr.section, ptr.option, ptr.value);
 
 	switch(cmd) {
+	case UCI_CMD_REORDER:
+		expand_ptr(ctx, &ptr, true);
+		if (!ptr.s)
+			UCI_THROW(ctx, UCI_ERR_NOTFOUND);
+		UCI_INTERNAL(uci_reorder_section, ctx, ptr.s, strtoul(ptr.value, NULL, 10));
+		break;
 	case UCI_CMD_RENAME:
 		UCI_INTERNAL(uci_rename, ctx, &ptr);
 		break;
@@ -425,6 +438,9 @@ int uci_save(struct uci_context *ctx, struct uci_package *p)
 		case UCI_CMD_ADD:
 			prefix = "+";
 			break;
+		case UCI_CMD_REORDER:
+			prefix = "^";
+			break;
 		case UCI_CMD_LIST_ADD:
 			prefix = "|";
 			break;

+ 30 - 0
list.c

@@ -48,6 +48,20 @@ static inline void uci_list_del(struct uci_list *ptr)
 	uci_list_init(ptr);
 }
 
+static inline void uci_list_set_pos(struct uci_list *head, struct uci_list *ptr, int pos)
+{
+	struct uci_list *new_head = head;
+	struct uci_element *p = NULL;
+
+	uci_list_del(ptr);
+	uci_foreach_element(head, p) {
+		new_head = &p->list;
+		if (pos-- <= 0)
+			break;
+	}
+	uci_list_add(new_head, ptr);
+}
+
 static inline void uci_list_fixup(struct uci_list *ptr)
 {
 	ptr->prev->next = ptr;
@@ -533,6 +547,22 @@ int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)
 	return 0;
 }
 
+int uci_reorder_section(struct uci_context *ctx, struct uci_section *s, int pos)
+{
+	struct uci_package *p = s->package;
+	char order[32];
+
+	UCI_HANDLE_ERR(ctx);
+
+	uci_list_set_pos(&s->package->sections, &s->e.list, pos);
+	if (!ctx->internal && p->has_history) {
+		sprintf(order, "%d", pos);
+		uci_add_history(ctx, &p->history, UCI_CMD_REORDER, s->e.name, NULL, order);
+	}
+
+	return 0;
+}
+
 int uci_add_section(struct uci_context *ctx, struct uci_package *p, const char *type, struct uci_section **res)
 {
 	bool internal = ctx->internal;

+ 9 - 0
uci.h

@@ -177,6 +177,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_reorder: Reposition a section
+ * @ctx: uci context
+ * @s: uci section to reposition
+ * @pos: new position in the section list
+ */
+extern int uci_reorder_section(struct uci_context *ctx, struct uci_section *s, int pos);
+
 /**
  * uci_rename: Rename an element
  * @ctx: uci context
@@ -389,6 +397,7 @@ enum uci_command {
 	UCI_CMD_REMOVE,
 	UCI_CMD_CHANGE,
 	UCI_CMD_RENAME,
+	UCI_CMD_REORDER,
 	UCI_CMD_LIST_ADD,
 };