Mercurial > projects > pwm
diff pwm.c @ 27:722a45b4028b
Add define command for defining macros
Macros are parsed when they are defined with the D command and can
subsequently be used as arguments for other commands.
Handle out of memory errors directly in tok.c.
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Mon, 25 Sep 2017 21:21:25 +0200 |
parents | 1b89066d992c |
children | e3db02d7f1f4 |
line wrap: on
line diff
--- a/pwm.c Thu Sep 21 09:45:59 2017 +0200 +++ b/pwm.c Mon Sep 25 21:21:25 2017 +0200 @@ -42,6 +42,7 @@ #include "pwm.h" #include "cmd.h" #include "io.h" +#include "macro.h" #include "pwfile.h" #include "tok.h" #include "util.h" @@ -108,6 +109,8 @@ GetLine *gl = NULL; char buf[PWM_LINE_MAX + 1]; int io_retval; + size_t tokenc = 0; + union tok **tokenv = NULL; int argc = 0; char **argv = NULL; struct cmd *cmd; @@ -159,9 +162,7 @@ } /* tokenize line */ - switch (tok_tokenize(buf, &argc, &argv)) { - case TOK_ERR_SYSTEM_ERROR: - err(1, "tok_tokenize"); + switch (tok_tokenize(buf, &tokenc, &tokenv)) { case TOK_ERR_UNTERMINATED_QUOTE: fprintf(stderr, "unterminated quote\n"); if (!ctx->is_interactive) { @@ -174,6 +175,22 @@ goto out; } goto next; + case TOK_ERR_INVALID_MACRO_NAME: + fprintf(stderr, "invalid macro name\n"); + if (!ctx->is_interactive) { + goto out; + } + goto next; + } + + /* expand macros */ + if (macro_expand_macros(ctx->macro_head, tokenc, tokenv, &argc, + &argv) != 0) { + fprintf(stderr, "undefined macro\n"); + if (!ctx->is_interactive) { + goto out; + } + goto next; } if (argc == 0) { @@ -216,6 +233,9 @@ free(argv); argc = 0; argv = NULL; + tok_free(tokenv); + tokenc = 0; + tokenv = NULL; } quit: @@ -226,6 +246,7 @@ free(argv[i]); } free(argv); + tok_free(tokenv); del_GetLine(gl); return (retval); @@ -397,6 +418,7 @@ } pwfile_init(&ctx); + macro_init(&ctx.macro_head); fp = fopen(ctx.filename, "r"); if ((fp == NULL) && (errno != ENOENT)) { @@ -424,6 +446,7 @@ status = (run_input_loop(&ctx) != 0); out: + macro_destroy(ctx.macro_head); pwfile_destroy(&ctx); if (fp != NULL) { fclose(fp);