From 295d7fde311f02172a73d24e510c433d5ac5aa39 Mon Sep 17 00:00:00 2001 From: "Sunrim KIM (keen)" <3han5chou7@gmail.com> Date: Thu, 17 Jul 2014 21:48:19 +0900 Subject: [PATCH 1/5] allow pipe syntax --- src/read.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/read.c b/src/read.c index f8836e44..734973d8 100644 --- a/src/read.c +++ b/src/read.c @@ -4,6 +4,7 @@ #include #include +#include #include "picrin.h" #include "picrin/error.h" #include "picrin/pair.h" @@ -354,6 +355,47 @@ read_string(pic_state *pic, struct pic_port *port, char c) return pic_obj_value(str); } +static pic_value +read_pipe(pic_state *pic, struct pic_port *port, char c) +{ + char *buf; + size_t size, cnt; + pic_sym sym; + + size = 256; + buf = pic_alloc(pic, size); + cnt = 0; + while ((c = next(port)) != '|') { + if (c == '\\') { + switch (c = next(port)) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 't': c = '\t'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 'x':{ + char hex[2]; /* Currently supports only ascii chars */ + size_t i = 0; + while((c = (next(port))) != ';' && i < 6) + hex[i++] = c; + c = (char)strtol(hex, NULL, 16); + break; + } + } + } + buf[cnt++] = c; + if (cnt >= size) { + buf = pic_realloc(pic, buf, size *= 2); + } + } + buf[cnt] = '\0'; + + sym = pic_intern_cstr(pic, buf); + pic_free(pic, buf); + + return pic_sym_value(sym); +} + static pic_value read_unsigned_blob(pic_state *pic, struct pic_port *port, char c) { @@ -584,6 +626,8 @@ read_nullable(pic_state *pic, struct pic_port *port, char c) return read_comma(pic, port, c); case '"': return read_string(pic, port, c); + case '|': + return read_pipe(pic, port, c); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return read_number(pic, port, c); From b373ec433b579c2e9cd250801999493239c412c1 Mon Sep 17 00:00:00 2001 From: "Sunrim KIM (keen)" <3han5chou7@gmail.com> Date: Thu, 17 Jul 2014 22:23:06 +0900 Subject: [PATCH 2/5] ensure to correctly terminate hex string with non-hex char(';') --- src/read.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/read.c b/src/read.c index 734973d8..7b059a30 100644 --- a/src/read.c +++ b/src/read.c @@ -374,10 +374,11 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 'x':{ - char hex[2]; /* Currently supports only ascii chars */ + /* Currently supports only ascii chars */ + size_t s = 3; /* 2 bytes of hex + 1 byte of terminator(';')*/ + char hex[s]; size_t i = 0; - while((c = (next(port))) != ';' && i < 6) - hex[i++] = c; + while((hex[i++] = (next(port))) != ';' && i < s); c = (char)strtol(hex, NULL, 16); break; } From 2c1209ba63b377c83c9478e41557a904c2d50b83 Mon Sep 17 00:00:00 2001 From: "Sunrim KIM (keen)" <3han5chou7@gmail.com> Date: Fri, 18 Jul 2014 15:44:29 +0900 Subject: [PATCH 3/5] remove redundant brace following review --- src/read.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/read.c b/src/read.c index 7b059a30..142db83c 100644 --- a/src/read.c +++ b/src/read.c @@ -361,6 +361,8 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) char *buf; size_t size, cnt; pic_sym sym; + /* Currently supports only ascii chars */ + char HEX_BUF[3]; size = 256; buf = pic_alloc(pic, size); @@ -373,16 +375,11 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) case 't': c = '\t'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; - case 'x':{ - /* Currently supports only ascii chars */ - size_t s = 3; /* 2 bytes of hex + 1 byte of terminator(';')*/ - char hex[s]; - size_t i = 0; - while((hex[i++] = (next(port))) != ';' && i < s); - c = (char)strtol(hex, NULL, 16); + case 'x': + for(size_t i = 0; (HEX_BUF[i++] = (next(port))) != ';' && i < sizeof HEX_BUF;); + c = (char)strtol(HEX_BUF, NULL, 16); break; } - } } buf[cnt++] = c; if (cnt >= size) { From c440629dbf6fe3532f4b1d696f82e9d151a5aecf Mon Sep 17 00:00:00 2001 From: "Sunrim KIM (keen)" <3han5chou7@gmail.com> Date: Fri, 18 Jul 2014 15:47:36 +0900 Subject: [PATCH 4/5] add error check --- src/read.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/read.c b/src/read.c index 142db83c..239c20e9 100644 --- a/src/read.c +++ b/src/read.c @@ -376,7 +376,10 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 'x': - for(size_t i = 0; (HEX_BUF[i++] = (next(port))) != ';' && i < sizeof HEX_BUF;); + for(size_t i = 0; (HEX_BUF[i] = next(port)) != ';'; i++) { + if (i >= sizeof HEX_BUF) + read_error(pic, "expected ';'"); + } c = (char)strtol(HEX_BUF, NULL, 16); break; } From a50d3da569cae27bfe4671752ca0b150b47d0556 Mon Sep 17 00:00:00 2001 From: "Sunrim KIM (keen)" <3han5chou7@gmail.com> Date: Fri, 18 Jul 2014 16:02:09 +0900 Subject: [PATCH 5/5] follow completely @wasabiz's code --- src/read.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/read.c b/src/read.c index 239c20e9..dfcc63d4 100644 --- a/src/read.c +++ b/src/read.c @@ -363,6 +363,7 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) pic_sym sym; /* Currently supports only ascii chars */ char HEX_BUF[3]; + size_t i = 0; size = 256; buf = pic_alloc(pic, size); @@ -376,7 +377,8 @@ read_pipe(pic_state *pic, struct pic_port *port, char c) case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 'x': - for(size_t i = 0; (HEX_BUF[i] = next(port)) != ';'; i++) { + i = 0; + while ((HEX_BUF[i++] = next(port)) != ';') { if (i >= sizeof HEX_BUF) read_error(pic, "expected ';'"); }