10 files changed, 68 insertions(+), 80 deletions(-)

M comment.c
M pipeline.c
M post_nv.c
M render.c
M req.c
M sidebar.c
M story.c
M template.y
M vars.c
M vars.h
M comment.c +6 -6
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2009-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2009-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 81,9 81,9 @@ 
 #define COMMENT_EMPTY		"x"
 
 static const struct nvl_convert_info comment_convert[] = {
-	{ .name = COMMENT_DATE,		.tgt_type = NVT_INT, },
-	{ .name = COMMENT_ID,		.tgt_type = NVT_INT, },
-	{ .name = COMMENT_CAPTCHA,	.tgt_type = NVT_INT, },
+	{ .name = COMMENT_DATE,		.tgt_type = VT_INT, },
+	{ .name = COMMENT_ID,		.tgt_type = VT_INT, },
+	{ .name = COMMENT_CAPTCHA,	.tgt_type = VT_INT, },
 	{ .name = NULL, },
 };
 

          
@@ 416,13 416,13 @@ static const char *save_comment(struct r
 	int id;
 
 	if (nvl_exists_type(req->scgi->request.headers, SCGI_HTTP_USER_AGENT,
-			    NVT_STR)) {
+			    VT_STR)) {
 		DBG("Missing user agent...");
 		return USERAGENT_MISSING;
 	}
 
 	if (nvl_exists_type(req->scgi->request.headers, SCGI_REMOTE_ADDR,
-			    NVT_STR)) {
+			    VT_STR)) {
 		DBG("Missing remote addr...");
 		return INTERNAL_ERR;
 	}

          
M pipeline.c +3 -1
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2013-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 143,6 143,8 @@ static struct val *__escape(struct val *
 		case VT_CONS:
 		case VT_BOOL:
 		case VT_CHAR:
+		case VT_ARRAY:
+		case VT_NVL:
 			panic("%s called with value type %d", __func__,
 			      val->type);
 	}

          
