uci_history -> uci_delta
authorFelix Fietkau <nbd@openwrt.org>
Fri, 20 Aug 2010 12:59:27 +0000 (14:59 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 20 Aug 2010 13:40:08 +0000 (15:40 +0200)
Makefile
cli.c
delta.c [new file with mode: 0644]
file.c
history.c [deleted file]
libuci.c
list.c
lua/uci.c
uci.h
uci_internal.h

index b00aac8..9f5b313 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ SOURCES = libuci.c file.c ucimap.c util.c
 
 all: uci libuci.$(SHLIB_EXT) uci-static ucimap-example
 
 
 all: uci libuci.$(SHLIB_EXT) uci-static ucimap-example
 
-$(eval $(call add_dep,libuci,history.c list.c uci.h uci_config.h uci_internal.h))
+$(eval $(call add_dep,libuci,delta.c list.c uci.h uci_config.h uci_internal.h))
 $(eval $(call add_dep,ucimap,uci.h uci_config.h ucimap.h))
 
 cli.o: cli.c uci.h uci_config.h
 $(eval $(call add_dep,ucimap,uci.h uci_config.h ucimap.h))
 
 cli.o: cli.c uci.h uci_config.h
diff --git a/cli.c b/cli.c
index 7bef7a9..0e98aa7 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -224,8 +224,8 @@ static void uci_show_changes(struct uci_package *p)
 {
        struct uci_element *e;
 
 {
        struct uci_element *e;
 
-       uci_foreach_element(&p->saved_history, e) {
-               struct uci_history *h = uci_to_history(e);
+       uci_foreach_element(&p->saved_delta, e) {
+               struct uci_delta *h = uci_to_delta(e);
                char *prefix = "";
                char *op = "=";
 
                char *prefix = "";
                char *op = "=";
 
@@ -653,10 +653,10 @@ int main(int argc, char **argv)
                                ctx->flags &= ~UCI_FLAG_EXPORT_NAME;
                                break;
                        case 'p':
                                ctx->flags &= ~UCI_FLAG_EXPORT_NAME;
                                break;
                        case 'p':
-                               uci_add_history_path(ctx, optarg);
+                               uci_add_delta_path(ctx, optarg);
                                break;
                        case 'P':
                                break;
                        case 'P':
-                               uci_add_history_path(ctx, ctx->savedir);
+                               uci_add_delta_path(ctx, ctx->savedir);
                                uci_set_savedir(ctx, optarg);
                                flags |= CLI_FLAG_NOCOMMIT;
                                break;
                                uci_set_savedir(ctx, optarg);
                                flags |= CLI_FLAG_NOCOMMIT;
                                break;
diff --git a/delta.c b/delta.c
new file mode 100644 (file)
index 0000000..e0fa1b1
--- /dev/null
+++ b/delta.c
@@ -0,0 +1,483 @@
+/*
+ * libuci - Library for the Unified Configuration Interface
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This file contains the code for handling uci config delta files
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/* record a change that was done to a package */
+void
+uci_add_delta(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value)
+{
+       struct uci_delta *h;
+       int size = strlen(section) + 1;
+       char *ptr;
+
+       if (value)
+               size += strlen(value) + 1;
+
+       h = uci_alloc_element(ctx, delta, option, size);
+       ptr = uci_dataptr(h);
+       h->cmd = cmd;
+       h->section = strcpy(ptr, section);
+       if (value) {
+               ptr += strlen(ptr) + 1;
+               h->value = strcpy(ptr, value);
+       }
+       uci_list_add(list, &h->e.list);
+}
+
+void
+uci_free_delta(struct uci_delta *h)
+{
+       if (!h)
+               return;
+       if ((h->section != NULL) &&
+               (h->section != uci_dataptr(h))) {
+               free(h->section);
+               free(h->value);
+       }
+       uci_free_element(&h->e);
+}
+
+
+int uci_set_savedir(struct uci_context *ctx, const char *dir)
+{
+       char *sdir;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, dir != NULL);
+
+       sdir = uci_strdup(ctx, dir);
+       if (ctx->savedir != uci_savedir)
+               free(ctx->savedir);
+       ctx->savedir = sdir;
+       return 0;
+}
+
+int uci_add_delta_path(struct uci_context *ctx, const char *dir)
+{
+       struct uci_element *e;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, dir != NULL);
+       e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
+       uci_list_add(&ctx->delta_path, &e->list);
+
+       return 0;
+}
+
+static inline int uci_parse_delta_tuple(struct uci_context *ctx, char **buf, struct uci_ptr *ptr)
+{
+       int c = UCI_CMD_CHANGE;
+
+       switch(**buf) {
+       case '^':
+               c = UCI_CMD_REORDER;
+               break;
+       case '-':
+               c = UCI_CMD_REMOVE;
+               break;
+       case '@':
+               c = UCI_CMD_RENAME;
+               break;
+       case '+':
+               /* UCI_CMD_ADD is used for anonymous sections or list values */
+               c = UCI_CMD_ADD;
+               break;
+       case '|':
+               c = UCI_CMD_LIST_ADD;
+               break;
+       }
+
+       if (c != UCI_CMD_CHANGE)
+               *buf += 1;
+
+       UCI_INTERNAL(uci_parse_ptr, ctx, ptr, *buf);
+
+       if (!ptr->section)
+               goto error;
+       if (ptr->flags & UCI_LOOKUP_EXTENDED)
+               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;
+               break;
+       case UCI_CMD_LIST_ADD:
+               if (!ptr->option)
+                       goto error;
+       }
+
+       return c;
+
+error:
+       UCI_THROW(ctx, UCI_ERR_INVAL);
+       return 0;
+}
+
+static void uci_parse_delta_line(struct uci_context *ctx, struct uci_package *p, char *buf)
+{
+       struct uci_element *e = NULL;
+       struct uci_ptr ptr;
+       int cmd;
+
+       cmd = uci_parse_delta_tuple(ctx, &buf, &ptr);
+       if (strcmp(ptr.package, p->e.name) != 0)
+               goto error;
+
+       if (ctx->flags & UCI_FLAG_SAVED_DELTA)
+               uci_add_delta(ctx, &p->saved_delta, 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;
+       case UCI_CMD_REMOVE:
+               UCI_INTERNAL(uci_delete, ctx, &ptr);
+               break;
+       case UCI_CMD_LIST_ADD:
+               UCI_INTERNAL(uci_add_list, ctx, &ptr);
+               break;
+       case UCI_CMD_ADD:
+       case UCI_CMD_CHANGE:
+               UCI_INTERNAL(uci_set, ctx, &ptr);
+               e = ptr.last;
+               if (!ptr.option && e && (cmd == UCI_CMD_ADD))
+                       uci_to_section(e)->anonymous = true;
+               break;
+       }
+       return;
+error:
+       UCI_THROW(ctx, UCI_ERR_PARSE);
+}
+
+/* returns the number of changes that were successfully parsed */
+static int uci_parse_delta(struct uci_context *ctx, FILE *stream, struct uci_package *p)
+{
+       struct uci_parse_context *pctx;
+       int changes = 0;
+
+       /* make sure no memory from previous parse attempts is leaked */
+       uci_cleanup(ctx);
+
+       pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context));
+       ctx->pctx = pctx;
+       pctx->file = stream;
+
+       while (!feof(pctx->file)) {
+               uci_getln(ctx, 0);
+               if (!pctx->buf[0])
+                       continue;
+
+               /*
+                * ignore parse errors in single lines, we want to preserve as much
+                * delta as possible
+                */
+               UCI_TRAP_SAVE(ctx, error);
+               uci_parse_delta_line(ctx, p, pctx->buf);
+               UCI_TRAP_RESTORE(ctx);
+               changes++;
+error:
+               continue;
+       }
+
+       /* no error happened, we can get rid of the parser context now */
+       uci_cleanup(ctx);
+       return changes;
+}
+
+/* returns the number of changes that were successfully parsed */
+static int uci_load_delta_file(struct uci_context *ctx, struct uci_package *p, char *filename, FILE **f, bool flush)
+{
+       FILE *stream = NULL;
+       int changes = 0;
+
+       UCI_TRAP_SAVE(ctx, done);
+       stream = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
+       if (p)
+               changes = uci_parse_delta(ctx, stream, p);
+       UCI_TRAP_RESTORE(ctx);
+done:
+       if (f)
+               *f = stream;
+       else if (stream)
+               uci_close_stream(stream);
+       return changes;
+}
+
+/* returns the number of changes that were successfully parsed */
+__private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, bool flush)
+{
+       struct uci_element *e;
+       char *filename = NULL;
+       FILE *f = NULL;
+       int changes = 0;
+
+       if (!p->has_delta)
+               return 0;
+
+       uci_foreach_element(&ctx->delta_path, e) {
+               if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
+                       UCI_THROW(ctx, UCI_ERR_MEM);
+
+               uci_load_delta_file(ctx, p, filename, NULL, false);
+               free(filename);
+       }
+
+       if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
+               UCI_THROW(ctx, UCI_ERR_MEM);
+
+       changes = uci_load_delta_file(ctx, p, filename, &f, flush);
+       if (flush && f && (changes > 0)) {
+               rewind(f);
+               if (ftruncate(fileno(f), 0) < 0) {
+                       uci_close_stream(f);
+                       UCI_THROW(ctx, UCI_ERR_IO);
+               }
+       }
+       if (filename)
+               free(filename);
+       uci_close_stream(f);
+       ctx->err = 0;
+       return changes;
+}
+
+static void uci_filter_delta(struct uci_context *ctx, const char *name, const char *section, const char *option)
+{
+       struct uci_parse_context *pctx;
+       struct uci_element *e, *tmp;
+       struct uci_list list;
+       char *filename = NULL;
+       struct uci_ptr ptr;
+       FILE *f = NULL;
+
+       uci_list_init(&list);
+       uci_alloc_parse_context(ctx);
+       pctx = ctx->pctx;
+
+       if ((asprintf(&filename, "%s/%s", ctx->savedir, name) < 0) || !filename)
+               UCI_THROW(ctx, UCI_ERR_MEM);
+
+       UCI_TRAP_SAVE(ctx, done);
+       f = uci_open_stream(ctx, filename, SEEK_SET, true, false);
+       pctx->file = f;
+       while (!feof(f)) {
+               struct uci_element *e;
+               char *buf;
+
+               uci_getln(ctx, 0);
+               buf = pctx->buf;
+               if (!buf[0])
+                       continue;
+
+               /* NB: need to allocate the element before the call to 
+                * uci_parse_delta_tuple, otherwise the original string 
+                * gets modified before it is saved */
+               e = uci_alloc_generic(ctx, UCI_TYPE_DELTA, pctx->buf, sizeof(struct uci_element));
+               uci_list_add(&list, &e->list);
+
+               uci_parse_delta_tuple(ctx, &buf, &ptr);
+               if (section) {
+                       if (!ptr.section || (strcmp(section, ptr.section) != 0))
+                               continue;
+               }
+               if (option) {
+                       if (!ptr.option || (strcmp(option, ptr.option) != 0))
+                               continue;
+               }
+               /* match, drop this element again */
+               uci_free_element(e);
+       }
+
+       /* rebuild the delta file */
+       rewind(f);
+       if (ftruncate(fileno(f), 0) < 0)
+               UCI_THROW(ctx, UCI_ERR_IO);
+       uci_foreach_element_safe(&list, tmp, e) {
+               fprintf(f, "%s\n", e->name);
+               uci_free_element(e);
+       }
+       UCI_TRAP_RESTORE(ctx);
+
+done:
+       if (filename)
+               free(filename);
+       uci_close_stream(pctx->file);
+       uci_foreach_element_safe(&list, tmp, e) {
+               uci_free_element(e);
+       }
+       uci_cleanup(ctx);
+}
+
+int uci_revert(struct uci_context *ctx, struct uci_ptr *ptr)
+{
+       char *package = NULL;
+       char *section = NULL;
+       char *option = NULL;
+
+       UCI_HANDLE_ERR(ctx);
+       expand_ptr(ctx, ptr, false);
+       UCI_ASSERT(ctx, ptr->p->has_delta);
+
+       /* 
+        * - flush unwritten changes
+        * - save the package name
+        * - unload the package
+        * - filter the delta
+        * - reload the package
+        */
+       UCI_TRAP_SAVE(ctx, error);
+       UCI_INTERNAL(uci_save, ctx, ptr->p);
+
+       /* NB: need to clone package, section and option names, 
+        * as they may get freed on uci_free_package() */
+       package = uci_strdup(ctx, ptr->p->e.name);
+       if (ptr->section)
+               section = uci_strdup(ctx, ptr->section);
+       if (ptr->option)
+               option = uci_strdup(ctx, ptr->option);
+
+       uci_free_package(&ptr->p);
+       uci_filter_delta(ctx, package, section, option);
+
+       UCI_INTERNAL(uci_load, ctx, package, &ptr->p);
+       UCI_TRAP_RESTORE(ctx);
+       ctx->err = 0;
+
+error:
+       if (package)
+               free(package);
+       if (section)
+               free(section);
+       if (option)
+               free(option);
+       if (ctx->err)
+               UCI_THROW(ctx, ctx->err);
+       return 0;
+}
+
+int uci_save(struct uci_context *ctx, struct uci_package *p)
+{
+       FILE *f = NULL;
+       char *filename = NULL;
+       struct uci_element *e, *tmp;
+       struct stat statbuf;
+
+       UCI_HANDLE_ERR(ctx);
+       UCI_ASSERT(ctx, p != NULL);
+
+       /* 
+        * if the config file was outside of the /etc/config path,
+        * don't save the delta to a file, update the real file
+        * directly.
+        * does not modify the uci_package pointer
+        */
+       if (!p->has_delta)
+               return uci_commit(ctx, &p, false);
+
+       if (uci_list_empty(&p->delta))
+               return 0;
+
+       if (stat(ctx->savedir, &statbuf) < 0)
+               mkdir(ctx->savedir, UCI_DIRMODE);
+       else if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
+               UCI_THROW(ctx, UCI_ERR_IO);
+
+       if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
+               UCI_THROW(ctx, UCI_ERR_MEM);
+
+       uci_foreach_element(&ctx->hooks, tmp) {
+               struct uci_hook *hook = uci_to_hook(tmp);
+
+               if (!hook->ops->set)
+                       continue;
+
+               uci_foreach_element(&p->delta, e) {
+                       hook->ops->set(hook->ops, p, uci_to_delta(e));
+               }
+       }
+
+       ctx->err = 0;
+       UCI_TRAP_SAVE(ctx, done);
+       f = uci_open_stream(ctx, filename, SEEK_END, true, true);
+       UCI_TRAP_RESTORE(ctx);
+
+       uci_foreach_element_safe(&p->delta, tmp, e) {
+               struct uci_delta *h = uci_to_delta(e);
+               char *prefix = "";
+
+               switch(h->cmd) {
+               case UCI_CMD_REMOVE:
+                       prefix = "-";
+                       break;
+               case UCI_CMD_RENAME:
+                       prefix = "@";
+                       break;
+               case UCI_CMD_ADD:
+                       prefix = "+";
+                       break;
+               case UCI_CMD_REORDER:
+                       prefix = "^";
+                       break;
+               case UCI_CMD_LIST_ADD:
+                       prefix = "|";
+                       break;
+               default:
+                       break;
+               }
+
+               fprintf(f, "%s%s.%s", prefix, p->e.name, h->section);
+               if (e->name)
+                       fprintf(f, ".%s", e->name);
+
+               if (h->cmd == UCI_CMD_REMOVE)
+                       fprintf(f, "\n");
+               else
+                       fprintf(f, "=%s\n", h->value);
+               uci_free_delta(h);
+       }
+
+done:
+       uci_close_stream(f);
+       if (filename)
+               free(filename);
+       if (ctx->err)
+               UCI_THROW(ctx, ctx->err);
+
+       return 0;
+}
+
+
diff --git a/file.c b/file.c
index 33ba93c..0120505 100644 (file)
--- a/file.c
+++ b/file.c
@@ -694,14 +694,14 @@ void uci_file_commit(struct uci_context *ctx, struct uci_package **package, bool
        /* open the config file for writing now, so that it is locked */
        f = uci_open_stream(ctx, p->path, SEEK_SET, true, true);
 
        /* open the config file for writing now, so that it is locked */
        f = uci_open_stream(ctx, p->path, SEEK_SET, true, true);
 
-       /* flush unsaved changes and reload from history file */
+       /* flush unsaved changes and reload from delta file */
        UCI_TRAP_SAVE(ctx, done);
        UCI_TRAP_SAVE(ctx, done);
-       if (p->has_history) {
+       if (p->has_delta) {
                if (!overwrite) {
                        name = uci_strdup(ctx, p->e.name);
                        path = uci_strdup(ctx, p->path);
                if (!overwrite) {
                        name = uci_strdup(ctx, p->e.name);
                        path = uci_strdup(ctx, p->path);
-                       /* dump our own changes to the history file */
-                       if (!uci_list_empty(&p->history))
+                       /* dump our own changes to the delta file */
+                       if (!uci_list_empty(&p->delta))
                                UCI_INTERNAL(uci_save, ctx, p);
 
                        /* 
                                UCI_INTERNAL(uci_save, ctx, p);
 
                        /* 
@@ -713,15 +713,15 @@ void uci_file_commit(struct uci_context *ctx, struct uci_package **package, bool
                        UCI_INTERNAL(uci_import, ctx, f, name, &p, true);
 
                        p->path = path;
                        UCI_INTERNAL(uci_import, ctx, f, name, &p, true);
 
                        p->path = path;
-                       p->has_history = true;
+                       p->has_delta = true;
                        *package = p;
 
                        /* freed together with the uci_package */
                        path = NULL;
                }
 
                        *package = p;
 
                        /* freed together with the uci_package */
                        path = NULL;
                }
 
-               /* flush history */
-               if (!uci_load_history(ctx, p, true))
+               /* flush delta */
+               if (!uci_load_delta(ctx, p, true))
                        goto done;
        }
 
                        goto done;
        }
 
@@ -841,8 +841,8 @@ static struct uci_package *uci_file_load(struct uci_context *ctx, const char *na
 
        if (package) {
                package->path = filename;
 
        if (package) {
                package->path = filename;
-               package->has_history = confdir;
-               uci_load_history(ctx, package, false);
+               package->has_delta = confdir;
+               uci_load_delta(ctx, package, false);
        }
 
 done:
        }
 
 done:
diff --git a/history.c b/history.c
deleted file mode 100644 (file)
index 649ead1..0000000
--- a/history.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * libuci - Library for the Unified Configuration Interface
- * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * This file contains the code for handling uci config history files
- */
-
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
-
-/* record a change that was done to a package */
-void
-uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value)
-{
-       struct uci_history *h;
-       int size = strlen(section) + 1;
-       char *ptr;
-
-       if (value)
-               size += strlen(value) + 1;
-
-       h = uci_alloc_element(ctx, history, option, size);
-       ptr = uci_dataptr(h);
-       h->cmd = cmd;
-       h->section = strcpy(ptr, section);
-       if (value) {
-               ptr += strlen(ptr) + 1;
-               h->value = strcpy(ptr, value);
-       }
-       uci_list_add(list, &h->e.list);
-}
-
-void
-uci_free_history(struct uci_history *h)
-{
-       if (!h)
-               return;
-       if ((h->section != NULL) &&
-               (h->section != uci_dataptr(h))) {
-               free(h->section);
-               free(h->value);
-       }
-       uci_free_element(&h->e);
-}
-
-
-int uci_set_savedir(struct uci_context *ctx, const char *dir)
-{
-       char *sdir;
-
-       UCI_HANDLE_ERR(ctx);
-       UCI_ASSERT(ctx, dir != NULL);
-
-       sdir = uci_strdup(ctx, dir);
-       if (ctx->savedir != uci_savedir)
-               free(ctx->savedir);
-       ctx->savedir = sdir;
-       return 0;
-}
-
-int uci_add_history_path(struct uci_context *ctx, const char *dir)
-{
-       struct uci_element *e;
-
-       UCI_HANDLE_ERR(ctx);
-       UCI_ASSERT(ctx, dir != NULL);
-       e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
-       uci_list_add(&ctx->history_path, &e->list);
-
-       return 0;
-}
-
-static inline int uci_parse_history_tuple(struct uci_context *ctx, char **buf, struct uci_ptr *ptr)
-{
-       int c = UCI_CMD_CHANGE;
-
-       switch(**buf) {
-       case '^':
-               c = UCI_CMD_REORDER;
-               break;
-       case '-':
-               c = UCI_CMD_REMOVE;
-               break;
-       case '@':
-               c = UCI_CMD_RENAME;
-               break;
-       case '+':
-               /* UCI_CMD_ADD is used for anonymous sections or list values */
-               c = UCI_CMD_ADD;
-               break;
-       case '|':
-               c = UCI_CMD_LIST_ADD;
-               break;
-       }
-
-       if (c != UCI_CMD_CHANGE)
-               *buf += 1;
-
-       UCI_INTERNAL(uci_parse_ptr, ctx, ptr, *buf);
-
-       if (!ptr->section)
-               goto error;
-       if (ptr->flags & UCI_LOOKUP_EXTENDED)
-               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;
-               break;
-       case UCI_CMD_LIST_ADD:
-               if (!ptr->option)
-                       goto error;
-       }
-
-       return c;
-
-error:
-       UCI_THROW(ctx, UCI_ERR_INVAL);
-       return 0;
-}
-
-static void uci_parse_history_line(struct uci_context *ctx, struct uci_package *p, char *buf)
-{
-       struct uci_element *e = NULL;
-       struct uci_ptr ptr;
-       int cmd;
-
-       cmd = uci_parse_history_tuple(ctx, &buf, &ptr);
-       if (strcmp(ptr.package, p->e.name) != 0)
-               goto error;
-
-       if (ctx->flags & UCI_FLAG_SAVED_HISTORY)
-               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;
-       case UCI_CMD_REMOVE:
-               UCI_INTERNAL(uci_delete, ctx, &ptr);
-               break;
-       case UCI_CMD_LIST_ADD:
-               UCI_INTERNAL(uci_add_list, ctx, &ptr);
-               break;
-       case UCI_CMD_ADD:
-       case UCI_CMD_CHANGE:
-               UCI_INTERNAL(uci_set, ctx, &ptr);
-               e = ptr.last;
-               if (!ptr.option && e && (cmd == UCI_CMD_ADD))
-                       uci_to_section(e)->anonymous = true;
-               break;
-       }
-       return;
-error:
-       UCI_THROW(ctx, UCI_ERR_PARSE);
-}
-
-/* returns the number of changes that were successfully parsed */
-static int uci_parse_history(struct uci_context *ctx, FILE *stream, struct uci_package *p)
-{
-       struct uci_parse_context *pctx;
-       int changes = 0;
-
-       /* make sure no memory from previous parse attempts is leaked */
-       uci_cleanup(ctx);
-
-       pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context));
-       ctx->pctx = pctx;
-       pctx->file = stream;
-
-       while (!feof(pctx->file)) {
-               uci_getln(ctx, 0);
-               if (!pctx->buf[0])
-                       continue;
-
-               /*
-                * ignore parse errors in single lines, we want to preserve as much
-                * history as possible
-                */
-               UCI_TRAP_SAVE(ctx, error);
-               uci_parse_history_line(ctx, p, pctx->buf);
-               UCI_TRAP_RESTORE(ctx);
-               changes++;
-error:
-               continue;
-       }
-
-       /* no error happened, we can get rid of the parser context now */
-       uci_cleanup(ctx);
-       return changes;
-}
-
-/* returns the number of changes that were successfully parsed */
-static int uci_load_history_file(struct uci_context *ctx, struct uci_package *p, char *filename, FILE **f, bool flush)
-{
-       FILE *stream = NULL;
-       int changes = 0;
-
-       UCI_TRAP_SAVE(ctx, done);
-       stream = uci_open_stream(ctx, filename, SEEK_SET, flush, false);
-       if (p)
-               changes = uci_parse_history(ctx, stream, p);
-       UCI_TRAP_RESTORE(ctx);
-done:
-       if (f)
-               *f = stream;
-       else if (stream)
-               uci_close_stream(stream);
-       return changes;
-}
-
-/* returns the number of changes that were successfully parsed */
-__private int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush)
-{
-       struct uci_element *e;
-       char *filename = NULL;
-       FILE *f = NULL;
-       int changes = 0;
-
-       if (!p->has_history)
-               return 0;
-
-       uci_foreach_element(&ctx->history_path, e) {
-               if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
-                       UCI_THROW(ctx, UCI_ERR_MEM);
-
-               uci_load_history_file(ctx, p, filename, NULL, false);
-               free(filename);
-       }
-
-       if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
-               UCI_THROW(ctx, UCI_ERR_MEM);
-
-       changes = uci_load_history_file(ctx, p, filename, &f, flush);
-       if (flush && f && (changes > 0)) {
-               rewind(f);
-               if (ftruncate(fileno(f), 0) < 0) {
-                       uci_close_stream(f);
-                       UCI_THROW(ctx, UCI_ERR_IO);
-               }
-       }
-       if (filename)
-               free(filename);
-       uci_close_stream(f);
-       ctx->err = 0;
-       return changes;
-}
-
-static void uci_filter_history(struct uci_context *ctx, const char *name, const char *section, const char *option)
-{
-       struct uci_parse_context *pctx;
-       struct uci_element *e, *tmp;
-       struct uci_list list;
-       char *filename = NULL;
-       struct uci_ptr ptr;
-       FILE *f = NULL;
-
-       uci_list_init(&list);
-       uci_alloc_parse_context(ctx);
-       pctx = ctx->pctx;
-
-       if ((asprintf(&filename, "%s/%s", ctx->savedir, name) < 0) || !filename)
-               UCI_THROW(ctx, UCI_ERR_MEM);
-
-       UCI_TRAP_SAVE(ctx, done);
-       f = uci_open_stream(ctx, filename, SEEK_SET, true, false);
-       pctx->file = f;
-       while (!feof(f)) {
-               struct uci_element *e;
-               char *buf;
-
-               uci_getln(ctx, 0);
-               buf = pctx->buf;
-               if (!buf[0])
-                       continue;
-
-               /* NB: need to allocate the element before the call to 
-                * uci_parse_history_tuple, otherwise the original string 
-                * gets modified before it is saved */
-               e = uci_alloc_generic(ctx, UCI_TYPE_HISTORY, pctx->buf, sizeof(struct uci_element));
-               uci_list_add(&list, &e->list);
-
-               uci_parse_history_tuple(ctx, &buf, &ptr);
-               if (section) {
-                       if (!ptr.section || (strcmp(section, ptr.section) != 0))
-                               continue;
-               }
-               if (option) {
-                       if (!ptr.option || (strcmp(option, ptr.option) != 0))
-                               continue;
-               }
-               /* match, drop this element again */
-               uci_free_element(e);
-       }
-
-       /* rebuild the history file */
-       rewind(f);
-       if (ftruncate(fileno(f), 0) < 0)
-               UCI_THROW(ctx, UCI_ERR_IO);
-       uci_foreach_element_safe(&list, tmp, e) {
-               fprintf(f, "%s\n", e->name);
-               uci_free_element(e);
-       }
-       UCI_TRAP_RESTORE(ctx);
-
-done:
-       if (filename)
-               free(filename);
-       uci_close_stream(pctx->file);
-       uci_foreach_element_safe(&list, tmp, e) {
-               uci_free_element(e);
-       }
-       uci_cleanup(ctx);
-}
-
-int uci_revert(struct uci_context *ctx, struct uci_ptr *ptr)
-{
-       char *package = NULL;
-       char *section = NULL;
-       char *option = NULL;
-
-       UCI_HANDLE_ERR(ctx);
-       expand_ptr(ctx, ptr, false);
-       UCI_ASSERT(ctx, ptr->p->has_history);
-
-       /* 
-        * - flush unwritten changes
-        * - save the package name
-        * - unload the package
-        * - filter the history
-        * - reload the package
-        */
-       UCI_TRAP_SAVE(ctx, error);
-       UCI_INTERNAL(uci_save, ctx, ptr->p);
-
-       /* NB: need to clone package, section and option names, 
-        * as they may get freed on uci_free_package() */
-       package = uci_strdup(ctx, ptr->p->e.name);
-       if (ptr->section)
-               section = uci_strdup(ctx, ptr->section);
-       if (ptr->option)
-               option = uci_strdup(ctx, ptr->option);
-
-       uci_free_package(&ptr->p);
-       uci_filter_history(ctx, package, section, option);
-
-       UCI_INTERNAL(uci_load, ctx, package, &ptr->p);
-       UCI_TRAP_RESTORE(ctx);
-       ctx->err = 0;
-
-error:
-       if (package)
-               free(package);
-       if (section)
-               free(section);
-       if (option)
-               free(option);
-       if (ctx->err)
-               UCI_THROW(ctx, ctx->err);
-       return 0;
-}
-
-int uci_save(struct uci_context *ctx, struct uci_package *p)
-{
-       FILE *f = NULL;
-       char *filename = NULL;
-       struct uci_element *e, *tmp;
-       struct stat statbuf;
-
-       UCI_HANDLE_ERR(ctx);
-       UCI_ASSERT(ctx, p != NULL);
-
-       /* 
-        * if the config file was outside of the /etc/config path,
-        * don't save the history to a file, update the real file
-        * directly.
-        * does not modify the uci_package pointer
-        */
-       if (!p->has_history)
-               return uci_commit(ctx, &p, false);
-
-       if (uci_list_empty(&p->history))
-               return 0;
-
-       if (stat(ctx->savedir, &statbuf) < 0)
-               mkdir(ctx->savedir, UCI_DIRMODE);
-       else if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
-               UCI_THROW(ctx, UCI_ERR_IO);
-
-       if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
-               UCI_THROW(ctx, UCI_ERR_MEM);
-
-       uci_foreach_element(&ctx->hooks, tmp) {
-               struct uci_hook *hook = uci_to_hook(tmp);
-
-               if (!hook->ops->set)
-                       continue;
-
-               uci_foreach_element(&p->history, e) {
-                       hook->ops->set(hook->ops, p, uci_to_history(e));
-               }
-       }
-
-       ctx->err = 0;
-       UCI_TRAP_SAVE(ctx, done);
-       f = uci_open_stream(ctx, filename, SEEK_END, true, true);
-       UCI_TRAP_RESTORE(ctx);
-
-       uci_foreach_element_safe(&p->history, tmp, e) {
-               struct uci_history *h = uci_to_history(e);
-               char *prefix = "";
-
-               switch(h->cmd) {
-               case UCI_CMD_REMOVE:
-                       prefix = "-";
-                       break;
-               case UCI_CMD_RENAME:
-                       prefix = "@";
-                       break;
-               case UCI_CMD_ADD:
-                       prefix = "+";
-                       break;
-               case UCI_CMD_REORDER:
-                       prefix = "^";
-                       break;
-               case UCI_CMD_LIST_ADD:
-                       prefix = "|";
-                       break;
-               default:
-                       break;
-               }
-
-               fprintf(f, "%s%s.%s", prefix, p->e.name, h->section);
-               if (e->name)
-                       fprintf(f, ".%s", e->name);
-
-               if (h->cmd == UCI_CMD_REMOVE)
-                       fprintf(f, "\n");
-               else
-                       fprintf(f, "=%s\n", h->value);
-               uci_free_history(h);
-       }
-
-done:
-       uci_close_stream(f);
-       if (filename)
-               free(filename);
-       if (ctx->err)
-               UCI_THROW(ctx, ctx->err);
-
-       return 0;
-}
-
-
index 5b22ef1..1a09fc7 100644 (file)
--- a/libuci.c
+++ b/libuci.c
@@ -44,7 +44,7 @@ static void uci_unload_plugin(struct uci_context *ctx, struct uci_plugin *p);
 
 #include "uci_internal.h"
 #include "list.c"
 
 #include "uci_internal.h"
 #include "list.c"
