version 1.2, 2016/05/30 12:05:56 |
version 1.3, 2016/05/30 12:57:21 |
|
|
#include "utf8.h" |
#include "utf8.h" |
|
|
static int dangerous_locale(void); |
static int dangerous_locale(void); |
|
static int grow_dst(char **, size_t *, size_t, char **, size_t); |
static int vasnmprintf(char **, size_t, int *, const char *, va_list); |
static int vasnmprintf(char **, size_t, int *, const char *, va_list); |
|
|
|
|
|
|
return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8"); |
return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8"); |
} |
} |
|
|
|
static int |
|
grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need) |
|
{ |
|
char *tp; |
|
size_t tsz; |
|
|
|
if (*dp + need < *dst + *sz) |
|
return 0; |
|
tsz = *sz + 128; |
|
if (tsz > maxsz) |
|
tsz = maxsz; |
|
if ((tp = realloc(*dst, tsz)) == NULL) |
|
return -1; |
|
*dp = tp + (*dp - *dst); |
|
*dst = tp; |
|
*sz = tsz; |
|
return 0; |
|
} |
|
|
/* |
/* |
* The following two functions limit the number of bytes written, |
* The following two functions limit the number of bytes written, |
* including the terminating '\0', to sz. Unless wp is NULL, |
* including the terminating '\0', to sz. Unless wp is NULL, |
|
|
char *dp; /* Pointer into dst. */ |
char *dp; /* Pointer into dst. */ |
char *tp; /* Temporary pointer for dst. */ |
char *tp; /* Temporary pointer for dst. */ |
size_t sz; /* Number of bytes allocated for dst. */ |
size_t sz; /* Number of bytes allocated for dst. */ |
size_t tsz; /* Temporary size while extending dst. */ |
|
wchar_t wc; /* Wide character at sp. */ |
wchar_t wc; /* Wide character at sp. */ |
int len; /* Number of bytes in the character at sp. */ |
int len; /* Number of bytes in the character at sp. */ |
int ret; /* Number of bytes needed to format src. */ |
int ret; /* Number of bytes needed to format src. */ |
|
|
if ((ret = vasprintf(&src, fmt, ap)) <= 0) |
if ((ret = vasprintf(&src, fmt, ap)) <= 0) |
goto fail; |
goto fail; |
|
|
sz = strlen(src); |
sz = strlen(src) + 1; |
if ((dst = malloc(sz)) == NULL) { |
if ((dst = malloc(sz)) == NULL) { |
free(src); |
free(src); |
goto fail; |
goto fail; |
|
|
total_width > max_width - width)) |
total_width > max_width - width)) |
print = 0; |
print = 0; |
if (print) { |
if (print) { |
|
if (grow_dst(&dst, &sz, maxsz, |
|
&dp, len) == -1) { |
|
ret = -1; |
|
break; |
|
} |
total_width += width; |
total_width += width; |
memcpy(dp, sp, len); |
memcpy(dp, sp, len); |
dp += len; |
dp += len; |
|
|
total_width > max_width - 4)) |
total_width > max_width - 4)) |
print = 0; |
print = 0; |
if (print) { |
if (print) { |
if (dp + 4 >= dst + sz) { |
if (grow_dst(&dst, &sz, maxsz, |
tsz = sz + 128; |
&dp, 4) == -1) { |
if (tsz > maxsz) |
ret = -1; |
tsz = maxsz; |
break; |
tp = realloc(dst, tsz); |
|
if (tp == NULL) { |
|
ret = -1; |
|
break; |
|
} |
|
dp = tp + (dp - dst); |
|
dst = tp; |
|
sz = tsz; |
|
} |
} |
tp = vis(dp, *sp, VIS_OCTAL | VIS_ALL, 0); |
tp = vis(dp, *sp, VIS_OCTAL | VIS_ALL, 0); |
width = tp - dp; |
width = tp - dp; |