1 /* ISC license. */
2 
3 #include <sys/types.h>
4 #include <stdint.h>
5 #include <skalibs/types.h>
6 #include <skalibs/bytestr.h>
7 #include <skalibs/stralloc.h>
8 #include <skalibs/djbunix.h>
9 #include <execline/execline.h>
10 
el_parse(stralloc * sa,el_chargen_func_t_ref next,void * source)11 int el_parse (stralloc *sa, el_chargen_func_t_ref next, void *source)
12 {
13   static unsigned char const class[256] = "`aaaaaaaaadaaaaaaaaaaaaaaaaaaaaaafcbffffffffffffjhhhhhhhiifffffffmmmmmmfffffffffffffffffffffeffffggmmmgfffffffkfffkfkfkflffnfoffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ;
14   static uint16_t const table[16][16] =
15   {
16     { 0x0011, 0x4011, 0x0010, 0x0010, 0x0010, 0x0011, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x4091 },
17     { 0x0000, 0x4000, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x0100, 0x4080 },
18     { 0x0005, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 },
19     { 0x0203, 0x0003, 0x8001, 0x0001, 0x8003, 0x0005, 0x0010, 0x0401, 0x0401, 0x0401, 0x0401, 0x0010, 0x0401, 0x0401, 0x0003, 0x0003 },
20     { 0x0000, 0x4000, 0x8001, 0x8003, 0x0003, 0x0000, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x0100, 0x4080 },
21     { 0x0202, 0x0002, 0x8001, 0x0004, 0x8003, 0x0005, 0x0010, 0x0404, 0x0404, 0x0404, 0x0404, 0x0010, 0x0404, 0x0404, 0x0002, 0x0002 },
22     { 0x8201, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 },
23     { 0x8201, 0x8001, 0x8001, 0x8003, 0x2003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x880c, 0x800d, 0x8403, 0x8001, 0x8001 },
24     { 0x8201, 0x8001, 0x8001, 0x8003, 0x9809, 0x0005, 0x8807, 0x8008, 0x800d, 0x800a, 0x800d, 0x880c, 0x800d, 0x8403, 0x8001, 0x8001 },
25     { 0x8201, 0x8001, 0x8001, 0x8003, 0x9809, 0x0005, 0x0010, 0x8403, 0x8403, 0x800a, 0x800d, 0x880c, 0x800d, 0x8403, 0x8001, 0x8001 },
26     { 0x8201, 0x8001, 0x8001, 0x8003, 0x1006, 0x0005, 0x8807, 0x8008, 0x800d, 0x800a, 0x800d, 0x880c, 0x800d, 0x8403, 0x8001, 0x8001 },
27     { 0x8201, 0x8001, 0x8001, 0x8003, 0x2003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 },
28     { 0x8201, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x100b, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 },
29     { 0x8201, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x880c, 0x800d, 0x8403, 0x8001, 0x8001 },
30     { 0x820e, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 },
31     { 0x820f, 0x8001, 0x8001, 0x8003, 0x8003, 0x0005, 0x0010, 0x8403, 0x8403, 0x8403, 0x8403, 0x0010, 0x8403, 0x8403, 0x8001, 0x8001 }
32   } ;
33 
34   size_t mark = 0 ;
35   int n = 0 ;
36   unsigned int blevel = 0 ;
37   unsigned char state = 0, base = 10 ;
38 
39   while (state < 0x10)
40   {
41     uint16_t c ;
42     unsigned char cur ;
43     if (!(*next)(&cur, source)) return -1 ;
44     c = table[class[cur]-'`'][state] ;
45     state = c & 0x1F ;
46 
47     if (c & 0x0400)
48     {
49       unsigned int z ;
50       if (!stralloc_0(sa)) return -1 ;
51       sa->len = mark ;
52       uint_scan_base(sa->s + sa->len, &z, base) ;
53       sa->s[sa->len++] = (unsigned char)z ;
54     }
55     if (c & 0x0800) mark = sa->len ;
56     if (c & 0x0200)
57     {
58       char tilde = EXECLINE_BLOCK_QUOTE_CHAR ;
59       unsigned int i = blevel ;
60       if (!stralloc_readyplus(sa, i<<1)) return -1 ;
61       while (i--) stralloc_catb(sa, &tilde, 1) ;
62     }
63     if (c & 0x0100) sa->len -= ++blevel ;
64     if (c & 0x0080)
65     {
66       if (!blevel--) return -4 ;
67       sa->s[--sa->len-1] = EXECLINE_BLOCK_END_CHAR ;
68       if (!EXECLINE_BLOCK_END_CHAR) sa->len-- ;
69     }
70     if (c & 0x8000) if (!stralloc_catb(sa, (char *)&cur, 1)) return -1 ;
71     if (c & 0x2000)
72     {
73       char x = 7 + byte_chr("abtnvfr", 7, cur) ;
74       if (!stralloc_catb(sa, &x, 1)) return -1 ;
75     }
76     if (c & 0x4000) if (n++, !stralloc_0(sa)) return -1 ;
77     if (c & 0x1000)
78       switch (cur)
79       {
80         case 'x' : base = 16 ; break ;
81         case '0' : base = 8 ; break ;
82         default : base = 10 ;
83       }
84   }
85   if (state == 0x10) return -2 ;
86   if (blevel) return -3 ;
87   return n ;
88 }
89