-#include "history.c"
+#include "delta.c"
 
 /* exported functions */
 struct uci_context *uci_alloc_context(void)
 
 /* exported functions */
 struct uci_context *uci_alloc_context(void)
@@ -57,11 +57,11 @@ struct uci_context *uci_alloc_context(void)
 
        memset(ctx, 0, sizeof(struct uci_context));
        uci_list_init(&ctx->root);
 
        memset(ctx, 0, sizeof(struct uci_context));
        uci_list_init(&ctx->root);
-       uci_list_init(&ctx->history_path);
+       uci_list_init(&ctx->delta_path);
        uci_list_init(&ctx->backends);
        uci_list_init(&ctx->hooks);
        uci_list_init(&ctx->plugins);
        uci_list_init(&ctx->backends);
        uci_list_init(&ctx->hooks);
        uci_list_init(&ctx->plugins);
-       ctx->flags = UCI_FLAG_STRICT | UCI_FLAG_SAVED_HISTORY;
+       ctx->flags = UCI_FLAG_STRICT | UCI_FLAG_SAVED_DELTA;
 
        ctx->confdir = (char *) uci_confdir;
        ctx->savedir = (char *) uci_savedir;
 
        ctx->confdir = (char *) uci_confdir;
        ctx->savedir = (char *) uci_savedir;
