From 689735eed88a4ccba136567131c9692b80463748 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 11 Mar 2020 07:13:02 +0000 Subject: [PATCH] added @pragma multilinestr on/off --- hawk/README.md | 18 ++++++++++-- hawk/bin/main.c | 2 ++ hawk/lib/hawk.c | 2 +- hawk/lib/hawk.h | 5 +++- hawk/lib/parse.c | 72 ++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 85 insertions(+), 14 deletions(-) diff --git a/hawk/README.md b/hawk/README.md index b5ad047b..d30af734 100644 --- a/hawk/README.md +++ b/hawk/README.md @@ -133,7 +133,7 @@ The typical execution begins with the BEGIN block, goes through pattern-action b } -### Value +### Values - unitialized value - integer @@ -142,10 +142,22 @@ The typical execution begins with the BEGIN block, goes through pattern-action b - byte string - array +### Pragmas + +A program item of the file scope can be placed in any source files. +A pragma item of the global scope can appear only once thoughout the all source files. + +| | Scope | Values | Description | +|---------------|--------|---------------|--------------------------------------------------------| +| implicit | file | on, off | allow undeclared variables | +| multilinestr | file | on, off | allow a multiline string literal without continuation | +| entry | global | function name | change the program entry point | +| striprecspc | global | on, off | | +| striprecspc | global | on, off | trim leading and trailing spaces when convering a string to a number | + + ### Module - - ### Incompatibility with AWK #### Parameter passing diff --git a/hawk/bin/main.c b/hawk/bin/main.c index 6457e48b..1812936e 100644 --- a/hawk/bin/main.c +++ b/hawk/bin/main.c @@ -499,6 +499,7 @@ struct opttab_t } opttab[] = { { "implicit", HAWK_IMPLICIT, "allow undeclared variables" }, + { "multilinestr", HAWK_MULTILINESTR, "allow raw multiline string and regular expression literals" }, { "nextofile", HAWK_NEXTOFILE, "enable nextofile & OFILENAME" }, { "rio", HAWK_RIO, "enable builtin I/O including getline & print" }, { "rwpipe", HAWK_RWPIPE, "allow a dual-directional pipe" }, @@ -640,6 +641,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) static hawk_bcli_lng_t lng[] = { { ":implicit", '\0' }, + { ":multilinestr", '\0' }, { ":nextofile", '\0' }, { ":rio", '\0' }, { ":rwpipe", '\0' }, diff --git a/hawk/lib/hawk.c b/hawk/lib/hawk.c index e55da6f6..ec955479 100644 --- a/hawk/lib/hawk.c +++ b/hawk/lib/hawk.c @@ -379,7 +379,7 @@ void hawk_clear (hawk_t* awk) awk->parse.depth.loop = 0; awk->parse.depth.expr = 0; awk->parse.depth.incl = 0; - awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in awk->opt.trait with hawk_setopt */ + awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in awk->opt.trait with hawk_setopt */ awk->parse.pragma.rtx_stack_limit = 0; awk->parse.pragma.entry[0] = '\0'; diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 0d009987..d2f294ca 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -1151,8 +1151,11 @@ enum hawk_trait_t /** allows undeclared variables */ HAWK_IMPLICIT = (1 << 0), + /** allows multiline string literals or regular expression literals */ + HAWK_MULTILINESTR = (1 << 1), + /** enables nextofile and NEXTOFILE */ - HAWK_NEXTOFILE = (1 << 1), + HAWK_NEXTOFILE = (1 << 2), /** supports \b getline, \b print, \b printf, \b close, \b fflush, * piping, and file rediction */ diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index 8d6aa203..62791806 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -872,7 +872,7 @@ static int begin_include (hawk_t* awk, int once) arg->pragma_trait = awk->parse.pragma.trait; /* but don't change awk->parse.pragma.trait. it means the included file inherits * the existing progma values. - awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); + awk->parse.pragma.trait = (awk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); */ /* i update the current pointer after opening is successful */ @@ -1039,6 +1039,35 @@ static int parse_progunit (hawk_t* awk) goto error_ident_on_off_expected_for_implicit; } } + else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("multilinestr")) == 0) + { + if (get_token(awk) <= -1) return -1; + if (!MATCH(awk, TOK_IDENT)) + { + error_ident_on_off_expected_for_multilinestr: + hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("identifier 'on' or 'off' expected for 'multilinestr'")); + return -1; + } + + name.len = HAWK_OOECS_LEN(awk->tok.name); + name.ptr = HAWK_OOECS_PTR(awk->tok.name); + if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("on")) == 0) + { + awk->parse.pragma.trait |= HAWK_MULTILINESTR; + } + else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("off")) == 0) + { + awk->parse.pragma.trait &= ~HAWK_MULTILINESTR; + } + else + { + goto error_ident_on_off_expected_for_multilinestr; + } + } + /* --------------------------------------------------------------------- + * the pragmas up to this point affect the parser + * the following pragmas affect runtime + * --------------------------------------------------------------------- */ else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("stack_limit")) == 0) { hawk_int_t sl; @@ -6131,22 +6160,47 @@ static int get_string ( } } - if (escaped == 0 && c == end_char) + if (escaped == 99) { - /* terminating quote */ - /*GET_CHAR_TO (awk, c);*/ - GET_CHAR (awk); - break; + escaped = 0; + if (c == '\n') continue; /* backslash \r \n */ } - if (escaped == 0 && c == esc_char) + if (escaped == 0) { - escaped = 1; - continue; + if (c == end_char) + { + /* terminating quote */ + /*GET_CHAR_TO (awk, c);*/ + GET_CHAR (awk); + break; + } + else if (c == esc_char) + { + escaped = 1; + continue; + } + else if (!(awk->parse.pragma.trait & HAWK_MULTILINESTR) && c == '\n' || c == '\r') + { + hawk_seterrnum (awk, &awk->tok.loc, HAWK_ESTRNC); + return -1; + } } if (escaped == 1) { + if (c == '\n') + { + /* line continuation - a backslash at the end of line */ + escaped = 0; + continue; + } + else if (c == '\r') + { + escaped = 99; + continue; + } + if (c == HAWK_T('n')) c = HAWK_T('\n'); else if (c == HAWK_T('r')) c = HAWK_T('\r'); else if (c == HAWK_T('t')) c = HAWK_T('\t');