aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-06-21 22:53:31 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-06-21 22:53:31 +0300
commit9aa885f548d8f6867f8e8cd20d143c4c72a771a1 (patch)
tree2a71433384d8fef69486c271d40a344562d8d62e
parentf507a4f071e7a77a040c535d00fa5a57d0cb6e1d (diff)
downloadsmap-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.c110
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 */

Return to:

Send suggestions and report system problems to the System administrator.