char *tlist_stringify(tlist *list, const char *sep, mmatic *mm) { int l = 0, sl = strlen(sep); char *s, *ret, *p; tlist_reset(list); while ((s = tlist_iter(list))) l += strlen(s) + sl; if (l <= 0) return mmstrdup(""); p = ret = mmalloc(l); tlist_reset(list); while ((s = tlist_iter(list))) { l = strlen(s); memcpy(p, s, l); memcpy(p+l, sep, sl); p += l + sl; } p -= sl; *p = '\0'; /* we dont want the last separator */ return ret; }
/* this probably needs a wise rewrite */ static char *fill_query(struct req *req, char *orig_query, tlist *data) { int i, qs; enum fq_state { NORMAL, INQ } state = NORMAL; xstr *query; MYSQL *conn; ut *arg, *el, *el2; tlist *list, *list2; bool atleastone, atleastone2; #define iskeyw(a) (sizeof(a) == i - qs && strncmp((a), orig_query + qs + 1, sizeof(a) - 1) == 0) /* XXX: uses list and el */ #define appendlist(utlist) do { \ atleastone = false; \ xstr_append(query, "("); \ list = ut_tlist(utlist); \ TLIST_ITER_LOOP(list, el) { \ if (atleastone) \ xstr_append_char(query, ','); \ xstr_append(query, \ pb("\"%s\"", escape(conn, ut_xstr(el)))); \ atleastone = true; \ } \ xstr_append(query, ")"); \ } while(0); conn = uthp_ptr(req->prv, "sqler", "conn"); query = xstr_create("", req); tlist_reset(data); for (i = 0; orig_query[i]; i++) { switch (state) { case NORMAL: if (orig_query[i] == '?') { qs = i; state = INQ; } else { xstr_append_char(query, orig_query[i]); } break; case INQ: if (orig_query[i] == '?') { if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else { /* probably needs an arg */ arg = tlist_iter(data); if (arg) { if (iskeyw("int")) { xstr_append(query, pb("%d", ut_int(arg))); } else if (iskeyw("str")) { xstr_append(query, pb("\"%s\"", escape(conn, ut_xstr(arg)))); } else if (iskeyw("dbl")) { xstr_append(query, pb("%g", ut_double(arg))); } else if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else if (iskeyw("array")) { appendlist(arg); } else if (iskeyw("arrays")) { atleastone2 = false; list2 = ut_tlist(arg); TLIST_ITER_LOOP(list2, el2) { if (atleastone2) xstr_append_char(query, ','); appendlist(el2); atleastone2 = true; } } /* XXX: arg eaten by unrecognizible substitution */ } } state = NORMAL; } else if (orig_query[i] < 'a' || orig_query[i] > 'z') { rollback: while (qs <= i) xstr_append_char(query, orig_query[qs++]); state = NORMAL; } break; }
void tlist_insertbefore(tlist *list, const void *val) { if (!list->current) tlist_reset(list); INSERT_EL(list->current, list->current->prev, list->head); }