diff options
Diffstat (limited to 'src/execline/envfile.c')
-rw-r--r-- | src/execline/envfile.c | 94 |
1 files changed, 76 insertions, 18 deletions
diff --git a/src/execline/envfile.c b/src/execline/envfile.c index 638b182..18a175b 100644 --- a/src/execline/envfile.c +++ b/src/execline/envfile.c @@ -3,9 +3,11 @@ #include <stdint.h> #include <string.h> +#include <skalibs/bytestr.h> #include <skalibs/types.h> #include <skalibs/buffer.h> #include <skalibs/strerr2.h> +#include <skalibs/fmtscan.h> #include <skalibs/env.h> #include <skalibs/stralloc.h> #include <skalibs/djbunix.h> @@ -14,6 +16,15 @@ #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") +static void scanoct (stralloc *sa, size_t pos) +{ + unsigned int u ; + if (!stralloc_0(sa)) dienomem() ; + uint_oscan(sa->s + pos, &u) ; + sa->s[pos] = u ; + sa->len = pos+1 ; +} + static inline uint8_t cclass (char c) { switch (c) @@ -26,7 +37,38 @@ static inline uint8_t cclass (char c) case '\t' : case '\f' : case '\r' : return 4 ; - default : return 5 ; + case '\\' : return 5 ; + case '\"' : return 6 ; + case 'a' : + case 'b' : + case 'f' : return 7 ; + case 'n' : + case 'r' : + case 't' : + case 'v' : return 8 ; + case '\'' : + case '?' : return 9 ; + case 'x' : return 10 ; + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : return 11 ; + case '8' : + case '9' : + case 'A' : + case 'B' : + case 'c' : + case 'C' : + case 'd' : + case 'D' : + case 'e' : + case 'E' : + case 'F' : return 12 ; + default : return 13 ; } } @@ -39,32 +81,48 @@ static inline char next (char const *file, buffer *b) return c ; } -static inline void parse_config (char const *file, buffer *b, stralloc *modif) +static inline void parse_config (char const *file, buffer *b, stralloc *sa) { - static uint8_t const table[7][6] = + static uint16_t const table[14][14] = { - { 0x07, 0x01, 0x80, 0x08, 0x00, 0x22 }, - { 0x07, 0x01, 0x80, 0x01, 0x01, 0x01 }, - { 0x08, 0x08, 0x08, 0x24, 0x03, 0x22 }, - { 0x08, 0x08, 0x08, 0x24, 0x03, 0x08 }, - { 0x47, 0x41, 0xc0, 0x25, 0x04, 0x25 }, - { 0x47, 0x41, 0xc0, 0x25, 0x46, 0x25 }, - { 0x07, 0x01, 0x80, 0x08, 0x06, 0x08 } + { 0x000e, 0x0001, 0x0020, 0x000f, 0x0000, 0x000f, 0x000f, 0x0012, 0x0012, 0x000f, 0x0012, 0x0012, 0x0012, 0x0012 }, + { 0x000e, 0x0001, 0x0020, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 }, + { 0x000f, 0x0012, 0x000f, 0x0014, 0x0003, 0x000f, 0x000f, 0x0012, 0x0012, 0x000f, 0x0012, 0x0012, 0x0012, 0x0012 }, + { 0x000f, 0x000f, 0x000f, 0x0014, 0x0003, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f }, + { 0x004e, 0x0015, 0x0060, 0x0015, 0x0004, 0x0008, 0x0007, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015 }, + { 0x004e, 0x0015, 0x0060, 0x0015, 0x0116, 0x0008, 0x0007, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015 }, + { 0x00ce, 0x0015, 0x00d0, 0x0015, 0x0016, 0x0008, 0x0007, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015, 0x0015 }, + { 0x000f, 0x0017, 0x000f, 0x0017, 0x0017, 0x0009, 0x0005, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017, 0x0017 }, + { 0x000f, 0x000f, 0x0025, 0x000f, 0x0015, 0x0015, 0x0015, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f }, + { 0x000f, 0x0017, 0x0027, 0x0017, 0x0017, 0x0017, 0x0017, 0x1017, 0x1017, 0x0017, 0x000a, 0x011c, 0x0017, 0x0017 }, + { 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x001b, 0x000f, 0x000f, 0x000f, 0x001b, 0x001b, 0x000f }, + { 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x0217, 0x000f, 0x000f, 0x000f, 0x0217, 0x0217, 0x000f }, + { 0x000f, 0x0417, 0x000f, 0x0417, 0x0417, 0x0409, 0x0405, 0x0417, 0x0417, 0x0417, 0x0417, 0x001d, 0x0417, 0x0417 }, + { 0x000f, 0x0417, 0x000f, 0x0417, 0x0417, 0x0409, 0x0405, 0x0417, 0x0417, 0x0417, 0x0417, 0x0817, 0x0417, 0x0417 } } ; unsigned int line = 1 ; + size_t mark = 0 ; uint8_t state = 0 ; - while (state < 7) + while (state < 14) { char c = next(file, b) ; - uint8_t what = table[state][cclass(c)] ; + uint16_t what = table[state][cclass(c)] ; state = what & 0x0f ; - if (what & 0x20) - if (!stralloc_catb(modif, &c, 1)) dienomem() ; - if (what & 0x40) - if (!stralloc_0(modif)) dienomem() ; - if (what & 0x80) line++ ; + if (what & 0x0400) scanoct(sa, mark) ; + if (what & 0x0100) mark = sa->len ; + if (what & 0x1000) c = 7 + byte_chr("abtnvfr", 7, c) ; + if (what & 0x0010) if (!stralloc_catb(sa, &c, 1)) dienomem() ; + if (what & 0x0020) line++ ; + if (what & 0x0080) sa->len = mark ; + if (what & 0x0040) if (!stralloc_0(sa)) dienomem() ; + if (what & 0x0200) + { + sa->s[sa->len-2] = (fmtscan_num(sa->s[sa->len-2], 16) << 4) + fmtscan_num(sa->s[sa->len-1], 16) ; + sa->len-- ; + } + if (what & 0x0800) scanoct(sa, mark) ; } - if (state > 7) + if (state > 14) { char fmt[UINT_FMT] ; fmt[uint_fmt(fmt, line)] = 0 ; |