@@ -87,7 +87,7 @@ void uci_free_context(struct uci_context *ctx)
                struct uci_package *p = uci_to_package(e);
                uci_free_package(&p);
        }
                struct uci_package *p = uci_to_package(e);
                uci_free_package(&p);
        }
-       uci_foreach_element_safe(&ctx->history_path, tmp, e) {
+       uci_foreach_element_safe(&ctx->delta_path, tmp, e) {
                uci_free_element(e);
        }
        UCI_TRAP_RESTORE(ctx);
                uci_free_element(e);
        }
        UCI_TRAP_RESTORE(ctx);
diff --git a/list.c b/list.c
index 1a080fa..cee1063 100644 (file)
--- a/list.c
+++ b/list.c
@@ -224,8 +224,8 @@ uci_alloc_package(struct uci_context *ctx, const char *name)
        p = uci_alloc_element(ctx, package, name, 0);
        p->ctx = ctx;
        uci_list_init(&p->sections);
        p = uci_alloc_element(ctx, package, name, 0);
        p->ctx = ctx;
        uci_list_init(&p->sections);
-       uci_list_init(&p->history);
-       uci_list_init(&p->saved_history);
+       uci_list_init(&p->delta);
+       uci_list_init(&p->saved_delta);
        return p;
 }
 
        return p;
 }
 
