aboutsummaryrefslogtreecommitdiff
path: root/lib/forlan.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-10-01 16:43:18 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-10-01 16:58:20 +0300
commitddb280198adcada561b8e72c79b92d50a05b3e78 (patch)
treede6f2d47fe10d0fb37279893d17ffcbd30b156ce /lib/forlan.c
parent78b25d9756403fef919684738f7aecb2cdcee465 (diff)
downloadeclat-ddb280198adcada561b8e72c79b92d50a05b3e78.tar.gz
eclat-ddb280198adcada561b8e72c79b92d50a05b3e78.tar.bz2
Implement exit; add some docs.
* Makefile.am (SUBDIRS): Add doc. * configure.ac: Build doc/Makefile * doc/Makefile.am: New file. * doc/eclat-associate-address.1: New file. * doc/eclat.1: New file. * etc/associate-address.fln: Call exit if the request fails. * etc/default.fln: Call exit if error is returned or if the response is not recognized. * lib/forlan.c (forlan_eval_env) <exit_code>: New member. New built-in function: exit. (forlan_run): Return exit code. * lib/forlan.h (forlan_run): Change return type. * lib/forlanlex.l: Treat unquoted decimal number as a quoted string. * src/asscaddr-cl.opt: Minor changes. * src/cmdline.opt: Minor changes. * src/eclat.c: Return EX_NOPERM on unsufficient permissions to open the configuration file. * tests/exit.at: New file. * tests/Makefile.am: Add new files. * tests/testsuite.at: Include new test cases. * tests/tforlan.c: Propagate the return from forlan_run to the shell.
Diffstat (limited to 'lib/forlan.c')
-rw-r--r--lib/forlan.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/lib/forlan.c b/lib/forlan.c
index f12e00b..74b03a3 100644
--- a/lib/forlan.c
+++ b/lib/forlan.c
@@ -28,6 +28,7 @@ struct forlan_eval_env {
struct grecs_node *top_node;
struct forlan_value retval;
union forlan_node *instr;
+ int exit_code;
jmp_buf stop_buf;
jmp_buf loop_buf;
};
@@ -800,7 +801,7 @@ node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b)
}
/* FIXME */
-void
+static void
func_sort(forlan_eval_env_t env, struct grecs_list *list)
{
struct forlan_value *val = list->head->data;
@@ -808,7 +809,7 @@ func_sort(forlan_eval_env_t env, struct grecs_list *list)
grecs_tree_sort(val->v.node, node_ident_cmp);
}
-void
+static void
func_decode(forlan_eval_env_t env, struct grecs_list *list)
{
struct forlan_value *val = list->head->data;
@@ -835,6 +836,23 @@ func_decode(forlan_eval_env_t env, struct grecs_list *list)
grecs_txtacc_free(acc);
}
+static void
+func_exit(forlan_eval_env_t env, struct grecs_list *list)
+{
+ struct forlan_value *val = list->head->data;
+ unsigned long code;
+ char *p;
+
+ code = strtoul(val->v.string, &p, 10);
+ if (*p || code > 255) {
+ err("invalid exit code \"%s\", assuming 255",
+ val->v.string);
+ code = 255;
+ }
+ env->exit_code = code;
+ longjmp(env->stop_buf, 1);
+}
+
static struct forlan_function functab[] = {
{ "dump", forlan_value_void, "n", 1, 1, func_dump },
{ "print", forlan_value_void, "", 1, -1, func_print },
@@ -842,6 +860,7 @@ static struct forlan_function functab[] = {
{ "parent", forlan_value_node, "n", 1, 1, func_parent },
{ "sort", forlan_value_void, "n", 1, 1, func_sort },
{ "decode", forlan_value_literal, "s", 1, 1, func_decode },
+ { "exit", forlan_value_void, "s", 1, 1, func_exit },
{ NULL }
};
@@ -864,7 +883,7 @@ forlan_eval(struct forlan_eval_env *env, union forlan_node *p)
f_tab[p->type].f_eval(env, p);
}
-void
+int
forlan_run(forlan_eval_env_t env, struct grecs_node *tree)
{
env->last = NULL;
@@ -875,6 +894,7 @@ forlan_run(forlan_eval_env_t env, struct grecs_node *tree)
if (setjmp(env->stop_buf) == 0)
forlan_eval(env, env->parse_tree);
free_value(&env->retval);
+ return env->exit_code;
}
forlan_eval_env_t

Return to:

Send suggestions and report system problems to the System administrator.