aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-09-28 14:15:44 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-09-28 14:15:44 +0300
commit4aef6e9feff509e8cb267473d505e82dd794df78 (patch)
tree7fd0ae1364812384858a7dfbf665c542b2d3ca0e
parentac1d6cbbcf5323d5db59886b98a24c45bafa64b8 (diff)
downloadeclat-4aef6e9feff509e8cb267473d505e82dd794df78.tar.gz
eclat-4aef6e9feff509e8cb267473d505e82dd794df78.tar.bz2
Add user-defined formats.
* etc/Makefile.am: Minor fixes. * src/cmdline.opt: New option --format. Add alias --formfile to --format-file * src/config.c: New configuration statement "define-format". * src/eclat.c (define_format): Rename to set_command_format. All uses changed. (define_format,find_format): New functions (read_format): Compile named format, if supplied with the --format option. * src/eclat.h: Update.
-rw-r--r--etc/Makefile.am16
-rw-r--r--src/cmdline.opt9
-rw-r--r--src/config.c35
-rw-r--r--src/eclat.c63
-rw-r--r--src/eclat.h4
5 files changed, 111 insertions, 16 deletions
diff --git a/etc/Makefile.am b/etc/Makefile.am
index 5eec565..56510a3 100644
--- a/etc/Makefile.am
+++ b/etc/Makefile.am
@@ -25,8 +25,6 @@ FLNFILES=\
EXTRA_DIST=$(FLNFILES) default.fln eclat.cfin
-noinst_SCRIPTS=eclat.conf
-CLEANFILES=eclat.conf
SUFFIXES=.cfin .conf
if SPLIT_FORMATS
@@ -34,27 +32,29 @@ SUFFIXES += .forlan .fln
.fln.forlan:
$(AM_V_GEN)$(abs_builddir)/flncat $< default.fln > $@
formatdir = @FORMATDIR@
-noinst_SCRIPTS += $(FLNFILES:.fln=.forlan)
-CLEANFILES += $(FLNFILES:.fln=.forlan)
+FORMATFILES = $(FLNFILES:.fln=.forlan)
FORMATNAME = $${command}
else
formatdir = @FORMATDIR@
-noinst_SCRIPTS += eclat.forlan
-CLEANFILES += eclat.forlan
+FORMATFILES = eclat.forlan
eclat.forlan: $(FLNFILES) default.fln
$(AM_V_GEN)(cd $(srcdir); $(abs_builddir)/flncat $(FLNFILES) default.fln) > eclat.forlan
FORMATNAME = eclat
endif
+noinst_SCRIPTS=eclat.conf $(FORMATFILES)
+CLEANFILES=eclat.conf $(FORMATFILES)
+
.cfin.conf:
$(AM_V_GEN)sed 's^FORMATDIR^$(formatdir)^;s^FORMATNAME^$(FORMATNAME)^' $< > $@
install-data-local:
@test -z "$(DESTDIR)$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)"
@if [ -r $(DESTDIR)$(sysconfdir)/eclat.conf ]; then :; \
- else ${INSTALL} -m 644 $(top_srcdir)/src/eclat.conf \
+ else ${INSTALL} -m 644 $(top_srcdir)/etc/eclat.conf \
$(DESTDIR)$(sysconfdir)/eclat.conf; \
- for file in $(noinst_SCRIPTS); do \
+ ${INSTALL} -d $(DESTDIR)$(formatdir); \
+ for file in $(FORMATFILES); do \
${INSTALL} -m 644 $$file $(DESTDIR)$(formatdir)/$$file; \
done; \
fi
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 3f0549f..357f7ef 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -109,8 +109,15 @@ BEGIN
use_ssl = 1;
END
-OPTION(format,F,FILE,
+OPTION(format,H,NAME,
+ [<use format NAME for output>])
+BEGIN
+ format_name_option = optarg;
+END
+
+OPTION(format-file,F,FILE,
[<use FILE to format the output>])
+ALIAS(formfile)
BEGIN
format_file_option = optarg;
END
diff --git a/src/config.c b/src/config.c
index aa60323..69835b9 100644
--- a/src/config.c
+++ b/src/config.c
@@ -103,9 +103,6 @@ cb_format(enum grecs_callback_command cmd,
grecs_value_t *value,
void *cb_data)
{
- struct ec2_param *p, key;
- int install = 1;
-
if (cmd != grecs_callback_set_value) {
grecs_error(locus, 0, "Unexpected block statement");
return 1;
@@ -119,9 +116,36 @@ cb_format(enum grecs_callback_command cmd,
grecs_error(locus, 0, "expected two strings");
return 1;
}
+ set_command_format(value->v.arg.v[0]->v.string,
+ value->v.arg.v[1]->v.string,
+ &value->v.arg.v[1]->locus);
+}
+
+static int
+cb_define_format(enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data)
+{
+ if (cmd != grecs_callback_set_value) {
+ grecs_error(locus, 0, "Unexpected block statement");
+ return 1;
+ }
+ if (!value || value->type != GRECS_TYPE_ARRAY || value->v.arg.c != 2) {
+ grecs_error(locus, 0, "expected two strings");
+ return 1;
+ }
+ if (value->v.arg.v[0]->type != GRECS_TYPE_STRING ||
+ value->v.arg.v[1]->type != GRECS_TYPE_STRING) {
+ grecs_error(locus, 0, "expected two strings");
+ return 1;
+ }
+
define_format(value->v.arg.v[0]->v.string,
value->v.arg.v[1]->v.string,
&value->v.arg.v[1]->locus);
+ return 0;
}
static struct grecs_keyword eclat_kw[] = {
@@ -138,8 +162,11 @@ static struct grecs_keyword eclat_kw[] = {
"Define default AWS region",
grecs_type_string, GRECS_DFLT, &region_name },
{ "format", "<command: string> <format: string>",
- "Set default format for the <command>",
+ "Set default format for <command>",
grecs_type_string, GRECS_MULT, NULL, 0, cb_format },
+ { "define-format", "<name: string> <format: string>",
+ "Define a named format",
+ grecs_type_string, GRECS_MULT, NULL, 0, cb_define_format },
{ "format-file", "file", "Read format from <file>",
grecs_type_string, GRECS_DFLT, &format_file },
{ NULL }
diff --git a/src/eclat.c b/src/eclat.c
index 31f2144..f213b7b 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -27,6 +27,7 @@ char *access_key;
char *secret_key;
char *region_name;
char *format_file_option;
+char *format_name_option;
int sort_option;
char *format_file;
@@ -290,7 +291,7 @@ find_command_tag(const char *tag)
}
void
-define_format(const char *name, const char *format, grecs_locus_t *locus)
+set_command_format(const char *name, const char *format, grecs_locus_t *locus)
{
struct command *cp = find_command_tag(name);
@@ -383,13 +384,69 @@ list_filters(FILE *fp)
}
fputc('\n', fp);
}
+
+struct format_defn {
+ const char *name;
+ char *text;
+ grecs_locus_t locus;
+};
+
+static struct grecs_symtab *format_table;
+
+void
+define_format(const char *name, const char *fmt, grecs_locus_t *loc)
+{
+ struct format_defn key;
+ struct format_defn *ent;
+ int install = 1;
+
+ if (!format_table) {
+ format_table = grecs_symtab_create_default(
+ sizeof(struct format_defn));
+ if (!format_table)
+ grecs_alloc_die();
+ }
+
+ key.name = (char*) name;
+ ent = grecs_symtab_lookup_or_install(format_table, &key, &install);
+ if (!ent)
+ grecs_alloc_die();
+ if (!install) {
+ grecs_error(loc, 0, "redefinition of format \"%s\"", name);
+ grecs_error(&ent->locus, 0,
+ "this is the place of the original definition");
+ free(ent->text);
+ }
+ ent->text = grecs_strdup(fmt);
+ ent->locus = *loc;
+}
+forlan_eval_env_t
+find_format(const char *name)
+{
+ struct format_defn key;
+ struct format_defn *defn;
+ forlan_eval_env_t env;
+
+ if (!format_table)
+ return NULL;
+ key.name = (char*) name;
+ defn = grecs_symtab_lookup_or_install(format_table, &key, NULL);
+ if (!defn)
+ return NULL;
+ env = forlan_parse_buffer(defn->text, strlen(defn->text),
+ &defn->locus.beg);
+ return env;
+}
+
static forlan_eval_env_t
read_format(struct command *cmd)
{
forlan_eval_env_t env = NULL;
-
- if (format_file_option)
+
+ if (format_name_option)
+ env = find_format(format_name_option);
+ else if (format_file_option)
env = compile_format_file(format_file_option);
else if (cmd && cmd->fmt)
env = forlan_parse_buffer(cmd->fmt, strlen(cmd->fmt),
diff --git a/src/eclat.h b/src/eclat.h
index 242861b..340edf0 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -89,3 +89,7 @@ int get_scr_cols(void);
int get_access_creds(const char *id, char **access_key_ptr,
char **secret_key_ptr);
+
+void define_format(const char *name, const char *fmt, grecs_locus_t *loc);
+forlan_eval_env_t find_format(const char *name);
+

Return to:

Send suggestions and report system problems to the System administrator.