Skip to content

Instantly share code, notes, and snippets.

@bitsmanent
Last active October 15, 2018 17:56
Show Gist options
  • Save bitsmanent/ca74007381518fd85abcf1254d7a79d0 to your computer and use it in GitHub Desktop.
Save bitsmanent/ca74007381518fd85abcf1254d7a79d0 to your computer and use it in GitHub Desktop.
Parse a printf-like format string
#include <wchar.h>
typedef struct {
wchar_t cs;
wchar_t flags[8];
wchar_t mod[3];
int w;
int len;
} Printf;
int
wparsef(Printf *pf, wchar_t *fmt) {
wchar_t *p = fmt, num[32];
int i;
if(*p != '%' || *++p == '%')
return -1;
pf->w = pf->len = 0;
/* flags */
i = 0;
while(*p == '#' || *p == '0' || *p == '-' || *p == ' '
|| *p == '+' || *p == '\'' || *p == 'I') {
pf->flags[i++] = *p;
++p;
}
pf->flags[i] = '\0';
/* padding */
if(*p == '*') {
pf->w = -1;
++p;
}
else if(*p >= '0' && *p <= '9') {
i = 0;
while(*p >= '0' && *p <= '9')
num[i++] = *p++;
num[i] = '\0';
pf->w = wcstol(num, NULL, 10);
}
/* truncation */
if(*p == '.' && *++p) {
if(*p == '*') {
pf->len = -1;
++p;
}
else if(*p >= '0' && *p <= '9') {
i = 0;
while(*p >= '0' && *p <= '9')
num[i++] = *p++;
num[i] = '\0';
pf->len = wcstol(num, NULL, 10);
}
}
/* modifier */
i = 0;
if(*p == 'h' || *p == 'l' || *p == 'q' || *p == 'L'
|| *p == 'j' || *p == 'z' || *p == 'Z' || *p == 't') {
pf->mod[i++] = *p++;
if((*p == 'l' || *p == 'h') && *(p+1) == *p)
pf->mod[i++] = *p++;
}
pf->mod[i] = '\0';
pf->cs = *p;
return p - fmt;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment