diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-16 16:17:03 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-16 16:23:53 +0200 |
commit | 6cfe6f8fe1b7506e772403fecc9d7298fc52dc74 (patch) | |
tree | 64e579d8895bfecfadceb9914f9f795d75e4ccbb /src/meta.c | |
parent | 98ca4bb1bc96cc95bdd141cb653b17029957de38 (diff) | |
download | wydawca-6cfe6f8fe1b7506e772403fecc9d7298fc52dc74.tar.gz wydawca-6cfe6f8fe1b7506e772403fecc9d7298fc52dc74.tar.bz2 |
Improve keyword (meta) expansion, add testsuite framework
* src/meta.c: New file.
* src/Makefile.am (wydawca_SOURCES): Add meta.c.
* Makefile.am (SUBDIRS): Add tests.
* configure.ac: Initialize testsuite.
* src/cmdline.opt: Add preprocessor-related options: --[no-]preprocessor,
-E
* src/mail.c, src/triplet.c, src/verify.c, src/wydawca.c, src/wydawca.h: Use
new expansion functions.
* src/update-2.0.awk: Replace % markup with $.
* etc/wydawca.rc: Switch to new meta-variable syntax.
* gnulib.modules: Add c-ctype.
* doc/Makefile.am (check-options): Rewrite.
* doc/wydawca.texi: Mark unrevised/obsolete material.
* tests/: New directory
Diffstat (limited to 'src/meta.c')
-rw-r--r-- | src/meta.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/meta.c b/src/meta.c new file mode 100644 index 0000000..4516df2 --- /dev/null +++ b/src/meta.c @@ -0,0 +1,183 @@ +/* wydawca - automatic release submission daemon + Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff + + Wydawca is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + Wydawca 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. + + You should have received a copy of the GNU General Public License along + with wydawca. If not, see <http://www.gnu.org/licenses/>. */ + +#include "wydawca.h" +#include "sql.h" +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include <obstack.h> +#include <c-ctype.h> + +static const char * +meta_expand (struct metadef *def, void *data) +{ + if (!def->value) + { + if (def->expand) + return def->expand (def, data); + def->value = "INTERNAL ERROR: NONEXPANDABLE DATA"; + } + return def->value; +} + +static const char * +find_expansion_char (int c, struct metadef *def, void *data) +{ + for (; def->kw; def++) + if (def->kw[1] == 0 && def->kw[0] == c) + return meta_expand (def, data); + return NULL; +} + +static const char * +find_expansion_word (const char *kw, size_t len, + struct metadef *def, void *data) +{ + for (; def->kw; def++) + if (strlen (def->kw) == len && memcmp (def->kw, kw, len) == 0) + return meta_expand (def, data); + return NULL; +} + +char * +meta_expand_string (const char *string, struct metadef *def, void *data) +{ + const char *p, *s; + char *res; + struct obstack stk; + + if (!string) + return NULL; + + obstack_init (&stk); + + for (p = string; *p;) + { + char *e; + size_t len = strcspn (p, "$"); + + obstack_grow (&stk, p, len); + p += len; + if (*p == '$') + { + switch (*++p) + { + case '$': + obstack_grow (&stk, p, 1); + p++; + break; + + case '{': + e = strchr (p + 1, '}'); + if (e && (s = find_expansion_word (p + 1, e - p - 1, def, data))) + { + obstack_grow (&stk, s, strlen (s)); + p = e + 1; + } + else + { + obstack_grow (&stk, p - 1, 1); + p++; + } + break; + + default: + if ((s = find_expansion_char (*p, def, data)) != NULL) + len = strlen (s); + else + { + s = p - 1; + len = 1; + } + obstack_grow (&stk, s, len); + p++; + } + } + else + obstack_grow (&stk, p, 1); + } + obstack_1grow (&stk, 0); + res = xstrdup (obstack_finish (&stk)); + obstack_free (&stk, NULL); + return res; +} + +/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed + quoted string. Return its length. */ +static size_t +quote_string (struct access_method *method, const char *input, char **poutput) +{ + size_t size, len; + int quote; + char *output; + + if (!input) + { + *poutput = xmalloc (1); + (*poutput)[0] = 0; + return 1; + } + + switch (method->type) + { + case method_sql: + len = strlen (input); + size = 2 * len + 1; + output = xmalloc (size); + mysql_real_escape_string (&method->v.sqlconn->mysql, output, input, len); + size = strlen (output); + break; + + default: + size = argcv_quoted_length (input, "e); + output = xmalloc (size); + argcv_quote_copy (output, input); + break; + } + + *poutput = output; + return size; +} + +void +meta_escape (struct access_method *method, struct metadef *def) +{ + for (; def->kw; def++) + { + if (def->value) + { + char *newval; + quote_string (method, def->value, &newval); + if (def->storage) + free (def->storage); + def->value = def->storage = newval; + } + } +} + +void +meta_free (struct metadef *def) +{ + for (; def->kw; def++) + { + if (def->storage) + { + free (def->storage); + def->value = def->storage = NULL; + } + } +} + |