diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-04-21 15:07:16 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-04-25 20:48:40 +0200 |
commit | 35af4ba4fc21a4b2357c50e6b02a2e3e4b236e88 (patch) | |
tree | 445f9fdf2e96e490cd681dca36d5cc9912474ed3 /lib | |
parent | f2c4b79feaffd7b2fdb4041f47c9cd0f4cc3bc6e (diff) |
treewide: rework internal data type system
Instead of relying on json_object values internally, use custom types to
represent the different ucode value types which brings a number of
advantages compared to the previous approach:
- Due to the use of tagged pointers, small integer, string and bool
values can be stored directly in the pointer addresses, vastly
reducing required heap memory
- Ability to create circular data structures such as
`let o; o = { test: o };`
- Ability to register custom `tostring()` function through prototypes
- Initial mark/sweep GC implementation to tear down circular object
graphs on VM deinit
The change also paves the way for possible future extensions such as
constant variables and meta methods for custom ressource types.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs.c | 312 | ||||
-rw-r--r-- | lib/math.c | 66 | ||||
-rw-r--r-- | lib/ubus.c | 127 | ||||
-rw-r--r-- | lib/uci.c | 431 |
4 files changed, 471 insertions, 465 deletions
@@ -28,29 +28,29 @@ #define err_return(err) do { last_error = err; return NULL; } while(0) //static const uc_ops *ops; -static uc_ressource_type *file_type, *proc_type, *dir_type; +static uc_ressource_type_t *file_type, *proc_type, *dir_type; static int last_error = 0; -static json_object * +static uc_value_t * uc_fs_error(uc_vm *vm, size_t nargs) { - json_object *errmsg; + uc_value_t *errmsg; if (last_error == 0) return NULL; - errmsg = json_object_new_string(strerror(last_error)); + errmsg = ucv_string_new(strerror(last_error)); last_error = 0; return errmsg; } -static json_object * +static uc_value_t * uc_fs_read_common(uc_vm *vm, size_t nargs, const char *type) { - json_object *limit = uc_get_arg(0); - json_object *rv = NULL; + uc_value_t *limit = uc_get_arg(0); + uc_value_t *rv = NULL; char buf[128], *p = NULL, *tmp; size_t rlen, len = 0; const char *lstr; @@ -61,8 +61,8 @@ uc_fs_read_common(uc_vm *vm, size_t nargs, const char *type) if (!fp || !*fp) err_return(EBADF); - if (json_object_is_type(limit, json_type_string)) { - lstr = json_object_get_string(limit); + if (ucv_type(limit) == UC_STRING) { + lstr = ucv_string_get(limit); if (!strcmp(lstr, "line")) { while (true) { @@ -110,8 +110,8 @@ uc_fs_read_common(uc_vm *vm, size_t nargs, const char *type) return NULL; } } - else if (json_object_is_type(limit, json_type_int)) { - lsize = json_object_get_int64(limit); + else if (ucv_type(limit) == UC_INTEGER) { + lsize = ucv_int64_get(limit); if (lsize <= 0) return NULL; @@ -132,43 +132,43 @@ uc_fs_read_common(uc_vm *vm, size_t nargs, const char *type) err_return(EINVAL); } - rv = json_object_new_string_len(p, len); + rv = ucv_string_new_length(p, len); free(p); return rv; } -static json_object * +static uc_value_t * uc_fs_write_common(uc_vm *vm, size_t nargs, const char *type) { - json_object *data = uc_get_arg(0); + uc_value_t *data = uc_get_arg(0); size_t len, wsize; - const char *str; + char *str; FILE **fp = uc_get_self(type); if (!fp || !*fp) err_return(EBADF); - if (json_object_is_type(data, json_type_string)) { - str = json_object_get_string(data); - len = json_object_get_string_len(data); + if (ucv_type(data) == UC_STRING) { + len = ucv_string_length(data); + wsize = fwrite(ucv_string_get(data), 1, len, *fp); } else { - str = json_object_to_json_string(data); + str = ucv_to_jsonstring(vm, data); len = str ? strlen(str) : 0; + wsize = fwrite(str, 1, len, *fp); + free(str); } - wsize = fwrite(str, 1, len, *fp); - if (wsize < len && ferror(*fp)) err_return(errno); - return json_object_new_int64(wsize); + return ucv_int64_new(wsize); } -static json_object * +static uc_value_t * uc_fs_pclose(uc_vm *vm, size_t nargs) { FILE **fp = uc_get_self("fs.proc"); @@ -184,38 +184,38 @@ uc_fs_pclose(uc_vm *vm, size_t nargs) err_return(errno); if (WIFEXITED(rc)) - return xjs_new_int64(WEXITSTATUS(rc)); + return ucv_int64_new(WEXITSTATUS(rc)); if (WIFSIGNALED(rc)) - return xjs_new_int64(-WTERMSIG(rc)); + return ucv_int64_new(-WTERMSIG(rc)); - return xjs_new_int64(0); + return ucv_int64_new(0); } -static json_object * +static uc_value_t * uc_fs_pread(uc_vm *vm, size_t nargs) { return uc_fs_read_common(vm, nargs, "fs.proc"); } -static json_object * +static uc_value_t * uc_fs_pwrite(uc_vm *vm, size_t nargs) { return uc_fs_write_common(vm, nargs, "fs.proc"); } -static json_object * +static uc_value_t * uc_fs_popen(uc_vm *vm, size_t nargs) { - json_object *comm = uc_get_arg(0); - json_object *mode = uc_get_arg(1); + uc_value_t *comm = uc_get_arg(0); + uc_value_t *mode = uc_get_arg(1); FILE *fp; - if (!json_object_is_type(comm, json_type_string)) + if (ucv_type(comm) != UC_STRING) err_return(EINVAL); - fp = popen(json_object_get_string(comm), - json_object_is_type(mode, json_type_string) ? json_object_get_string(mode) : "r"); + fp = popen(ucv_string_get(comm), + ucv_type(mode) == UC_STRING ? ucv_string_get(mode) : "r"); if (!fp) err_return(errno); @@ -224,7 +224,7 @@ uc_fs_popen(uc_vm *vm, size_t nargs) } -static json_object * +static uc_value_t * uc_fs_close(uc_vm *vm, size_t nargs) { FILE **fp = uc_get_self("fs.file"); @@ -235,26 +235,26 @@ uc_fs_close(uc_vm *vm, size_t nargs) fclose(*fp); *fp = NULL; - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_read(uc_vm *vm, size_t nargs) { return uc_fs_read_common(vm, nargs, "fs.file"); } -static json_object * +static uc_value_t * uc_fs_write(uc_vm *vm, size_t nargs) { return uc_fs_write_common(vm, nargs, "fs.file"); } -static json_object * +static uc_value_t * uc_fs_seek(uc_vm *vm, size_t nargs) { - json_object *ofs = uc_get_arg(0); - json_object *how = uc_get_arg(1); + uc_value_t *ofs = uc_get_arg(0); + uc_value_t *how = uc_get_arg(1); int whence, res; long offset; @@ -265,27 +265,27 @@ uc_fs_seek(uc_vm *vm, size_t nargs) if (!ofs) offset = 0; - else if (!json_object_is_type(ofs, json_type_int)) + else if (ucv_type(ofs) != UC_INTEGER) err_return(EINVAL); else - offset = (long)json_object_get_int64(ofs); + offset = (long)ucv_int64_get(ofs); if (!how) whence = 0; - else if (!json_object_is_type(how, json_type_int)) + else if (ucv_type(how) != UC_INTEGER) err_return(EINVAL); else - whence = (int)json_object_get_int64(how); + whence = (int)ucv_int64_get(how); res = fseek(*fp, offset, whence); if (res < 0) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_tell(uc_vm *vm, size_t nargs) { long offset; @@ -300,21 +300,21 @@ uc_fs_tell(uc_vm *vm, size_t nargs) if (offset < 0) err_return(errno); - return json_object_new_int64(offset); + return ucv_int64_new(offset); } -static json_object * +static uc_value_t * uc_fs_open(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); - json_object *mode = uc_get_arg(1); + uc_value_t *path = uc_get_arg(0); + uc_value_t *mode = uc_get_arg(1); FILE *fp; - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - fp = fopen(json_object_get_string(path), - json_object_is_type(mode, json_type_string) ? json_object_get_string(mode) : "r"); + fp = fopen(ucv_string_get(path), + ucv_type(mode) == UC_STRING ? ucv_string_get(mode) : "r"); if (!fp) err_return(errno); @@ -323,7 +323,7 @@ uc_fs_open(uc_vm *vm, size_t nargs) } -static json_object * +static uc_value_t * uc_fs_readdir(uc_vm *vm, size_t nargs) { DIR **dp = uc_get_self("fs.dir"); @@ -338,10 +338,10 @@ uc_fs_readdir(uc_vm *vm, size_t nargs) if (!e) err_return(errno); - return json_object_new_string(e->d_name); + return ucv_string_new(e->d_name); } -static json_object * +static uc_value_t * uc_fs_telldir(uc_vm *vm, size_t nargs) { DIR **dp = uc_get_self("fs.dir"); @@ -355,30 +355,30 @@ uc_fs_telldir(uc_vm *vm, size_t nargs) if (position == -1) err_return(errno); - return json_object_new_int64((int64_t)position); + return ucv_int64_new((int64_t)position); } -static json_object * +static uc_value_t * uc_fs_seekdir(uc_vm *vm, size_t nargs) { - json_object *ofs = uc_get_arg(0); + uc_value_t *ofs = uc_get_arg(0); DIR **dp = uc_get_self("fs.dir"); long position; - if (!json_object_is_type(ofs, json_type_int)) + if (ucv_type(ofs) != UC_INTEGER) err_return(EINVAL); if (!dp || !*dp) err_return(EBADF); - position = (long)json_object_get_int64(ofs); + position = (long)ucv_int64_get(ofs); seekdir(*dp, position); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_closedir(uc_vm *vm, size_t nargs) { DIR **dp = uc_get_self("fs.dir"); @@ -389,19 +389,19 @@ uc_fs_closedir(uc_vm *vm, size_t nargs) closedir(*dp); *dp = NULL; - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_opendir(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); + uc_value_t *path = uc_get_arg(0); DIR *dp; - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - dp = opendir(json_object_get_string(path)); + dp = opendir(ucv_string_get(path)); if (!dp) err_return(errno); @@ -409,15 +409,15 @@ uc_fs_opendir(uc_vm *vm, size_t nargs) return uc_alloc_ressource(dir_type, dp); } -static json_object * +static uc_value_t * uc_fs_readlink(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); - json_object *res; + uc_value_t *path = uc_get_arg(0); + uc_value_t *res; ssize_t buflen = 0, rv; char *buf = NULL, *tmp; - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); do { @@ -430,7 +430,7 @@ uc_fs_readlink(uc_vm *vm, size_t nargs) } buf = tmp; - rv = readlink(json_object_get_string(path), buf, buflen); + rv = readlink(ucv_string_get(path), buf, buflen); if (rv == -1) { free(buf); @@ -442,173 +442,173 @@ uc_fs_readlink(uc_vm *vm, size_t nargs) } while (true); - res = json_object_new_string_len(buf, rv); + res = ucv_string_new_length(buf, rv); free(buf); return res; } -static json_object * +static uc_value_t * uc_fs_stat_common(uc_vm *vm, size_t nargs, bool use_lstat) { - json_object *path = uc_get_arg(0); - json_object *res, *o; + uc_value_t *path = uc_get_arg(0); + uc_value_t *res, *o; struct stat st; int rv; - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - rv = (use_lstat ? lstat : stat)(json_object_get_string(path), &st); + rv = (use_lstat ? lstat : stat)(ucv_string_get(path), &st); if (rv == -1) err_return(errno); - res = json_object_new_object(); + res = ucv_object_new(vm); if (!res) err_return(ENOMEM); - o = json_object_new_object(); + o = ucv_object_new(vm); if (o) { - json_object_object_add(o, "major", json_object_new_int64(major(st.st_dev))); - json_object_object_add(o, "minor", json_object_new_int64(minor(st.st_dev))); + ucv_object_add(o, "major", ucv_int64_new(major(st.st_dev))); + ucv_object_add(o, "minor", ucv_int64_new(minor(st.st_dev))); - json_object_object_add(res, "dev", o); + ucv_object_add(res, "dev", o); } - o = json_object_new_object(); + o = ucv_object_new(vm); if (o) { - json_object_object_add(o, "setuid", json_object_new_boolean(st.st_mode & S_ISUID)); - json_object_object_add(o, "setgid", json_object_new_boolean(st.st_mode & S_ISGID)); - json_object_object_add(o, "sticky", json_object_new_boolean(st.st_mode & S_ISVTX)); + ucv_object_add(o, "setuid", ucv_boolean_new(st.st_mode & S_ISUID)); + ucv_object_add(o, "setgid", ucv_boolean_new(st.st_mode & S_ISGID)); + ucv_object_add(o, "sticky", ucv_boolean_new(st.st_mode & S_ISVTX)); - json_object_object_add(o, "user_read", json_object_new_boolean(st.st_mode & S_IRUSR)); - json_object_object_add(o, "user_write", json_object_new_boolean(st.st_mode & S_IWUSR)); - json_object_object_add(o, "user_exec", json_object_new_boolean(st.st_mode & S_IXUSR)); + ucv_object_add(o, "user_read", ucv_boolean_new(st.st_mode & S_IRUSR)); + ucv_object_add(o, "user_write", ucv_boolean_new(st.st_mode & S_IWUSR)); + ucv_object_add(o, "user_exec", ucv_boolean_new(st.st_mode & S_IXUSR)); - json_object_object_add(o, "group_read", json_object_new_boolean(st.st_mode & S_IRGRP)); - json_object_object_add(o, "group_write", json_object_new_boolean(st.st_mode & S_IWGRP)); - json_object_object_add(o, "group_exec", json_object_new_boolean(st.st_mode & S_IXGRP)); + ucv_object_add(o, "group_read", ucv_boolean_new(st.st_mode & S_IRGRP)); + ucv_object_add(o, "group_write", ucv_boolean_new(st.st_mode & S_IWGRP)); + ucv_object_add(o, "group_exec", ucv_boolean_new(st.st_mode & S_IXGRP)); - json_object_object_add(o, "other_read", json_object_new_boolean(st.st_mode & S_IROTH)); - json_object_object_add(o, "other_write", json_object_new_boolean(st.st_mode & S_IWOTH)); - json_object_object_add(o, "other_exec", json_object_new_boolean(st.st_mode & S_IXOTH)); + ucv_object_add(o, "other_read", ucv_boolean_new(st.st_mode & S_IROTH)); + ucv_object_add(o, "other_write", ucv_boolean_new(st.st_mode & S_IWOTH)); + ucv_object_add(o, "other_exec", ucv_boolean_new(st.st_mode & S_IXOTH)); - json_object_object_add(res, "perm", o); + ucv_object_add(res, "perm", o); } - json_object_object_add(res, "inode", json_object_new_int64((int64_t)st.st_ino)); - json_object_object_add(res, "mode", json_object_new_int64((int64_t)st.st_mode & ~S_IFMT)); - json_object_object_add(res, "nlink", json_object_new_int64((int64_t)st.st_nlink)); - json_object_object_add(res, "uid", json_object_new_int64((int64_t)st.st_uid)); - json_object_object_add(res, "gid", json_object_new_int64((int64_t)st.st_gid)); - json_object_object_add(res, "size", json_object_new_int64((int64_t)st.st_size)); - json_object_object_add(res, "blksize", json_object_new_int64((int64_t)st.st_blksize)); - json_object_object_add(res, "blocks", json_object_new_int64((int64_t)st.st_blocks)); - json_object_object_add(res, "atime", json_object_new_int64((int64_t)st.st_atime)); - json_object_object_add(res, "mtime", json_object_new_int64((int64_t)st.st_mtime)); - json_object_object_add(res, "ctime", json_object_new_int64((int64_t)st.st_ctime)); + ucv_object_add(res, "inode", ucv_int64_new((int64_t)st.st_ino)); + ucv_object_add(res, "mode", ucv_int64_new((int64_t)st.st_mode & ~S_IFMT)); + ucv_object_add(res, "nlink", ucv_int64_new((int64_t)st.st_nlink)); + ucv_object_add(res, "uid", ucv_int64_new((int64_t)st.st_uid)); + ucv_object_add(res, "gid", ucv_int64_new((int64_t)st.st_gid)); + ucv_object_add(res, "size", ucv_int64_new((int64_t)st.st_size)); + ucv_object_add(res, "blksize", ucv_int64_new((int64_t)st.st_blksize)); + ucv_object_add(res, "blocks", ucv_int64_new((int64_t)st.st_blocks)); + ucv_object_add(res, "atime", ucv_int64_new((int64_t)st.st_atime)); + ucv_object_add(res, "mtime", ucv_int64_new((int64_t)st.st_mtime)); + ucv_object_add(res, "ctime", ucv_int64_new((int64_t)st.st_ctime)); if (S_ISREG(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("file")); + ucv_object_add(res, "type", ucv_string_new("file")); else if (S_ISDIR(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("directory")); + ucv_object_add(res, "type", ucv_string_new("directory")); else if (S_ISCHR(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("char")); + ucv_object_add(res, "type", ucv_string_new("char")); else if (S_ISBLK(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("block")); + ucv_object_add(res, "type", ucv_string_new("block")); else if (S_ISFIFO(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("fifo")); + ucv_object_add(res, "type", ucv_string_new("fifo")); else if (S_ISLNK(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("link")); + ucv_object_add(res, "type", ucv_string_new("link")); else if (S_ISSOCK(st.st_mode)) - json_object_object_add(res, "type", json_object_new_string("socket")); + ucv_object_add(res, "type", ucv_string_new("socket")); else - json_object_object_add(res, "type", json_object_new_string("unknown")); + ucv_object_add(res, "type", ucv_string_new("unknown")); return res; } -static json_object * +static uc_value_t * uc_fs_stat(uc_vm *vm, size_t nargs) { return uc_fs_stat_common(vm, nargs, false); } -static json_object * +static uc_value_t * uc_fs_lstat(uc_vm *vm, size_t nargs) { return uc_fs_stat_common(vm, nargs, true); } -static json_object * +static uc_value_t * uc_fs_mkdir(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); - json_object *mode = uc_get_arg(1); + uc_value_t *path = uc_get_arg(0); + uc_value_t *mode = uc_get_arg(1); - if (!json_object_is_type(path, json_type_string) || - (mode && !json_object_is_type(mode, json_type_int))) + if (ucv_type(path) != UC_STRING || + (mode && ucv_type(mode) != UC_INTEGER)) err_return(EINVAL); - if (mkdir(json_object_get_string(path), (mode_t)(mode ? json_object_get_int64(mode) : 0777)) == -1) + if (mkdir(ucv_string_get(path), (mode_t)(mode ? ucv_int64_get(mode) : 0777)) == -1) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_rmdir(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); + uc_value_t *path = uc_get_arg(0); - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - if (rmdir(json_object_get_string(path)) == -1) + if (rmdir(ucv_string_get(path)) == -1) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_symlink(uc_vm *vm, size_t nargs) { - json_object *dest = uc_get_arg(0); - json_object *path = uc_get_arg(1); + uc_value_t *dest = uc_get_arg(0); + uc_value_t *path = uc_get_arg(1); - if (!json_object_is_type(dest, json_type_string) || - !json_object_is_type(path, json_type_string)) + if (ucv_type(dest) != UC_STRING || + ucv_type(path) != UC_STRING) err_return(EINVAL); - if (symlink(json_object_get_string(dest), json_object_get_string(path)) == -1) + if (symlink(ucv_string_get(dest), ucv_string_get(path)) == -1) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_unlink(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); + uc_value_t *path = uc_get_arg(0); - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - if (unlink(json_object_get_string(path)) == -1) + if (unlink(ucv_string_get(path)) == -1) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_fs_getcwd(uc_vm *vm, size_t nargs) { - json_object *res; + uc_value_t *res; char *buf = NULL, *tmp; size_t buflen = 0; @@ -634,25 +634,25 @@ uc_fs_getcwd(uc_vm *vm, size_t nargs) } while (true); - res = json_object_new_string(buf); + res = ucv_string_new(buf); free(buf); return res; } -static json_object * +static uc_value_t * uc_fs_chdir(uc_vm *vm, size_t nargs) { - json_object *path = uc_get_arg(0); + uc_value_t *path = uc_get_arg(0); - if (!json_object_is_type(path, json_type_string)) + if (ucv_type(path) != UC_STRING) err_return(EINVAL); - if (chdir(json_object_get_string(path)) == -1) + if (chdir(ucv_string_get(path)) == -1) err_return(errno); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } static const uc_cfunction_list proc_fns[] = { @@ -720,7 +720,7 @@ static void close_dir(void *ud) closedir(dp); } -void uc_module_init(uc_prototype *scope) +void uc_module_init(uc_value_t *scope) { uc_add_proto_functions(scope, global_fns); @@ -728,7 +728,7 @@ void uc_module_init(uc_prototype *scope) file_type = uc_declare_type("fs.file", file_fns, close_file); dir_type = uc_declare_type("fs.dir", dir_fns, close_dir); - uc_add_proto_val(scope, "stdin", uc_alloc_ressource(file_type, stdin)); - uc_add_proto_val(scope, "stdout", uc_alloc_ressource(file_type, stdout)); - uc_add_proto_val(scope, "stderr", uc_alloc_ressource(file_type, stderr)); + ucv_object_add(scope, "stdin", uc_alloc_ressource(file_type, stdin)); + ucv_object_add(scope, "stdout", uc_alloc_ressource(file_type, stdout)); + ucv_object_add(scope, "stderr", uc_alloc_ressource(file_type, stderr)); } @@ -21,105 +21,105 @@ static bool srand_called = false; -static json_object * +static uc_value_t * uc_abs(uc_vm *vm, size_t nargs) { - json_object *v = uc_get_arg(0); - enum json_type t; + uc_value_t *v = uc_get_arg(0); + uc_type_t t; int64_t n; double d; - if (json_object_is_type(v, json_type_null)) - return uc_alloc_double(NAN); + if (ucv_type(v) == UC_NULL) + return ucv_double_new(NAN); t = uc_to_number(v, &n, &d); - if (t == json_type_double) - return (isnan(d) || d < 0) ? uc_alloc_double(-d) : json_object_get(v); + if (t == UC_DOUBLE) + return (isnan(d) || d < 0) ? ucv_double_new(-d) : ucv_get(v); - return (n < 0) ? json_object_new_int64(-n) : json_object_get(v); + return (n < 0) ? ucv_int64_new(-n) : ucv_get(v); } -static json_object * +static uc_value_t * uc_atan2(uc_vm *vm, size_t nargs) { double d1 = uc_to_double(uc_get_arg(0)); double d2 = uc_to_double(uc_get_arg(1)); if (isnan(d1) || isnan(d2)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(atan2(d1, d2)); + return ucv_double_new(atan2(d1, d2)); } -static json_object * +static uc_value_t * uc_cos(uc_vm *vm, size_t nargs) { double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(cos(d)); + return ucv_double_new(cos(d)); } -static json_object * +static uc_value_t * uc_exp(uc_vm *vm, size_t nargs) { double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(exp(d)); + return ucv_double_new(exp(d)); } -static json_object * +static uc_value_t * uc_log(uc_vm *vm, size_t nargs) { double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(log(d)); + return ucv_double_new(log(d)); } -static json_object * +static uc_value_t * uc_sin(uc_vm *vm, size_t nargs) { double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(sin(d)); + return ucv_double_new(sin(d)); } -static json_object * +static uc_value_t * uc_sqrt(uc_vm *vm, size_t nargs) { double d = uc_to_double(uc_get_arg(0)); if (isnan(d)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(sqrt(d)); + return ucv_double_new(sqrt(d)); } -static json_object * +static uc_value_t * uc_pow(uc_vm *vm, size_t nargs) { double x = uc_to_double(uc_get_arg(0)); double y = uc_to_double(uc_get_arg(1)); if (isnan(x) || isnan(y)) - return uc_alloc_double(NAN); + return ucv_double_new(NAN); - return uc_alloc_double(pow(x, y)); + return ucv_double_new(pow(x, y)); } -static json_object * +static uc_value_t * uc_rand(uc_vm *vm, size_t nargs) { struct timeval tv; @@ -131,10 +131,10 @@ uc_rand(uc_vm *vm, size_t nargs) srand_called = true; } - return json_object_new_int64(rand()); + return ucv_int64_new(rand()); } -static json_object * +static uc_value_t * uc_srand(uc_vm *vm, size_t nargs) { int64_t n = uc_to_int64(uc_get_arg(0)); @@ -158,7 +158,7 @@ static const uc_cfunction_list math_fns[] = { { "srand", uc_srand }, }; -void uc_module_init(uc_prototype *scope) +void uc_module_init(uc_value_t *scope) { uc_add_proto_functions(scope, math_fns); } @@ -24,7 +24,7 @@ #define err_return(err) do { last_error = err; return NULL; } while(0) static enum ubus_msg_status last_error = 0; -static uc_ressource_type *conn_type; +static uc_ressource_type_t *conn_type; typedef struct { int timeout; @@ -32,28 +32,28 @@ typedef struct { struct ubus_context *ctx; } ubus_connection; -static json_object * +static uc_value_t * uc_ubus_error(uc_vm *vm, size_t nargs) { - json_object *errmsg; + uc_value_t *errmsg; if (last_error == 0) return NULL; - errmsg = json_object_new_string(ubus_strerror(last_error)); + errmsg = ucv_string_new(ubus_strerror(last_error)); last_error = 0; return errmsg; } -static json_object * -uc_blob_to_json(struct blob_attr *attr, bool table, const char **name); +static uc_value_t * +uc_blob_to_json(uc_vm *vm, struct blob_attr *attr, bool table, const char **name); -static json_object * -uc_blob_array_to_json(struct blob_attr *attr, size_t len, bool table) +static uc_value_t * +uc_blob_array_to_json(uc_vm *vm, struct blob_attr *attr, size_t len, bool table) { - json_object *o = table ? json_object_new_object() : json_object_new_array(); - json_object *v; + uc_value_t *o = table ? ucv_object_new(vm) : ucv_array_new(vm); + uc_value_t *v; struct blob_attr *pos; size_t rem = len; const char *name; @@ -63,21 +63,21 @@ uc_blob_array_to_json(struct blob_attr *attr, size_t len, bool table) __blob_for_each_attr(pos, attr, rem) { name = NULL; - v = uc_blob_to_json(pos, table, &name); + v = uc_blob_to_json(vm, pos, table, &name); if (table && name) - json_object_object_add(o, name, v); + ucv_object_add(o, name, v); else if (!table) - json_object_array_add(o, v); + ucv_array_push(o, v); else - json_object_put(v); + ucv_put(v); } return o; } -static json_object * -uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) +static uc_value_t * +uc_blob_to_json(uc_vm *vm, struct blob_attr *attr, bool table, const char **name) { void *data; int len; @@ -93,16 +93,16 @@ uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) switch (blob_id(attr)) { case BLOBMSG_TYPE_BOOL: - return json_object_new_boolean(*(uint8_t *)data); + return ucv_boolean_new(*(uint8_t *)data); case BLOBMSG_TYPE_INT16: - return json_object_new_int64((int64_t)be16_to_cpu(*(uint16_t *)data)); + return ucv_int64_new((int64_t)be16_to_cpu(*(uint16_t *)data)); case BLOBMSG_TYPE_INT32: - return json_object_new_int64((int64_t)be32_to_cpu(*(uint32_t *)data)); + return ucv_int64_new((int64_t)be32_to_cpu(*(uint32_t *)data)); case BLOBMSG_TYPE_INT64: - return json_object_new_uint64(be64_to_cpu(*(uint64_t *)data)); + return ucv_uint64_new(be64_to_cpu(*(uint64_t *)data)); case BLOBMSG_TYPE_DOUBLE: ; @@ -113,16 +113,16 @@ uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) v.u64 = be64_to_cpu(*(uint64_t *)data); - return json_object_new_double(v.d); + return ucv_double_new(v.d); case BLOBMSG_TYPE_STRING: - return json_object_new_string(data); + return ucv_string_new(data); case BLOBMSG_TYPE_ARRAY: - return uc_blob_array_to_json(data, len, false); + return uc_blob_array_to_json(vm, data, len, false); case BLOBMSG_TYPE_TABLE: - return uc_blob_array_to_json(data, len, true); + return uc_blob_array_to_json(vm, data, len, true); default: return NULL; @@ -130,16 +130,16 @@ uc_blob_to_json(struct blob_attr *attr, bool table, const char **name) } -static json_object * +static uc_value_t * uc_ubus_connect(uc_vm *vm, size_t nargs) { - json_object *socket = uc_get_arg(0); - json_object *timeout = uc_get_arg(1); - json_object *co; + uc_value_t *socket = uc_get_arg(0); + uc_value_t *timeout = uc_get_arg(1); + uc_value_t *co; ubus_connection *c; - if ((socket && !json_object_is_type(socket, json_type_string)) || - (timeout && !json_object_is_type(timeout, json_type_int))) + if ((socket && ucv_type(socket) != UC_STRING) || + (timeout && ucv_type(timeout) != UC_INTEGER)) err_return(UBUS_STATUS_INVALID_ARGUMENT); c = calloc(1, sizeof(*c)); @@ -147,8 +147,8 @@ uc_ubus_connect(uc_vm *vm, size_t nargs) if (!c) err_return(UBUS_STATUS_UNKNOWN_ERROR); - c->ctx = ubus_connect(socket ? json_object_get_string(socket) : NULL); - c->timeout = timeout ? json_object_get_int(timeout) : 30; + c->ctx = ubus_connect(socket ? ucv_string_get(socket) : NULL); + c->timeout = timeout ? ucv_int64_get(timeout) : 30; if (!c->ctx) { free(c); @@ -158,7 +158,7 @@ uc_ubus_connect(uc_vm *vm, size_t nargs) if (c->timeout < 0) c->timeout = 30; - co = json_object_new_object(); + co = ucv_object_new(vm); if (!co) { ubus_free(c->ctx); @@ -174,16 +174,16 @@ uc_ubus_connect(uc_vm *vm, size_t nargs) static void uc_ubus_signatures_cb(struct ubus_context *c, struct ubus_object_data *o, void *p) { - json_object *arr = p; - json_object *sig; + uc_value_t *arr = p; + uc_value_t *sig; if (!o->signature) return; - sig = uc_blob_array_to_json(blob_data(o->signature), blob_len(o->signature), true); + sig = uc_blob_array_to_json(NULL, blob_data(o->signature), blob_len(o->signature), true); if (sig) - json_object_array_add(arr, sig); + ucv_array_push(arr, sig); } static void @@ -198,27 +198,27 @@ uc_ubus_objects_cb(struct ubus_context *c, struct ubus_object_data *o, void *p) json_object_array_add(arr, obj); } -static json_object * +static uc_value_t * uc_ubus_list(uc_vm *vm, size_t nargs) { ubus_connection **c = uc_get_self("ubus.connection"); - json_object *objname = uc_get_arg(0); - json_object *res = NULL; + uc_value_t *objname = uc_get_arg(0); + uc_value_t *res = NULL; enum ubus_msg_status rv; if (!c || !*c || !(*c)->ctx) err_return(UBUS_STATUS_CONNECTION_FAILED); - if (objname && !json_object_is_type(objname, json_type_string)) + if (objname && ucv_type(objname) != UC_STRING) err_return(UBUS_STATUS_INVALID_ARGUMENT); - res = json_object_new_array(); + res = ucv_array_new(vm); if (!res) err_return(UBUS_STATUS_UNKNOWN_ERROR); rv = ubus_lookup((*c)->ctx, - objname ? json_object_get_string(objname) : NULL, + objname ? ucv_string_get(objname) : NULL, objname ? uc_ubus_signatures_cb : uc_ubus_objects_cb, res); @@ -231,41 +231,48 @@ uc_ubus_list(uc_vm *vm, size_t nargs) static void uc_ubus_call_cb(struct ubus_request *req, int type, struct blob_attr *msg) { - json_object **res = (json_object **)req->priv; + uc_value_t **res = (uc_value_t **)req->priv; - *res = msg ? uc_blob_array_to_json(blob_data(msg), blob_len(msg), true) : NULL; + *res = msg ? uc_blob_array_to_json(NULL, blob_data(msg), blob_len(msg), true) : NULL; } -static json_object * +static uc_value_t * uc_ubus_call(uc_vm *vm, size_t nargs) { ubus_connection **c = uc_get_self("ubus.connection"); - json_object *objname = uc_get_arg(0); - json_object *funname = uc_get_arg(1); - json_object *funargs = uc_get_arg(2); - json_object *res = NULL; + uc_value_t *objname = uc_get_arg(0); + uc_value_t *funname = uc_get_arg(1); + uc_value_t *funargs = uc_get_arg(2); + uc_value_t *res = NULL; + json_object *o; enum ubus_msg_status rv; uint32_t id; if (!c || !*c || !(*c)->ctx) err_return(UBUS_STATUS_CONNECTION_FAILED); - if (!json_object_is_type(objname, json_type_string) || - !json_object_is_type(funname, json_type_string) || - (funargs && !json_object_is_type(funargs, json_type_object))) + if (ucv_type(objname) != UC_STRING || + ucv_type(funname) != UC_STRING || + (funargs && ucv_type(funargs) != UC_OBJECT)) err_return(UBUS_STATUS_INVALID_ARGUMENT); blob_buf_init(&(*c)->buf, 0); - if (funargs && !blobmsg_add_object(&(*c)->buf, funargs)) - err_return(UBUS_STATUS_UNKNOWN_ERROR); + if (funargs) { + o = ucv_to_json(funargs); + rv = blobmsg_add_object(&(*c)->buf, o); + json_object_put(o); + + if (!rv) + err_return(UBUS_STATUS_UNKNOWN_ERROR); + } - rv = ubus_lookup_id((*c)->ctx, json_object_get_string(objname), &id); + rv = ubus_lookup_id((*c)->ctx, ucv_string_get(objname), &id); if (rv != UBUS_STATUS_OK) err_return(rv); - rv = ubus_invoke((*c)->ctx, id, json_object_get_string(funname), (*c)->buf.head, + rv = ubus_invoke((*c)->ctx, id, ucv_string_get(funname), (*c)->buf.head, uc_ubus_call_cb, &res, (*c)->timeout * 1000); if (rv != UBUS_STATUS_OK) @@ -274,7 +281,7 @@ uc_ubus_call(uc_vm *vm, size_t nargs) return res; } -static json_object * +static uc_value_t * uc_ubus_disconnect(uc_vm *vm, size_t nargs) { ubus_connection **c = uc_get_self("ubus.connection"); @@ -285,7 +292,7 @@ uc_ubus_disconnect(uc_vm *vm, size_t nargs) ubus_free((*c)->ctx); (*c)->ctx = NULL; - return json_object_new_boolean(true); + return ucv_boolean_new(true); } @@ -313,7 +320,7 @@ static void close_connection(void *ud) { free(conn); } -void uc_module_init(uc_prototype *scope) +void uc_module_init(uc_value_t *scope) { uc_add_proto_functions(scope, global_fns); @@ -22,7 +22,7 @@ #define err_return(err) do { last_error = err; return NULL; } while(0) static int last_error = 0; -static uc_ressource_type *cursor_type; +static uc_ressource_type_t *cursor_type; enum pkg_cmd { CMD_SAVE, @@ -30,11 +30,11 @@ enum pkg_cmd { CMD_REVERT }; -static json_object * +static uc_value_t * uc_uci_error(uc_vm *vm, size_t nargs) { char buf[sizeof("Unknown error: -9223372036854775808")]; - json_object *errmsg; + uc_value_t *errmsg; const char *errstr[] = { [UCI_ERR_MEM] = "Out of memory", @@ -49,12 +49,12 @@ uc_uci_error(uc_vm *vm, size_t nargs) if (last_error == 0) return NULL; - if (last_error >= 0 && last_error < ARRAY_SIZE(errstr)) { - errmsg = json_object_new_string(errstr[last_error]); + if (last_error >= 0 && (unsigned)last_error < ARRAY_SIZE(errstr)) { + errmsg = ucv_string_new(errstr[last_error]); } else { snprintf(buf, sizeof(buf), "Unknown error: %d", last_error); - errmsg = json_object_new_string(buf); + errmsg = ucv_string_new(buf); } last_error = 0; @@ -63,16 +63,16 @@ uc_uci_error(uc_vm *vm, size_t nargs) } -static json_object * +static uc_value_t * uc_uci_cursor(uc_vm *vm, size_t nargs) { - json_object *cdir = uc_get_arg(0); - json_object *sdir = uc_get_arg(1); + uc_value_t *cdir = uc_get_arg(0); + uc_value_t *sdir = uc_get_arg(1); struct uci_context *c; int rv; - if ((cdir && !json_object_is_type(cdir, json_type_string)) || - (sdir && !json_object_is_type(sdir, json_type_string))) + if ((cdir && ucv_type(cdir) != UC_STRING) || + (sdir && ucv_type(sdir) != UC_STRING)) err_return(UCI_ERR_INVAL); c = uci_alloc_context(); @@ -81,14 +81,14 @@ uc_uci_cursor(uc_vm *vm, size_t nargs) err_return(UCI_ERR_MEM); if (cdir) { - rv = uci_set_confdir(c, json_object_get_string(cdir)); + rv = uci_set_confdir(c, ucv_string_get(cdir)); if (rv) err_return(rv); } if (sdir) { - rv = uci_set_savedir(c, json_object_get_string(sdir)); + rv = uci_set_savedir(c, ucv_string_get(sdir)); if (rv) err_return(rv); @@ -98,54 +98,57 @@ uc_uci_cursor(uc_vm *vm, size_t nargs) } -static json_object * +static uc_value_t * uc_uci_load(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); + uc_value_t *conf = uc_get_arg(0); struct uci_element *e; + char *s; if (!c || !*c) err_return(UCI_ERR_INVAL); - if (!json_object_is_type(conf, json_type_string)) + if (ucv_type(conf) != UC_STRING) err_return(UCI_ERR_INVAL); + s = ucv_string_get(conf); + uci_foreach_element(&(*c)->root, e) { - if (!strcmp(e->name, json_object_get_string(conf))) { + if (!strcmp(e->name, s)) { uci_unload(*c, uci_to_package(e)); break; } } - if (uci_load(*c, json_object_get_string(conf), NULL)) + if (uci_load(*c, s, NULL)) err_return((*c)->err); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_unload(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); + uc_value_t *conf = uc_get_arg(0); struct uci_element *e; if (!c || !*c) err_return(UCI_ERR_INVAL); - if (!json_object_is_type(conf, json_type_string)) + if (ucv_type(conf) != UC_STRING) err_return(UCI_ERR_INVAL); uci_foreach_element(&(*c)->root, e) { - if (!strcmp(e->name, json_object_get_string(conf))) { + if (!strcmp(e->name, ucv_string_get(conf))) { uci_unload(*c, uci_to_package(e)); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } } - return json_object_new_boolean(false); + return ucv_boolean_new(false); } static int @@ -177,22 +180,22 @@ lookup_ptr(struct uci_context *ctx, struct uci_ptr *ptr, bool extended) return uci_lookup_ptr(ctx, ptr, NULL, extended); } -static json_object * -option_to_json(struct uci_option *o) +static uc_value_t * +option_to_uval(uc_vm *vm, struct uci_option *o) { - json_object *arr; struct uci_element *e; + uc_value_t *arr; switch (o->type) { case UCI_TYPE_STRING: - return json_object_new_string(o->v.string); + return ucv_string_new(o->v.string); case UCI_TYPE_LIST: - arr = json_object_new_array(); + arr = ucv_array_new(vm); if (arr) uci_foreach_element(&o->v.list, e) - json_object_array_add(arr, json_object_new_string(e->name)); + ucv_array_push(arr, ucv_string_new(e->name)); return arr; @@ -201,36 +204,36 @@ option_to_json(struct uci_option *o) } } -static json_object * -section_to_json(struct uci_section *s, int index) +static uc_value_t * +section_to_uval(uc_vm *vm, struct uci_section *s, int index) { - json_object *so = json_object_new_object(); + uc_value_t *so = ucv_object_new(vm); struct uci_element *e; struct uci_option *o; if (!so) return NULL; - json_object_object_add(so, ".anonymous", json_object_new_boolean(s->anonymous)); - json_object_object_add(so, ".type", json_object_new_string(s->type)); - json_object_object_add(so, ".name", json_object_new_string(s->e.name)); + ucv_object_add(so, ".anonymous", ucv_boolean_new(s->anonymous)); + ucv_object_add(so, ".type", ucv_string_new(s->type)); + ucv_object_add(so, ".name", ucv_string_new(s->e.name)); if (index >= 0) - json_object_object_add(so, ".index", json_object_new_int64(index)); + ucv_object_add(so, ".index", ucv_int64_new(index)); uci_foreach_element(&s->options, e) { o = uci_to_option(e); - json_object_object_add(so, o->e.name, option_to_json(o)); + ucv_object_add(so, o->e.name, option_to_uval(vm, o)); } return so; } -static json_object * -package_to_json(struct uci_package *p) +static uc_value_t * +package_to_uval(uc_vm *vm, struct uci_package *p) { - json_object *po = json_object_new_object(); - json_object *so; + uc_value_t *po = ucv_object_new(vm); + uc_value_t *so; struct uci_element *e; int i = 0; @@ -238,37 +241,37 @@ package_to_json(struct uci_package *p) return NULL; uci_foreach_element(&p->sections, e) { - so = section_to_json(uci_to_section(e), i++); - json_object_object_add(po, e->name, so); + so = section_to_uval(vm, uci_to_section(e), i++); + ucv_object_add(po, e->name, so); } return po; } -static json_object * +static uc_value_t * uc_uci_get_any(uc_vm *vm, size_t nargs, bool all) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *sect = uc_get_arg(1); - json_object *opt = uc_get_arg(2); + uc_value_t *conf = uc_get_arg(0); + uc_value_t *sect = uc_get_arg(1); + uc_value_t *opt = uc_get_arg(2); struct uci_ptr ptr = {}; int rv; if (!c || !*c) err_return(UCI_ERR_INVAL); - if (!json_object_is_type(conf, json_type_string) || - (sect && !json_object_is_type(sect, json_type_string)) || - (opt && !json_object_is_type(opt, json_type_string))) + if ((ucv_type(conf) != UC_STRING) || + (sect && ucv_type(sect) != UC_STRING) || + (opt && ucv_type(opt) != UC_STRING)) err_return(UCI_ERR_INVAL); if ((!sect && !all) || (opt && all)) err_return(UCI_ERR_INVAL); - ptr.package = json_object_get_string(conf); - ptr.section = sect ? json_object_get_string(sect) : NULL; - ptr.option = opt ? json_object_get_string(opt) : NULL; + ptr.package = ucv_string_get(conf); + ptr.section = sect ? ucv_string_get(sect) : NULL; + ptr.option = opt ? ucv_string_get(opt) : NULL; rv = lookup_ptr(*c, &ptr, true); @@ -283,60 +286,60 @@ uc_uci_get_any(uc_vm *vm, size_t nargs, bool all) if (!ptr.s) err_return(UCI_ERR_NOTFOUND); - return section_to_json(ptr.s, -1); + return section_to_uval(vm, ptr.s, -1); } if (!ptr.p) err_return(UCI_ERR_NOTFOUND); - return package_to_json(ptr.p); + return package_to_uval(vm, ptr.p); } if (ptr.option) { if (!ptr.o) err_return(UCI_ERR_NOTFOUND); - return option_to_json(ptr.o); + return option_to_uval(vm, ptr.o); } if (!ptr.s) err_return(UCI_ERR_NOTFOUND); - return json_object_new_string(ptr.s->type); + return ucv_string_new(ptr.s->type); } -static json_object * +static uc_value_t * uc_uci_get(uc_vm *vm, size_t nargs) { return uc_uci_get_any(vm, nargs, false); } -static json_object * +static uc_value_t * uc_uci_get_all(uc_vm *vm, size_t nargs) { return uc_uci_get_any(vm, nargs, true); } -static json_object * +static uc_value_t * uc_uci_get_first(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *type = uc_get_arg(1); - json_object *opt = uc_get_arg(2); + uc_value_t *conf = uc_get_arg(0); + uc_value_t *type = uc_get_arg(1); + uc_value_t *opt = uc_get_arg(2); struct uci_package *p = NULL; struct uci_section *sc; struct uci_element *e; struct uci_ptr ptr = {}; int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(type, json_type_string) || - (opt && !json_object_is_type(opt, json_type_string))) + if (ucv_type(conf) != UC_STRING || + ucv_type(type) != UC_STRING || + (opt && ucv_type(opt) != UC_STRING)) err_return(UCI_ERR_INVAL); uci_foreach_element(&(*c)->root, e) { - if (strcmp(e->name, json_object_get_string(conf))) + if (strcmp(e->name, ucv_string_get(conf))) continue; p = uci_to_package(e); @@ -349,15 +352,15 @@ uc_uci_get_first(uc_vm *vm, size_t nargs) uci_foreach_element(&p->sections, e) { sc = uci_to_section(e); - if (strcmp(sc->type, json_object_get_string(type))) + if (strcmp(sc->type, ucv_string_get(type))) continue; if (!opt) - return json_object_new_string(sc->e.name); + return ucv_string_new(sc->e.name); - ptr.package = json_object_get_string(conf); + ptr.package = ucv_string_get(conf); ptr.section = sc->e.name; - ptr.option = json_object_get_string(opt); + ptr.option = ucv_string_get(opt); ptr.p = p; ptr.s = sc; @@ -369,29 +372,29 @@ uc_uci_get_first(uc_vm *vm, size_t nargs) if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) err_return(UCI_ERR_NOTFOUND); - return option_to_json(ptr.o); + return option_to_uval(vm, ptr.o); } err_return(UCI_ERR_NOTFOUND); } -static json_object * +static uc_value_t * uc_uci_add(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *type = uc_get_arg(1); + uc_value_t *conf = uc_get_arg(0); + uc_value_t *type = uc_get_arg(1); struct uci_element *e = NULL; struct uci_package *p = NULL; struct uci_section *sc = NULL; int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(type, json_type_string)) + if (ucv_type(conf) != UC_STRING || + ucv_type(type) != UC_STRING) err_return(UCI_ERR_INVAL); uci_foreach_element(&(*c)->root, e) { - if (!strcmp(e->name, json_object_get_string(conf))) { + if (!strcmp(e->name, ucv_string_get(conf))) { p = uci_to_package(e); break; } @@ -400,73 +403,75 @@ uc_uci_add(uc_vm *vm, size_t nargs) if (!p) err_return(UCI_ERR_NOTFOUND); - rv = uci_add_section(*c, p, json_object_get_string(type), &sc); + rv = uci_add_section(*c, p, ucv_string_get(type), &sc); if (rv != UCI_OK) err_return(rv); else if (!sc) err_return(UCI_ERR_NOTFOUND); - return json_object_new_string(sc->e.name); + return ucv_string_new(sc->e.name); } static bool -json_to_value(json_object *val, const char **p, bool *is_list) +uval_to_uci(uc_vm *vm, uc_value_t *val, const char **p, bool *is_list) { - json_object *item; + uc_value_t *item; *p = NULL; if (is_list) *is_list = false; - switch (json_object_get_type(val)) { - case json_type_object: - return false; - - case json_type_array: - if (json_object_array_length(val) == 0) + switch (ucv_type(val)) { + case UC_ARRAY: + if (ucv_array_length(val) == 0) return false; - item = json_object_array_get_idx(val, 0); + item = ucv_array_get(val, 0); /* don't recurse */ - if (json_object_is_type(item, json_type_array)) + if (ucv_type(item) == UC_ARRAY) return false; if (is_list) *is_list = true; - return json_to_value(item, p, NULL); + return uval_to_uci(vm, item, p, NULL); - case json_type_boolean: - *p = json_object_get_boolean(val) ? "1" : "0"; + case UC_BOOLEAN: + *p = xstrdup(ucv_boolean_get(val) ? "1" : "0"); return true; - case json_type_null: + case UC_DOUBLE: + case UC_INTEGER: + case UC_STRING: + *p = ucv_to_string(vm, val); + /* fall through */ + + case UC_NULL: return true; default: - *p = json_object_get_string(val); - - return true; + return false; } } -static json_object * +static uc_value_t * uc_uci_set(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *sect = uc_get_arg(1); - json_object *opt = NULL, *val = NULL; + uc_value_t *conf = uc_get_arg(0); + uc_value_t *sect = uc_get_arg(1); + uc_value_t *opt = NULL, *val = NULL; struct uci_ptr ptr = {}; bool is_list = false; - int rv, i; + size_t i; + int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(sect, json_type_string)) + if (ucv_type(conf) != UC_STRING || + ucv_type(sect) != UC_STRING) err_return(UCI_ERR_INVAL); switch (nargs) { @@ -475,7 +480,7 @@ uc_uci_set(uc_vm *vm, size_t nargs) opt = uc_get_arg(2); val = uc_get_arg(3); - if (!json_object_is_type(opt, json_type_string)) + if (ucv_type(opt) != UC_STRING) err_return(UCI_ERR_INVAL); break; @@ -484,7 +489,7 @@ uc_uci_set(uc_vm *vm, size_t nargs) case 3: val = uc_get_arg(2); - if (!json_object_is_type(val, json_type_string)) + if (ucv_type(val) != UC_STRING) err_return(UCI_ERR_INVAL); break; @@ -493,9 +498,9 @@ uc_uci_set(uc_vm *vm, size_t nargs) err_return(UCI_ERR_INVAL); } - ptr.package = json_object_get_string(conf); - ptr.section = json_object_get_string(sect); - ptr.option = opt ? json_object_get_string(opt) : NULL; + ptr.package = ucv_string_get(conf); + ptr.section = ucv_string_get(sect); + ptr.option = opt ? ucv_string_get(opt) : NULL; rv = lookup_ptr(*c, &ptr, true); @@ -505,18 +510,19 @@ uc_uci_set(uc_vm *vm, size_t nargs) if (!ptr.s && ptr.option) err_return(UCI_ERR_NOTFOUND); - if (!json_to_value(val, &ptr.value, &is_list)) + if (!uval_to_uci(vm, val, &ptr.value, &is_list)) err_return(UCI_ERR_INVAL); if (is_list) { /* if we got a one-element array, delete existing option (if any) * and iterate array at offset 0 */ - if (json_object_array_length(val) == 1) { + if (ucv_array_length(val) == 1) { i = 0; - if (ptr.o) { - ptr.value = NULL; + free((char *)ptr.value); + ptr.value = NULL; + if (ptr.o) { rv = uci_delete(*c, &ptr); if (rv != UCI_OK) @@ -529,16 +535,18 @@ uc_uci_set(uc_vm *vm, size_t nargs) i = 1; rv = uci_set(*c, &ptr); + free((char *)ptr.value); if (rv != UCI_OK) err_return(rv); } - for (; i < json_object_array_length(val); i++) { - if (!json_to_value(json_object_array_get_idx(val, i), &ptr.value, NULL)) + for (; i < ucv_array_length(val); i++) { + if (!uval_to_uci(vm, ucv_array_get(val, i), &ptr.value, NULL)) continue; rv = uci_add_list(*c, &ptr); + free((char *)ptr.value); if (rv != UCI_OK) err_return(rv); @@ -546,32 +554,33 @@ uc_uci_set(uc_vm *vm, size_t nargs) } else { rv = uci_set(*c, &ptr); + free((char *)ptr.value); if (rv != UCI_OK) err_return(rv); } - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_delete(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *sect = uc_get_arg(1); - json_object *opt = uc_get_arg(2); + uc_value_t *conf = uc_get_arg(0); + uc_value_t *sect = uc_get_arg(1); + uc_value_t *opt = uc_get_arg(2); struct uci_ptr ptr = {}; int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(sect, json_type_string) || - (opt && !json_object_is_type(opt, json_type_string))) + if (ucv_type(conf) != UC_STRING || + ucv_type(sect) != UC_STRING || + (opt && ucv_type(opt) != UC_STRING)) err_return(UCI_ERR_INVAL); - ptr.package = json_object_get_string(conf); - ptr.section = json_object_get_string(sect); - ptr.option = opt ? json_object_get_string(opt) : NULL; + ptr.package = ucv_string_get(conf); + ptr.section = ucv_string_get(sect); + ptr.option = opt ? ucv_string_get(opt) : NULL; rv = lookup_ptr(*c, &ptr, true); @@ -586,21 +595,21 @@ uc_uci_delete(uc_vm *vm, size_t nargs) if (rv != UCI_OK) err_return(rv); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_rename(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *sect = uc_get_arg(1); - json_object *opt = NULL, *val = NULL; + uc_value_t *conf = uc_get_arg(0); + uc_value_t *sect = uc_get_arg(1); + uc_value_t *opt = NULL, *val = NULL; struct uci_ptr ptr = {}; int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(sect, json_type_string)) + if (ucv_type(conf) != UC_STRING || + ucv_type(sect) != UC_STRING) err_return(UCI_ERR_INVAL); switch (nargs) { @@ -609,8 +618,8 @@ uc_uci_rename(uc_vm *vm, size_t nargs) opt = uc_get_arg(2); val = uc_get_arg(3); - if (!json_object_is_type(opt, json_type_string) || - !json_object_is_type(val, json_type_string)) + if (ucv_type(opt) != UC_STRING || + ucv_type(val) != UC_STRING) err_return(UCI_ERR_INVAL); break; @@ -619,7 +628,7 @@ uc_uci_rename(uc_vm *vm, size_t nargs) case 3: val = uc_get_arg(2); - if (!json_object_is_type(val, json_type_string)) + if (ucv_type(val) != UC_STRING) err_return(UCI_ERR_INVAL); break; @@ -628,10 +637,10 @@ uc_uci_rename(uc_vm *vm, size_t nargs) err_return(UCI_ERR_INVAL); } - ptr.package = json_object_get_string(conf); - ptr.section = json_object_get_string(sect); - ptr.option = opt ? json_object_get_string(opt) : NULL; - ptr.value = json_object_get_string(val); + ptr.package = ucv_string_get(conf); + ptr.section = ucv_string_get(sect); + ptr.option = opt ? ucv_string_get(opt) : NULL; + ptr.value = ucv_string_get(val); rv = lookup_ptr(*c, &ptr, true); @@ -646,32 +655,32 @@ uc_uci_rename(uc_vm *vm, size_t nargs) if (rv != UCI_OK) err_return(rv); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_reorder(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *sect = uc_get_arg(1); - json_object *val = uc_get_arg(2); + uc_value_t *conf = uc_get_arg(0); + uc_value_t *sect = uc_get_arg(1); + uc_value_t *val = uc_get_arg(2); struct uci_ptr ptr = {}; int64_t n; int rv; - if (!json_object_is_type(conf, json_type_string) || - !json_object_is_type(sect, json_type_string) || - !json_object_is_type(val, json_type_int)) + if (ucv_type(conf) != UC_STRING || + ucv_type(sect) != UC_STRING || + ucv_type(val) != UC_INTEGER) err_return(UCI_ERR_INVAL); - n = json_object_get_int64(val); + n = ucv_int64_get(val); if (n < 0) err_return(UCI_ERR_INVAL); - ptr.package = json_object_get_string(conf); - ptr.section = json_object_get_string(sect); + ptr.package = ucv_string_get(conf); + ptr.section = ucv_string_get(sect); rv = lookup_ptr(*c, &ptr, true); @@ -686,14 +695,14 @@ uc_uci_reorder(uc_vm *vm, size_t nargs) if (rv != UCI_OK) err_return(rv); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_pkg_command(uc_vm *vm, size_t nargs, enum pkg_cmd cmd) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); + uc_value_t *conf = uc_get_arg(0); struct uci_element *e, *tmp; struct uci_package *p; struct uci_ptr ptr = {}; @@ -702,13 +711,13 @@ uc_uci_pkg_command(uc_vm *vm, size_t nargs, enum pkg_cmd cmd) if (cmd != CMD_REVERT && conf) err_return(UCI_ERR_INVAL); - if (conf && !json_object_is_type(conf, json_type_string)) + if (conf && ucv_type(conf) != UC_STRING) err_return(UCI_ERR_INVAL); uci_foreach_element_safe(&(*c)->root, tmp, e) { p = uci_to_package(e); - if (conf && strcmp(e->name, json_object_get_string(conf))) + if (conf && strcmp(e->name, ucv_string_get(conf))) continue; switch (cmd) { @@ -736,29 +745,29 @@ uc_uci_pkg_command(uc_vm *vm, size_t nargs, enum pkg_cmd cmd) if (res != UCI_OK) err_return(res); - return json_object_new_boolean(true); + return ucv_boolean_new(true); } -static json_object * +static uc_value_t * uc_uci_save(uc_vm *vm, size_t nargs) { return uc_uci_pkg_command(vm, nargs, CMD_SAVE); } -static json_object * +static uc_value_t * uc_uci_commit(uc_vm *vm, size_t nargs) { return uc_uci_pkg_command(vm, nargs, CMD_COMMIT); } -static json_object * +static uc_value_t * uc_uci_revert(uc_vm *vm, size_t nargs) { return uc_uci_pkg_command(vm, nargs, CMD_REVERT); } -static json_object * -change_to_json(struct uci_delta *d) +static uc_value_t * +change_to_uval(uc_vm *vm, struct uci_delta *d) { const char *types[] = { [UCI_CMD_REORDER] = "order", @@ -770,36 +779,36 @@ change_to_json(struct uci_delta *d) [UCI_CMD_CHANGE] = "set", }; - json_object *a; + uc_value_t *a; if (!d->section) return NULL; - a = json_object_new_array(); + a = ucv_array_new(vm); if (!a) return NULL; - json_object_array_add(a, json_object_new_string(types[d->cmd])); - json_object_array_add(a, json_object_new_string(d->section)); + ucv_array_push(a, ucv_string_new(types[d->cmd])); + ucv_array_push(a, ucv_string_new(d->section)); if (d->e.name) - json_object_array_add(a, json_object_new_string(d->e.name)); + ucv_array_push(a, ucv_string_new(d->e.name)); if (d->value) { if (d->cmd == UCI_CMD_REORDER) - json_object_array_add(a, json_object_new_int64(strtoul(d->value, NULL, 10))); + ucv_array_push(a, ucv_int64_new(strtoul(d->value, NULL, 10))); else - json_object_array_add(a, json_object_new_string(d->value)); + ucv_array_push(a, ucv_string_new(d->value)); } return a; } -static json_object * -changes_to_json(struct uci_context *ctx, const char *package) +static uc_value_t * +changes_to_uval(uc_vm *vm, struct uci_context *ctx, const char *package) { - json_object *a = NULL, *c; + uc_value_t *a = NULL, *c; struct uci_package *p = NULL; struct uci_element *e; bool unload = false; @@ -820,23 +829,23 @@ changes_to_json(struct uci_context *ctx, const char *package) return NULL; if (!uci_list_empty(&p->delta) || !uci_list_empty(&p->saved_delta)) { - a = json_object_new_array(); + a = ucv_array_new(vm); if (!a) err_return(UCI_ERR_MEM); uci_foreach_element(&p->saved_delta, e) { - c = change_to_json(uci_to_delta(e)); + c = change_to_uval(vm, uci_to_delta(e)); if (c) - json_object_array_add(a, c); + ucv_array_push(a, c); } uci_foreach_element(&p->delta, e) { - c = change_to_json(uci_to_delta(e)); + c = change_to_uval(vm, uci_to_delta(e)); if (c) - json_object_array_add(a, c); + ucv_array_push(a, c); } } @@ -846,16 +855,16 @@ changes_to_json(struct uci_context *ctx, const char *package) return a; } -static json_object * +static uc_value_t * uc_uci_changes(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *res, *chg; + uc_value_t *conf = uc_get_arg(0); + uc_value_t *res, *chg; char **configs; int rv, i; - if (conf && !json_object_is_type(conf, json_type_string)) + if (conf && ucv_type(conf) != UC_STRING) err_return(UCI_ERR_INVAL); rv = uci_list_configs(*c, &configs); @@ -863,21 +872,16 @@ uc_uci_changes(uc_vm *vm, size_t nargs) if (rv != UCI_OK) err_return(rv); - res = json_object_new_object(); - - if (!res) { - free(configs); - err_return(UCI_ERR_MEM); - } + res = ucv_object_new(vm); for (i = 0; configs[i]; i++) { - if (conf && strcmp(configs[i], json_object_get_string(conf))) + if (conf && strcmp(configs[i], ucv_string_get(conf))) continue; - chg = changes_to_json(*c, configs[i]); + chg = changes_to_uval(vm, *c, configs[i]); if (chg) - json_object_object_add(res, configs[i], chg); + ucv_object_add(res, configs[i], chg); } free(configs); @@ -885,14 +889,14 @@ uc_uci_changes(uc_vm *vm, size_t nargs) return res; } -static json_object * +static uc_value_t * uc_uci_foreach(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *conf = uc_get_arg(0); - json_object *type = uc_get_arg(1); - json_object *func = uc_get_arg(2); - json_object *rv = NULL; + uc_value_t *conf = uc_get_arg(0); + uc_value_t *type = uc_get_arg(1); + uc_value_t *func = uc_get_arg(2); + uc_value_t *rv = NULL; struct uci_package *p = NULL; struct uci_element *e, *tmp; struct uci_section *sc; @@ -901,12 +905,12 @@ uc_uci_foreach(uc_vm *vm, size_t nargs) bool ret = false; int i = 0; - if (!json_object_is_type(conf, json_type_string) || - (type && !json_object_is_type(type, json_type_string))) + if (ucv_type(conf) != UC_STRING || + (type && ucv_type(type) != UC_STRING)) err_return(UCI_ERR_INVAL); uci_foreach_element(&(*c)->root, e) { - if (strcmp(e->name, json_object_get_string(conf))) + if (strcmp(e->name, ucv_string_get(conf))) continue; p = uci_to_package(e); @@ -920,11 +924,11 @@ uc_uci_foreach(uc_vm *vm, size_t nargs) sc = uci_to_section(e); i++; - if (type && strcmp(sc->type, json_object_get_string(type))) + if (type && strcmp(sc->type, ucv_string_get(type))) continue; - uc_push_val(uc_value_get(func)); - uc_push_val(section_to_json(sc, i - 1)); + uc_push_val(ucv_get(func)); + uc_push_val(section_to_uval(vm, sc, i - 1)); ex = uc_call(1); @@ -934,9 +938,9 @@ uc_uci_foreach(uc_vm *vm, size_t nargs) ret = true; rv = uc_pop_val(); - stop = (json_object_is_type(rv, json_type_boolean) && !json_object_get_boolean(rv)); + stop = (ucv_type(rv) == UC_BOOLEAN && !ucv_boolean_get(rv)); - json_object_put(rv); + ucv_put(rv); if (stop) break; @@ -944,14 +948,14 @@ uc_uci_foreach(uc_vm *vm, size_t nargs) /* XXX: rethrow */ - return json_object_new_boolean(ret); + return ucv_boolean_new(ret); } -static json_object * +static uc_value_t * uc_uci_configs(uc_vm *vm, size_t nargs) { struct uci_context **c = uc_get_self("uci.cursor"); - json_object *a; + uc_value_t *a; char **configs; int i, rv; @@ -960,15 +964,10 @@ uc_uci_configs(uc_vm *vm, size_t nargs) if (rv != UCI_OK) err_return(rv); - a = json_object_new_array(); - - if (!a) { - free(configs); - err_return(UCI_ERR_MEM); - } + a = ucv_array_new(vm); for (i = 0; configs[i]; i++) - json_object_array_add(a, json_object_new_string(configs[i])); + ucv_array_push(a, ucv_string_new(configs[i])); free(configs); @@ -1006,7 +1005,7 @@ static void close_uci(void *ud) { uci_free_context((struct uci_context *)ud); } -void uc_module_init(uc_prototype *scope) +void uc_module_init(uc_value_t *scope) { uc_add_proto_functions(scope, global_fns); |