diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-21 22:53:31 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-21 22:53:31 +0300 |
commit | 9aa885f548d8f6867f8e8cd20d143c4c72a771a1 (patch) | |
tree | 2a71433384d8fef69486c271d40a344562d8d62e | |
parent | f507a4f071e7a77a040c535d00fa5a57d0cb6e1d (diff) | |
download | smap-9aa885f548d8f6867f8e8cd20d143c4c72a771a1.tar.gz smap-9aa885f548d8f6867f8e8cd20d143c4c72a771a1.tar.bz2 |
Configurable replies for sed databases.
* modules/sed/sed.c (sed_init): Implement module init method.
(sed_init_db): Initialize replies to global ones.
(sed_reply): New function.
(sed_query): Select template depending on whether some
change has been made to the key. Use sed_reply to output
the reply.
-rw-r--r-- | modules/sed/sed.c | 110 |
1 files changed, 101 insertions, 9 deletions
diff --git a/modules/sed/sed.c b/modules/sed/sed.c index bc08c63..0c6d5cc 100644 --- a/modules/sed/sed.c +++ b/modules/sed/sed.c @@ -24,9 +24,14 @@ #include <smap/module.h> #include <smap/parseopt.h> #include <smap/stream.h> +#include <smap/wordsplit.h> #include "transform.h" static size_t dbgid; +static char *def_positive_reply = "OK ${xform}"; +static char *def_negative_reply = "NOTFOUND"; +static char *def_onerror_reply = NULL; +int def_cflags = REG_EXTENDED; struct sed_slist_entry { struct sed_slist_entry *next; @@ -121,23 +126,43 @@ sed_slist_reduce(void *data, char **pret) } +int +sed_init(int argc, char **argv) +{ + static struct smap_option init_option[] = { + { SMAP_OPTSTR(icase), smap_opt_bitmask, + &def_cflags, { REG_ICASE } }, + { SMAP_OPTSTR(extended), smap_opt_bitmask, + &def_cflags, { REG_EXTENDED } }, + { SMAP_OPTSTR(positive-reply), smap_opt_string, + &def_positive_reply }, + { SMAP_OPTSTR(negative-reply), smap_opt_string, + &def_negative_reply }, + { SMAP_OPTSTR(onerror-reply), smap_opt_string, + &def_onerror_reply }, + { NULL } + }; + return smap_parseopt(init_option, argc, argv, 0, NULL); +} + struct sed_db { struct transform tr; struct sed_slist slist; - char *positive_reply; /* FIXME: Not used */ - char *negative_reply; /* FIXME: Not used */ + char *positive_reply; + char *negative_reply; + char *onerror_reply; }; static smap_database_t sed_init_db(const char *dbid, int argc, char **argv) { - int cflags = REG_EXTENDED; int i; struct sed_db *db; - char *positive_reply = NULL; /* FIXME: Not used */ - char *negative_reply = NULL; /* FIXME: Not used */ - char *onerror_reply = NULL; /* FIXME: Not used */ + int cflags = def_cflags; + char *positive_reply = def_positive_reply; + char *negative_reply = def_negative_reply; + char *onerror_reply = def_onerror_reply; struct smap_option init_option[] = { { SMAP_OPTSTR(icase), smap_opt_bitmask, @@ -166,6 +191,9 @@ sed_init_db(const char *dbid, int argc, char **argv) transform_init (&db->tr); db->tr.tr_append = sed_slist_append; db->tr.tr_reduce = sed_slist_reduce; + db->positive_reply = positive_reply; + db->negative_reply = negative_reply; + db->onerror_reply = onerror_reply; slist_init(&db->slist); for (; i < argc; i++) { if (transform_compile_incr(&db->tr, argv[i], cflags)) { @@ -206,6 +234,61 @@ sed_xform(smap_database_t dbp, return 0; } +static char * +format_env(const char *var, const char *val) +{ + char *p = malloc(strlen(var) + strlen(val) + 2); + if (!p) { + smap_error("not enough memory"); + return NULL; + } + strcpy(p, var); + strcat(p, "="); + strcat(p, val); + return p; +} + +static int +sed_reply(smap_stream_t ostr, const char *reply, + const char *map, const char *key, const char *xform) +{ + int rc; + struct wordsplit ws; + char *env[4]; + + if ((env[0] = format_env("map", map)) == NULL) + return 1; + if ((env[1] = format_env("key", key)) == NULL) { + free(env[0]); + return 1; + } + if (xform) { + if ((env[2] = format_env("xform", xform)) == NULL) { + free(env[0]); + free(env[1]); + return 1; + } + } else + env[2] = 0; + env[3] = 0; + + ws.ws_env = (const char **) env; + ws.ws_error = smap_error; + rc = wordsplit(reply, &ws, + WRDSF_NOSPLIT | + WRDSF_NOCMD | + WRDSF_ENV | + WRDSF_ERROR | + WRDSF_SHOWERR); + if (rc == 0) + smap_stream_printf(ostr, "%s\n", ws.ws_wordv[0]); + wordsplit_free(&ws); + free(env[0]); + free(env[1]); + free(env[2]); + return rc; +} + static int sed_query(smap_database_t dbp, smap_stream_t ostr, @@ -214,23 +297,32 @@ sed_query(smap_database_t dbp, { struct sed_db *db = (struct sed_db *)dbp; char *output; + char *repl; + int rc; if (transform_string(&db->tr, key, &db->slist, &output)) { transform_perror(&db->tr, smap_error_str); smap_stream_write(smap_error_str, "\n", 1, NULL); + if (db->onerror_reply) { + return sed_reply(ostr, db->onerror_reply, map, key, + NULL); + } return 1; } - smap_stream_printf(ostr, "OK %s\n", output); + repl = strcmp(key, output) ? + db->positive_reply : db->negative_reply; + rc = sed_reply(ostr, repl, map, key, output); + slist_free(&db->slist); free(output); - return 0; + return rc; } struct smap_module SMAP_EXPORT(sed, module) = { SMAP_MODULE_VERSION, SMAP_CAPA_QUERY|SMAP_CAPA_XFORM, - NULL, /* smap_init */ + sed_init, sed_init_db, sed_free_db, NULL, /* smap_open */ |