@@ -243,11 +243,11 @@ uci_free_package(struct uci_package **package)
        uci_foreach_element_safe(&p->sections, tmp, e) {
                uci_free_section(uci_to_section(e));
        }
        uci_foreach_element_safe(&p->sections, tmp, e) {
                uci_free_section(uci_to_section(e));
        }
-       uci_foreach_element_safe(&p->history, tmp, e) {
-               uci_free_history(uci_to_history(e));
+       uci_foreach_element_safe(&p->delta, tmp, e) {
+               uci_free_delta(uci_to_delta(e));
        }
        }
-       uci_foreach_element_safe(&p->saved_history, tmp, e) {
-               uci_free_history(uci_to_history(e));
+       uci_foreach_element_safe(&p->saved_delta, tmp, e) {
+               uci_free_delta(uci_to_delta(e));
        }
        uci_free_element(&p->e);
        *package = NULL;
        }
        uci_free_element(&p->e);
        *package = NULL;
@@ -452,8 +452,8 @@ static void uci_add_element_list(struct uci_context *ctx, struct uci_ptr *ptr, b
        struct uci_package *p;
 
        p = ptr->p;
        struct uci_package *p;
 
        p = ptr->p;
-       if (!internal && p->has_history)
-               uci_add_history(ctx, &p->history, UCI_CMD_LIST_ADD, ptr->section, ptr->option, ptr->value);
+       if (!internal && p->has_delta)
+               uci_add_delta(ctx, &p->delta, UCI_CMD_LIST_ADD, ptr->section, ptr->option, ptr->value);
 
        e = uci_alloc_generic(ctx, UCI_TYPE_ITEM, ptr->value, sizeof(struct uci_option));
        uci_list_add(&ptr->o->v.list, &e->list);
 
        e = uci_alloc_generic(ctx, UCI_TYPE_ITEM, ptr->value, sizeof(struct uci_option));
        uci_list_add(&ptr->o->v.list, &e->list);
@@ -461,7 +461,7 @@ static void uci_add_element_list(struct uci_context *ctx, struct uci_ptr *ptr, b
 
 int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)
 {
 
 int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)
 {
-       /* NB: UCI_INTERNAL use means without history tracking */
+       /* NB: UCI_INTERNAL use means without delta tracking */
        bool internal = ctx->internal;
        struct uci_element *e;
        struct uci_package *p;
        bool internal = ctx->internal;
        struct uci_element *e;
        struct uci_package *p;
@@ -475,8 +475,8 @@ int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr)
        UCI_ASSERT(ctx, ptr->s);
        UCI_ASSERT(ctx, ptr->value);
 
        UCI_ASSERT(ctx, ptr->s);
        UCI_ASSERT(ctx, ptr->value);
 
-       if (!internal && p->has_history)
-               uci_add_history(ctx, &p->history, UCI_CMD_RENAME, ptr->section, ptr->option, ptr->value);
+       if (!internal && p->has_delta)
+               uci_add_delta(ctx, &p->delta, UCI_CMD_RENAME, ptr->section, ptr->option, ptr->value);
 
        n = uci_strdup(ctx, ptr->value);
        if (e->name)
 
        n = uci_strdup(ctx, ptr->value);
        if (e->name)
@@ -497,9 +497,9 @@ int uci_reorder_section(struct uci_context *ctx, struct uci_section *s, int pos)
        UCI_HANDLE_ERR(ctx);
 
        uci_list_set_pos(&s->package->sections, &s->e.list, pos);
        UCI_HANDLE_ERR(ctx);
 
        uci_list_set_pos(&s->package->sections, &s->e.list, pos);
-       if (!ctx->internal && p->has_history) {
+       if (!ctx->internal && p->has_delta) {
                sprintf(order, "%d", pos);
                sprintf(order, "%d", pos);
-               uci_add_history(ctx, &p->history, UCI_CMD_REORDER, s->e.name, NULL, order);
+               uci_add_delta(ctx, &p->delta, UCI_CMD_REORDER, s->e.name, NULL, order);
        }
 
        return 0;
        }
 
        return 0;
@@ -515,8 +515,8 @@ int uci_add_section(struct uci_context *ctx, struct uci_package *p, const char *
        s = uci_alloc_section(p, type, NULL);
        uci_fixup_section(ctx, s);
        *res = s;
        s = uci_alloc_section(p, type, NULL);
        uci_fixup_section(ctx, s);
        *res = s;
-       if (!internal && p->has_history)
-               uci_add_history(ctx, &p->history, UCI_CMD_ADD, s->e.name, NULL, type);
+       if (!internal && p->has_delta)
+               uci_add_delta(ctx, &p->delta, UCI_CMD_ADD, s->e.name, NULL, type);
 
        return 0;
 }
 
        return 0;
 }
