string_format.c (1257B)
1 /* ISC license. */ 2 3 #include <string.h> 4 #include <errno.h> 5 #include <skalibs/bytestr.h> 6 #include <skalibs/stralloc.h> 7 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 }