/* * STFL - The Structured Terminal Forms Language/Library * Copyright (C) 2006, 2007 Clifford Wolf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * dump.c: Create STFL code from a widget tree */ #include "stfl_internals.h" #include "stfl_compat.h" #include #include #include struct txtnode { struct txtnode *prev; wchar_t *value; int len; }; static void newtxt(struct txtnode **o, const wchar_t *fmt, ...) /* __attribute__ ((format (wprintf, 2, 3))) */ { struct txtnode *n = calloc(1, sizeof(struct txtnode)); n->prev = *o; *o = n; va_list ap; va_start(ap, fmt); wchar_t buf[4096]; vswprintf(buf,4096, fmt, ap); n->value = compat_wcsdup(buf); if (n->value) n->len = wcslen(n->value); else n->len = 0; va_end(ap); } static void myquote(struct txtnode **txt, const wchar_t *text) { wchar_t q[2] = {L'"', 0}; int segment_len; if (wcscspn(text, L"'") > wcscspn(text, L"\"")) q[0] = L'\''; while (*text) { segment_len = wcscspn(text, q); newtxt(txt, L"%c%.*ls%c", q[0], segment_len, text, q[0]); q[0] = q[0] == L'"' ? L'\'' : L'"'; text += segment_len; } } static void mydump(struct stfl_widget *w, const wchar_t *prefix, int focus_id, struct txtnode **txt) { newtxt(txt, L"{%ls%ls", w->id == focus_id ? L"!" : L"", w->type->name); if (w->cls) newtxt(txt, L"#%ls", w->cls); if (w->name) { newtxt(txt, L"["); myquote(txt, prefix); myquote(txt, w->name); newtxt(txt, L"]"); } struct stfl_kv *kv = w->kv_list; while (kv) { if (kv->name) { newtxt(txt, L" %ls[", kv->key); myquote(txt, prefix); myquote(txt, kv->name); newtxt(txt, L"]:"); } else newtxt(txt, L" %ls:", kv->key); myquote(txt, kv->value); kv = kv->next; } struct stfl_widget *c = w->first_child; while (c) { mydump(c, prefix, focus_id, txt); c = c->next_sibling; } newtxt(txt, L"}"); } static wchar_t *txt2string(struct txtnode *txt) { int string_len = 0; struct txtnode *t, *prev; for (t=txt; t; t=t->prev) string_len += t->len; wchar_t *string = malloc(sizeof(wchar_t)*(string_len+1)); int i = string_len; for (t=txt; t; t=prev) { i -= t->len; wmemcpy(string+i, t->value, t->len); prev = t->prev; free(t->value); free(t); } string[string_len] = 0; return string; } wchar_t *stfl_quote_backend(const wchar_t *text) { struct txtnode *txt = 0; myquote(&txt, text); return txt2string(txt); } wchar_t *stfl_widget_dump(struct stfl_widget *w, const wchar_t *prefix, int focus_id) { struct txtnode *txt = 0; mydump(w, prefix, focus_id, &txt); return txt2string(txt); }