@@ -535,8 +535,8 @@ int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr)
 
        UCI_ASSERT(ctx, ptr->s);
 
 
        UCI_ASSERT(ctx, ptr->s);
 
-       if (!internal && p->has_history)
-               uci_add_history(ctx, &p->history, UCI_CMD_REMOVE, ptr->section, ptr->option, NULL);
+       if (!internal && p->has_delta)
+               uci_add_delta(ctx, &p->delta, UCI_CMD_REMOVE, ptr->section, ptr->option, NULL);
 
        uci_free_any(&e);
 
 
        uci_free_any(&e);
 
@@ -550,7 +550,7 @@ int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr)
 
 int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)
 {
 
 int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)
 {
-       /* NB: UCI_INTERNAL use means without history tracking */
+       /* NB: UCI_INTERNAL use means without delta tracking */
        bool internal = ctx->internal;
        struct uci_option *prev = NULL;
        const char *value2 = NULL;
        bool internal = ctx->internal;
        struct uci_option *prev = NULL;
        const char *value2 = NULL;
@@ -591,7 +591,7 @@ int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr)
 
 int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
 {
 
 int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
 {
-       /* NB: UCI_INTERNAL use means without history tracking */
+       /* NB: UCI_INTERNAL use means without delta tracking */
        bool internal = ctx->internal;
 
        UCI_HANDLE_ERR(ctx);
        bool internal = ctx->internal;
 
        UCI_HANDLE_ERR(ctx);
@@ -644,8 +644,8 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
                UCI_THROW(ctx, UCI_ERR_INVAL);
        }
 
                UCI_THROW(ctx, UCI_ERR_INVAL);
        }
 
