diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-28 14:15:44 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-28 14:15:44 +0300 |
commit | 4aef6e9feff509e8cb267473d505e82dd794df78 (patch) | |
tree | 7fd0ae1364812384858a7dfbf665c542b2d3ca0e | |
parent | ac1d6cbbcf5323d5db59886b98a24c45bafa64b8 (diff) | |
download | eclat-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.am | 16 | ||||
-rw-r--r-- | src/cmdline.opt | 9 | ||||
-rw-r--r-- | src/config.c | 35 | ||||
-rw-r--r-- | src/eclat.c | 63 | ||||
-rw-r--r-- | src/eclat.h | 4 |
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, ®ion_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); + |