skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

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 }