-       if (!internal && ptr->p->has_history)
-               uci_add_history(ctx, &ptr->p->history, UCI_CMD_CHANGE, ptr->section, ptr->option, ptr->value);
+       if (!internal && ptr->p->has_delta)
+               uci_add_delta(ctx, &ptr->p->delta, UCI_CMD_CHANGE, ptr->section, ptr->option, ptr->value);
 
        return 0;
 }
 
        return 0;
 }
index b355420..efa8c1a 100644 (file)
--- a/lua/uci.c
+++ b/lua/uci.c
@@ -689,10 +689,10 @@ uci_lua_revert(lua_State *L)
 static void
 uci_lua_add_change(lua_State *L, struct uci_element *e)
 {
 static void
 uci_lua_add_change(lua_State *L, struct uci_element *e)
 {
-       struct uci_history *h;
+       struct uci_delta *h;
        const char *name;
 
        const char *name;
 
-       h = uci_to_history(e);
+       h = uci_to_delta(e);
        if (!h->section)
                return;
 
        if (!h->section)
                return;
 
@@ -728,14 +728,14 @@ uci_lua_changes_pkg(lua_State *L, struct uci_context *ctx, const char *package)
                        return;
        }
 
                        return;
        }
 
-       if (uci_list_empty(&p->history) && uci_list_empty(&p->saved_history))
+       if (uci_list_empty(&p->delta) && uci_list_empty(&p->saved_delta))
                goto done;
 
        lua_newtable(L);
                goto done;
 
        lua_newtable(L);
