1 /* ISC license. */
2 
3 #include <string.h>
4 #include <errno.h>
5 #include <skalibs/bytestr.h>
6 #include <skalibs/stralloc.h>
7 
string_format(stralloc * sa,char const * vars,char const * format,char const * const * args)8 int string_format (stralloc *sa, char const *vars, char const *format, char const *const *args)
9 {
10   static unsigned char const tab[2][4] = { "1442", "4833" } ;
11   char class[256] = "3222222222222222222222222222222222222022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" ;
12   size_t varlen = strlen(vars) ;
13   size_t base = sa->len ;
14   size_t state = 0 ;
15   int wasnull = !sa->s ;
16 
17   for (; state < varlen ; state++)
18     if (class[(unsigned char)vars[state]] == '2')
19       class[(unsigned char)vars[state]] = '1' ;
20     else return (errno = EINVAL, 0) ;
21 
22   for (state = 0 ; state < 2 ; format++)
23   {
24     unsigned char c = tab[state][class[(unsigned char)(*format)] - '0'] ;
25     state = c & 3 ;
26     if (c & 4) if (!stralloc_catb(sa, format, 1)) goto err ;
27     if (c & 8) if (!stralloc_cats(sa, args[byte_chr(vars, varlen, *format)])) goto err ;
28   }
29   if (state == 2) return 1 ;
30   errno = EINVAL ;
31  err:
32   if (wasnull) stralloc_free(sa) ; else sa->len = base ;
33   return 0 ;
34 }
35