M post_nv.c +19 -39
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2009-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2009-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 31,38 31,27 @@ 
 static int __tag_val(struct nvlist *post, avl_tree_t *list)
 {
 	struct post_tag *cur;
-	struct nvval *tags;
+	struct val **tags;
 	size_t ntags;
 	size_t i;
-	int ret;
 
 	ntags = avl_numnodes(list);
 
-	tags = mem_reallocarray(NULL, ntags, sizeof(struct nvval));
+	tags = mem_reallocarray(NULL, ntags, sizeof(struct val *));
 	if (!tags)
 		return -ENOMEM;
 
 	i = 0;
-	avl_for_each(list, cur) {
-		struct nvval *tag = &tags[i++];
-
-		tag->type = NVT_STR;
-		tag->str = str_getref(cur->tag);
-	}
+	avl_for_each(list, cur)
+		tags[i++] = str_getref_val(cur->tag);
 
-	ret = nvl_set_array(post, "tags", tags, ntags);
-	if (ret) {
-		nvval_release_array(tags, ntags);
-		free(tags);
-	}
-
-	return ret;
+	return nvl_set_array(post, "tags", tags, ntags);
 }
 
 static int __com_val(struct nvlist *post, struct list *list)
 {
 	struct comment *cur;
-	struct nvval *comments;
+	struct val **comments;
 	size_t ncomments;
 	int ret;
 	int i;

          
@@ 76,13 65,12 @@ static int __com_val(struct nvlist *post
 	if (!ncomments)
 		return 0;
 
-	comments = mem_reallocarray(NULL, ncomments, sizeof(struct nvval));
+	comments = mem_reallocarray(NULL, ncomments, sizeof(struct val *));
 	if (!comments)
 		return -ENOMEM;
 
 	i = 0;
 	list_for_each(cur, list) {
-		struct nvval *comment = &comments[i++];
 		struct nvlist *c;
 
 		c = nvl_alloc();

          
@@ 91,8 79,7 @@ static int __com_val(struct nvlist *post
 			goto err;
 		}
 
-		comment->type = NVT_NVL;
-		comment->nvl = c;
+		comments[i++] = nvl_cast_to_val(c);
 
 		if ((ret = nvl_set_int(c, "commid", cur->id)))
 			goto err;

          
@@ 110,14 97,12 @@ static int __com_val(struct nvlist *post
 			goto err;
 	}
 
-	ret = nvl_set_array(post, "comments", comments, ncomments);
-	if (ret)
-		goto err;
-
-	return 0;
+	return nvl_set_array(post, "comments", comments, ncomments);
 
 err:
-	nvval_release_array(comments, i);
+	while (i-- > 0)
+		val_putref(comments[i]);
+
 	free(comments);
 
 	return ret;

          
@@ 202,24 187,20 @@ struct nvlist *get_post(struct req *req,
 }
 
 /*
- * Fill in the `posts' array with all posts matching the prepared and bound
- * statement.
- *
- * `stmt' should be all ready to execute and it should output two columns:
- *     post id
- *     post time
+ * Set "posts", "lastupdate", and "moreposts" vars based on the array of
+ * posts passed in as @posts.
  */
 void load_posts(struct req *req, struct post **posts, int nposts,
 		bool moreposts)
 {
-	struct nvval *nvposts;
+	struct val **nvposts;
 	size_t nnvposts;
 	time_t maxtime;
 	size_t i;
 
 	maxtime = 0;
 
-	nvposts = mem_reallocarray(NULL, nposts, sizeof(struct nvval));
+	nvposts = mem_reallocarray(NULL, nposts, sizeof(struct val *));
 	ASSERT(nvposts);
 
 	nnvposts = 0;

          
@@ 229,9 210,8 @@ void load_posts(struct req *req, struct 
 
 		post_lock(post, true);
 
-		nvposts[nnvposts].type = NVT_NVL;
-		nvposts[nnvposts].nvl = __store_vars(req, post, NULL);
-		if (IS_ERR(nvposts[nnvposts].nvl)) {
+		nvposts[nnvposts] = nvl_cast_to_val(__store_vars(req, post, NULL));
+		if (IS_ERR(nvposts[nnvposts])) {
 			post_unlock(post);
 			post_putref(post);
 			continue;

          
M render.c +2 -2
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2013-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 68,7 68,7 @@ char *render_template(struct req *req, c
 		 tmpl);
 
 	raw = file_cache_get_cb(path, revalidate_all_posts, NULL);
-	if (!raw)
+	if (IS_ERR(raw))
 		return NULL;
 
 	out = render_page(req, str_cstr(raw));

          
M req.c +5 -5
@@ 197,7 197,7 @@ static void log_request(struct req *req)
 	nvl_set_nvl(logentry, "options", tmp);
 
 	/* serialize */
-	buf = nvl_pack(logentry, NVF_JSON);
+	buf = nvl_pack(logentry, VF_JSON);
 	if (IS_ERR(buf))
 		goto err_free;
 

          
@@ 241,10 241,10 @@ void req_head(struct req *req, const cha
 }
 
 static const struct nvl_convert_info info[] = {
-	{ .name = "p",       .tgt_type = NVT_INT, },
-	{ .name = "paged",   .tgt_type = NVT_INT, },
-	{ .name = "m",       .tgt_type = NVT_INT, },
-	{ .name = "preview", .tgt_type = NVT_INT, },
+	{ .name = "p",       .tgt_type = VT_INT, },
+	{ .name = "paged",   .tgt_type = VT_INT, },
+	{ .name = "m",       .tgt_type = VT_INT, },
+	{ .name = "preview", .tgt_type = VT_INT, },
 	{ .name = NULL, },
 };
 

          
M sidebar.c +4 -5
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2013-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 36,7 36,7 @@ 
 
 struct tagcloud_state {
 	unsigned long ntags;
-	struct nvval *cloud;
+	struct val **cloud;
 };
 
 static int __tag_size(int count, int cmin, int cmax)

          
@@ 57,7 57,7 @@ static int __tagcloud_init(void *arg, un
 {
 	struct tagcloud_state *state = arg;
 
-	state->cloud = mem_reallocarray(NULL, ntags, sizeof(struct nvval));
+	state->cloud = mem_reallocarray(NULL, ntags, sizeof(struct val *));
 	state->ntags = 0;
 
 	return state->cloud ? 0 : -ENOMEM;

          
@@ 87,8 87,7 @@ static void __tagcloud_step(void *arg, s
 	if ((ret = nvl_set_int(tmp, "size", __tag_size(count, cmin, cmax))))
 		goto err;
 
-	state->cloud[state->ntags].type = NVT_NVL;
-	state->cloud[state->ntags].nvl = tmp;
+	state->cloud[state->ntags] = nvl_cast_to_val(tmp);
 	state->ntags++;
 
 	return;

          
M story.c +10 -6
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2009-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2009-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 37,7 37,7 @@ 
 static int __load_post(struct req *req, int p, bool preview)
 {
 	struct nvlist *post;
-	struct nvval *val;
+	struct val **val;
 
 	post = get_post(req, p, "title", preview);
 	if (!post) {

          
@@ 49,12 49,16 @@ static int __load_post(struct req *req, 
 		return -ENOENT;
 	}
 
-	val = malloc(sizeof(struct nvval));
-	if (!val)
+	val = malloc(sizeof(struct val *));
+	if (!val) {
+		DBG("failed to allocate val array");
+
+		nvl_putref(post);
+
 		return -ENOMEM;
+	}
 
-	val->type = NVT_NVL;
-	val->nvl = post;
+	*val = nvl_cast_to_val(post);
 
 	vars_set_array(&req->vars, "posts", val, 1);
 

          
M template.y +15 -12
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2012-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2012-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 77,7 77,7 @@ static char *condconcat(struct parser_ou
 
 static char *__foreach(struct req *req, const struct nvpair *var, char *tmpl)
 {
-	const struct nvval *items;
+	struct val **items;
 	size_t nitems;
 	size_t i;
 	char *out;

          
@@ 91,13 91,14 @@ static char *__foreach(struct req *req, 
 	for (i = 0; i < nitems; i++) {
 		vars_scope_push(&req->vars);
 
-		switch (items[i].type) {
-			case NVT_NVL:
-				vars_merge(&req->vars, items[i].nvl);
+		switch (items[i]->type) {
+			case VT_NVL:
+				vars_merge(&req->vars,
+					   val_cast_to_nvl(items[i]));
 				break;
-			case NVT_STR:
+			case VT_STR:
 				vars_set_str(&req->vars, nvpair_name(var),
-					     str_getref(items[i].str));
+					     val_getref_str(items[i]));
 				break;
 			default:
 				//vars_dump(&req->vars);

          
@@ 150,6 151,8 @@ static char *print_val(struct val *val)
 		case VT_CONS:
 		case VT_BOOL:
 		case VT_CHAR:
+		case VT_ARRAY:
+		case VT_NVL:
 			panic("%s called with value of type %d", __func__,
 			      val->type);
 	}

          
@@ 164,12 167,12 @@ static char *print_var(const struct nvpa
 	char *ret;
 
 	switch (nvpair_type(var)) {
-		case NVT_STR:
+		case VT_STR:
 			str = nvpair_value_str(var);
 			ret = xstrdup(str_cstr(str));
 			str_putref(str);
 			break;
-		case NVT_INT:
+		case VT_INT:
 			snprintf(buf, sizeof(buf), "%"PRIu64, pair2int(var));
 			ret = xstrdup(buf);
 			break;

          
@@ 202,10 205,10 @@ static char *pipeline(struct parser_outp
 	}
 
 	switch (nvpair_type(var)) {
-		case NVT_STR:
+		case VT_STR:
 			val = str_cast_to_val(nvpair_value_str(var));
 			break;
-		case NVT_INT:
+		case VT_INT:
 			val = VAL_ALLOC_INT(pair2int(var));
 			break;
 		default:

          
@@ 261,7 264,7 @@ static uint64_t __function_get_arg(struc
 		return 0;
 
 	switch (nvpair_type(var)) {
-		case NVT_INT:
+		case VT_INT:
 			return pair2int(var);
 		default:
 			panic("unexpected nvpair type: %d",

          
M vars.c +2 -2
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2013-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 95,7 95,7 @@ void varfxn(struct vars *vars, const cha
 
 WRAP_SET1(vars_set_str, nvl_set_str, struct str *);
 WRAP_SET1(vars_set_int, nvl_set_int, uint64_t);
-WRAP_SET2(vars_set_array, nvl_set_array, struct nvval *);
+WRAP_SET2(vars_set_array, nvl_set_array, struct val **);
 
 const struct nvpair *vars_lookup(struct vars *vars, const char *name)
 {

          
M vars.h +2 -2
@@ 1,5 1,5 @@ 
 /*
- * Copyright (c) 2013-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2013-2018 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal

          
@@ 38,7 38,7 @@ extern void vars_scope_pop(struct vars *
 extern void vars_set_str(struct vars *vars, const char *name, struct str *val);
 extern void vars_set_int(struct vars *vars, const char *name, uint64_t val);
 extern void vars_set_array(struct vars *vars, const char *name,
-		struct nvval *val, size_t nval);
+		struct val **vals, size_t nval);
 extern const struct nvpair *vars_lookup(struct vars *vars, const char *name);
 extern struct str *vars_lookup_str(struct vars *vars, const char *name);
 extern uint64_t vars_lookup_int(struct vars *vars, const char *name);