-       uci_foreach_element(&p->saved_history, e) {
+       uci_foreach_element(&p->saved_delta, e) {
                uci_lua_add_change(L, e);
        }
                uci_lua_add_change(L, e);
        }
-       uci_foreach_element(&p->history, e) {
+       uci_foreach_element(&p->delta, e) {
                uci_lua_add_change(L, e);
        }
        lua_setfield(L, -2, p->e.name);
                uci_lua_add_change(L, e);
        }
        lua_setfield(L, -2, p->e.name);
@@ -810,14 +810,14 @@ uci_lua_get_savedir(lua_State *L)
 }
 
 static int
 }
 
 static int
-uci_lua_add_history(lua_State *L)
+uci_lua_add_delta(lua_State *L)
 {
        struct uci_context *ctx;
        int ret, offset = 0;
 
        ctx = find_context(L, &offset);
        luaL_checkstring(L, 1 + offset);
 {
        struct uci_context *ctx;
        int ret, offset = 0;
 
        ctx = find_context(L, &offset);
        luaL_checkstring(L, 1 + offset);
-       ret = uci_add_history_path(ctx, lua_tostring(L, -1));
+       ret = uci_add_delta_path(ctx, lua_tostring(L, -1));
        return uci_push_status(L, ctx, false);
 }
 
        return uci_push_status(L, ctx, false);
 }
 
@@ -902,7 +902,7 @@ static const luaL_Reg uci[] = {
        { "reorder", uci_lua_reorder },
        { "changes", uci_lua_changes },
        { "foreach", uci_lua_foreach },
        { "reorder", uci_lua_reorder },
        { "changes", uci_lua_changes },
        { "foreach", uci_lua_foreach },
-       { "add_history", uci_lua_add_history },
+       { "add_delta", uci_lua_add_delta },
        { "load_plugins", uci_lua_load_plugins },
        { "get_confdir", uci_lua_get_confdir },
        { "set_confdir", uci_lua_set_confdir },
        { "load_plugins", uci_lua_load_plugins },
        { "get_confdir", uci_lua_get_confdir },
        { "set_confdir", uci_lua_set_confdir },
diff --git a/uci.h b/uci.h
index 4fa0b6a..5644ca8 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -62,7 +62,7 @@ struct uci_element;
 struct uci_package;
 struct uci_section;
 struct uci_option;
 struct uci_package;
 struct uci_section;
 struct uci_option;
-struct uci_history;
+struct uci_delta;
 struct uci_context;
 struct uci_backend;
 struct uci_parse_context;
 struct uci_context;
 struct uci_backend;
 struct uci_parse_context;
@@ -104,7 +104,7 @@ extern void uci_get_errorstr(struct uci_context *ctx, char **dest, const char *s
  * @single: ignore the 'package' keyword and parse everything into a single package
  *
  * the name parameter is for config files that don't explicitly use the 'package <...>' keyword
  * @single: ignore the 'package' keyword and parse everything into a single package
  *
  * the name parameter is for config files that don't explicitly use the 'package <...>' keyword
- * if 'package' points to a non-null struct pointer, enable history tracking and merge 
+ * if 'package' points to a non-null struct pointer, enable delta tracking and merge 
  */
 extern int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package, bool single);
 
  */
 extern int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package, bool single);
 
@@ -204,7 +204,7 @@ extern int uci_rename(struct uci_context *ctx, struct uci_ptr *ptr);
 extern int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr);
 
 /**
 extern int uci_delete(struct uci_context *ctx, struct uci_ptr *ptr);
 
 /**
- * uci_save: save change history for a package
+ * uci_save: save change delta for a package
  * @ctx: uci context
  * @p: uci_package struct
  */
  * @ctx: uci context
  * @p: uci_package struct
  */
@@ -214,7 +214,7 @@ extern int uci_save(struct uci_context *ctx, struct uci_package *p);
  * uci_commit: commit changes to a package
  * @ctx: uci context
  * @p: uci_package struct pointer
  * uci_commit: commit changes to a package
  * @ctx: uci context
  * @p: uci_package struct pointer
- * @overwrite: overwrite existing config data and flush history
+ * @overwrite: overwrite existing config data and flush delta
  *
  * committing may reload the whole uci_package data,
  * the supplied pointer is updated accordingly
  *
  * committing may reload the whole uci_package data,
  * the supplied pointer is updated accordingly
@@ -230,7 +230,7 @@ extern int uci_commit(struct uci_context *ctx, struct uci_package **p, bool over
 extern int uci_list_configs(struct uci_context *ctx, char ***list);
 
 /** 
 extern int uci_list_configs(struct uci_context *ctx, char ***list);
 
 /** 
- * uci_set_savedir: override the default history save directory
+ * uci_set_savedir: override the default delta save directory
  * @ctx: uci context
  * @dir: directory name
  */
  * @ctx: uci context
  * @dir: directory name
  */
@@ -244,14 +244,14 @@ extern int uci_set_savedir(struct uci_context *ctx, const char *dir);
 extern int uci_set_confdir(struct uci_context *ctx, const char *dir);
 
 /**
 extern int uci_set_confdir(struct uci_context *ctx, const char *dir);
 
 /**
- * uci_add_history_path: add a directory to the search path for change history files
+ * uci_add_delta_path: add a directory to the search path for change delta files
  * @ctx: uci context
  * @dir: directory name
  *
  * This function allows you to add directories, which contain 'overlays'
  * for the active config, that will never be committed.
  */
  * @ctx: uci context
  * @dir: directory name
  *
  * This function allows you to add directories, which contain 'overlays'
  * for the active config, that will never be committed.
  */
-extern int uci_add_history_path(struct uci_context *ctx, const char *dir);
+extern int uci_add_delta_path(struct uci_context *ctx, const char *dir);
 
 /**
  * uci_revert: revert all changes to a config item
 
 /**
  * uci_revert: revert all changes to a config item
@@ -336,7 +336,7 @@ int uci_parse_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *str);
 /* UCI data structures */
 enum uci_type {
        UCI_TYPE_UNSPEC = 0,
 /* UCI data structures */
 enum uci_type {
        UCI_TYPE_UNSPEC = 0,
-       UCI_TYPE_HISTORY = 1,
+       UCI_TYPE_DELTA = 1,
        UCI_TYPE_PACKAGE = 2,
        UCI_TYPE_SECTION = 3,
        UCI_TYPE_OPTION = 4,
        UCI_TYPE_PACKAGE = 2,
        UCI_TYPE_SECTION = 3,
        UCI_TYPE_OPTION = 4,
@@ -356,7 +356,7 @@ enum uci_flags {
        UCI_FLAG_STRICT =        (1 << 0), /* strict mode for the parser */
        UCI_FLAG_PERROR =        (1 << 1), /* print parser error messages */
        UCI_FLAG_EXPORT_NAME =   (1 << 2), /* when exporting, name unnamed sections */
        UCI_FLAG_STRICT =        (1 << 0), /* strict mode for the parser */
        UCI_FLAG_PERROR =        (1 << 1), /* print parser error messages */
        UCI_FLAG_EXPORT_NAME =   (1 << 2), /* when exporting, name unnamed sections */
-       UCI_FLAG_SAVED_HISTORY = (1 << 3), /* store the saved history in memory as well */
+       UCI_FLAG_SAVED_DELTA = (1 << 3), /* store the saved delta in memory as well */
 };
 
 struct uci_element
 };
 
 struct uci_element
@@ -396,8 +396,8 @@ struct uci_context
        char *confdir;
        char *savedir;
 
        char *confdir;
        char *savedir;
 
-       /* search path for history files */
-       struct uci_list history_path;
+       /* search path for delta files */
+       struct uci_list delta_path;
 
        /* private: */
        int err;
 
        /* private: */
        int err;
@@ -416,15 +416,15 @@ struct uci_package
        struct uci_element e;
        struct uci_list sections;
        struct uci_context *ctx;
        struct uci_element e;
        struct uci_list sections;
        struct uci_context *ctx;
-       bool has_history;
+       bool has_delta;
        char *path;
 
        /* private: */
        struct uci_backend *backend;
        void *priv;
        int n_section;
        char *path;
 
        /* private: */
        struct uci_backend *backend;
        void *priv;
        int n_section;
-       struct uci_list history;
-       struct uci_list saved_history;
+       struct uci_list delta;
+       struct uci_list saved_delta;
 };
 
 struct uci_section
 };
 
 struct uci_section
@@ -456,7 +456,7 @@ enum uci_command {
        UCI_CMD_LIST_ADD,
 };
 
        UCI_CMD_LIST_ADD,
 };
 
-struct uci_history
+struct uci_delta
 {
        struct uci_element e;
        enum uci_command cmd;
 {
        struct uci_element e;
        enum uci_command cmd;
@@ -487,7 +487,7 @@ struct uci_ptr
 struct uci_hook_ops
 {
        void (*load)(const struct uci_hook_ops *ops, struct uci_package *p);
 struct uci_hook_ops
 {
        void (*load)(const struct uci_hook_ops *ops, struct uci_package *p);
-       void (*set)(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_history *e);
+       void (*set)(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_delta *e);
 };
 
 struct uci_hook
 };
 
 struct uci_hook
@@ -575,7 +575,7 @@ struct uci_plugin
 
 /* wrappers for dynamic type handling */
 #define uci_type_backend UCI_TYPE_BACKEND
 
 /* wrappers for dynamic type handling */
 #define uci_type_backend UCI_TYPE_BACKEND
-#define uci_type_history UCI_TYPE_HISTORY
+#define uci_type_delta UCI_TYPE_DELTA
 #define uci_type_package UCI_TYPE_PACKAGE
 #define uci_type_section UCI_TYPE_SECTION
 #define uci_type_option UCI_TYPE_OPTION
 #define uci_type_package UCI_TYPE_PACKAGE
 #define uci_type_section UCI_TYPE_SECTION
 #define uci_type_option UCI_TYPE_OPTION
@@ -586,7 +586,7 @@ struct uci_plugin
 #ifdef UCI_DEBUG_TYPECAST
 static const char *uci_typestr[] = {
        [uci_type_backend] = "backend",
 #ifdef UCI_DEBUG_TYPECAST
 static const char *uci_typestr[] = {
        [uci_type_backend] = "backend",
-       [uci_type_history] = "history",
+       [uci_type_delta] = "delta",
        [uci_type_package] = "package",
        [uci_type_section] = "section",
        [uci_type_option] = "option",
        [uci_type_package] = "package",
        [uci_type_section] = "section",
        [uci_type_option] = "option",
@@ -609,7 +609,7 @@ static void uci_typecast_error(int from, int to)
        }
 
 BUILD_CAST(backend)
        }
 
 BUILD_CAST(backend)
-BUILD_CAST(history)
+BUILD_CAST(delta)
 BUILD_CAST(package)
 BUILD_CAST(section)
 BUILD_CAST(option)
 BUILD_CAST(package)
 BUILD_CAST(section)
 BUILD_CAST(option)
@@ -618,7 +618,7 @@ BUILD_CAST(plugin)
 
 #else
 #define uci_to_backend(ptr) container_of(ptr, struct uci_backend, e)
 
 #else
 #define uci_to_backend(ptr) container_of(ptr, struct uci_backend, e)
-#define uci_to_history(ptr) container_of(ptr, struct uci_history, e)
+#define uci_to_delta(ptr) container_of(ptr, struct uci_delta, e)
 #define uci_to_package(ptr) container_of(ptr, struct uci_package, e)
 #define uci_to_section(ptr) container_of(ptr, struct uci_section, e)
 #define uci_to_option(ptr)  container_of(ptr, struct uci_option, e)
 #define uci_to_package(ptr) container_of(ptr, struct uci_package, e)
 #define uci_to_section(ptr) container_of(ptr, struct uci_section, e)
 #define uci_to_option(ptr)  container_of(ptr, struct uci_option, e)
index 7ce00d0..728920d 100644 (file)
@@ -44,8 +44,8 @@ __plugin void *uci_malloc(struct uci_context *ctx, size_t size);
 __plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size);
 __plugin char *uci_strdup(struct uci_context *ctx, const char *str);
 __plugin bool uci_validate_str(const char *str, bool name);
 __plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size);
 __plugin char *uci_strdup(struct uci_context *ctx, const char *str);
 __plugin bool uci_validate_str(const char *str, bool name);
-__plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value);
-__plugin void uci_free_history(struct uci_history *h);
+__plugin void uci_add_delta(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value);
+__plugin void uci_free_delta(struct uci_delta *h);
 __plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
 
 __private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create);
 __plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
 
 __private FILE *uci_open_stream(struct uci_context *ctx, const char *filename, int pos, bool write, bool create);
@@ -60,7 +60,7 @@ __private struct uci_element *uci_lookup_list(struct uci_list *list, const char
 __private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s);
 __private void uci_free_package(struct uci_package **package);
 
 __private void uci_fixup_section(struct uci_context *ctx, struct uci_section *s);
 __private void uci_free_package(struct uci_package **package);
 
-__private int uci_load_history(struct uci_context *ctx, struct uci_package *p, bool flush);
+__private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, bool flush);
 
 static inline bool uci_validate_package(const char *str)
 {
 
 static inline bool uci_validate_package(const char *str)
 {