Skip to content
Snippets Groups Projects
Commit 1feb9a1f authored by deuce's avatar deuce
Browse files

Update handling of %c so it uses the first char of a charp if that is passed.

Update length handling... do all replacements even if the return string
is prematurely terminated (as with a %c and parameter of zero).

Have xp_asprintf_end() return the length if a pointer is passed.
parent d01880de
No related branches found
No related tags found
No related merge requests found
......@@ -323,9 +323,10 @@ char *xp_asprintf_next(char *format, int type, ...)
*/
if(!*(size_t *) format)
return(format);
p=format+*(size_t *)format;
offset=p-format;
format_len=strlen(format+sizeof(size_t))+sizeof(size_t)+1;
format_len=*(size_t *)(format+sizeof(size_t))+sizeof(size_t)*2+1;
this_format[0]=0;
fmt=this_format;
*(fmt++)=*(p++);
......@@ -615,6 +616,7 @@ char *xp_asprintf_next(char *format, int type, ...)
*/
va_start(vars, type);
switch(type & ~XP_PRINTF_CONVERT) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT: /* Also includes char and short */
i=va_arg(vars, int);
break;
......@@ -661,8 +663,49 @@ char *xp_asprintf_next(char *format, int type, ...)
type=type & ~XP_PRINTF_CONVERT;
if(type != correct_type) {
switch(correct_type) {
case XP_PRINTF_TYPE_CHAR:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
i=i;
break;
case XP_PRINTF_TYPE_UINT:
i=ui;
break;
case XP_PRINTF_TYPE_LONG:
i=l;
break;
case XP_PRINTF_TYPE_ULONG:
i=ul;
break;
#if defined(XP_PRINTF_TYPE_LONGLONG)
case XP_PRINTF_TYPE_LONGLONG:
i=ll;
break;
case XP_PRINTF_TYPE_ULONGLONG:
i=ull;
break;
#endif
case XP_PRINTF_TYPE_CHARP:
i=*cp;
break;
case XP_PRINTF_TYPE_DOUBLE:
i=(int)d;
break;
case XP_PRINTF_TYPE_LONGDOUBLE:
i=(int)ld;
break;
case XP_PRINTF_TYPE_VOIDP:
i=(int)pntr;
break;
case XP_PRINTF_TYPE_SIZET:
i=s;
break;
}
break;
case XP_PRINTF_TYPE_INT:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
i=i;
break;
......@@ -702,6 +745,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_UINT:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
ui=i;
break;
......@@ -741,6 +785,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_LONG:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
l=i;
break;
......@@ -780,6 +825,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_ULONG:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
ul=i;
break;
......@@ -820,6 +866,7 @@ char *xp_asprintf_next(char *format, int type, ...)
#if defined(XP_PRINTF_TYPE_LONGLONG)
case XP_PRINTF_TYPE_LONGLONG:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
ll=i;
break;
......@@ -857,6 +904,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_ULONGLONG:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
ull=i;
break;
......@@ -896,6 +944,7 @@ char *xp_asprintf_next(char *format, int type, ...)
case XP_PRINTF_TYPE_CHARP:
num_str[0]=0;
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
sprintf(num_str, "%d", i);
cp=num_str;
......@@ -948,6 +997,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_DOUBLE:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
d=i;
break;
......@@ -987,6 +1037,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_LONGDOUBLE:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
ld=i;
break;
......@@ -1028,6 +1079,7 @@ char *xp_asprintf_next(char *format, int type, ...)
case XP_PRINTF_TYPE_VOIDP:
/* ToDo: this is nasty... */
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
pntr=(void *)i;
break;
......@@ -1067,6 +1119,7 @@ char *xp_asprintf_next(char *format, int type, ...)
break;
case XP_PRINTF_TYPE_SIZET:
switch(type) {
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT:
s=i;
break;
......@@ -1114,6 +1167,7 @@ char *xp_asprintf_next(char *format, int type, ...)
*fmt=0;
entry=entry_buf;
switch(type) {
case XP_PRINTF_TYPE_CHAR: /* Also includes char and short */
case XP_PRINTF_TYPE_INT: /* Also includes char and short */
j=sprintf(entry, this_format, i);
break;
......@@ -1184,6 +1238,9 @@ char *xp_asprintf_next(char *format, int type, ...)
}
else
p=format+offset+this_format_len;
*(size_t *)(format+sizeof(size_t))=format_len-this_format_len+j-sizeof(size_t)*2-1;
/*
* Search for next non-%% separateor and set offset
* to zero if none found for wrappers to know when
......@@ -1209,15 +1266,18 @@ char *xp_asprintf_start(const char *format)
char *ret;
char *p;
ret=(char *)malloc(strlen(format)+1+(sizeof(size_t)));
ret=(char *)malloc(strlen(format)+1+((sizeof(size_t)*2)));
if(ret==NULL)
return(NULL);
/* Place current offset at the start of the buffer */
strcpy(ret+sizeof(size_t),format);
strcpy(ret+sizeof(size_t)*2,format);
/* Place the current length after the offset */
*(size_t *)(ret+sizeof(size_t))=strlen(format);
/*
* Find the next non %% format, leaving %% as it is
*/
for(p=ret+sizeof(size_t); *p; p++) {
for(p=ret+sizeof(size_t)*2; *p; p++) {
if(*p=='%') {
if(*(p+1) == '%')
p++;
......@@ -1232,17 +1292,23 @@ char *xp_asprintf_start(const char *format)
return(ret);
}
char *xp_asprintf_end(char *format)
char *xp_asprintf_end(char *format, size_t *lenret)
{
char *p;
size_t len;
size_t end_len;
len=strlen(format+sizeof(size_t));
for(p=format+sizeof(size_t); *p; p++, len--) {
if(*p=='%' && *(p+1)=='%')
len=*(size_t *)(format+sizeof(size_t));
end_len=len;
for(p=format+sizeof(size_t)*2; len; p++, len--) {
if(*p=='%' && *(p+1)=='%') {
memmove(p, p+1, len--);
end_len--;
}
}
memmove(format, format+sizeof(size_t), strlen(format+sizeof(size_t))+1);
memmove(format, format+sizeof(size_t)*2, end_len+1);
if(lenret)
*lenret=end_len;
return(format);
}
......@@ -1262,6 +1328,7 @@ char *xp_vasprintf(const char *format, va_list va)
case 0:
free(working);
return(NULL);
case XP_PRINTF_TYPE_CHAR:
case XP_PRINTF_TYPE_INT: /* Also includes char and short */
next=xp_asprintf_next(working, type, va_arg(va, int));
break;
......@@ -1304,7 +1371,7 @@ char *xp_vasprintf(const char *format, va_list va)
}
working=next;
}
next=xp_asprintf_end(working);
next=xp_asprintf_end(working, NULL);
if(next==NULL) {
free(working);
return(NULL);
......@@ -1387,7 +1454,7 @@ int main(int argc, char *argv[])
}
format=p;
}
p=xp_asprintf_end(format);
p=xp_asprintf_end(format, NULL);
printf("At end, value is: '%s'\n",p);
free(p);
}
......
......@@ -45,26 +45,26 @@
#define XP_PRINTF_TYPE_AUTO 0
#define XP_PRINTF_TYPE_INT 1
#define XP_PRINTF_TYPE_UINT 2
#define XP_PRINTF_TYPE_CHAR XP_PRINTF_TYPE_INT /* Assumes a signed char */
#define XP_PRINTF_TYPE_CHAR 3 /* Assumes a signed char */
#define XP_PRINTF_TYPE_SCHAR XP_PRINTF_TYPE_INT
#define XP_PRINTF_TYPE_UCHAR XP_PRINTF_TYPE_UINT
#define XP_PRINTF_TYPE_SHORT XP_PRINTF_TYPE_INT
#define XP_PRINTF_TYPE_USHORT XP_PRINTF_TYPE_UINT
#define XP_PRINTF_TYPE_LONG 3
#define XP_PRINTF_TYPE_ULONG 4
#define XP_PRINTF_TYPE_LONG 4
#define XP_PRINTF_TYPE_ULONG 5
#if !defined(_MSC_VER) && !defined(__BORLANDC__)
#define XP_PRINTF_TYPE_LONGLONG 5
#define XP_PRINTF_TYPE_ULONGLONG 6
#define XP_PRINTF_TYPE_LONGLONG 6
#define XP_PRINTF_TYPE_ULONGLONG 7
#endif
#define XP_PRINTF_TYPE_CHARP 7
#define XP_PRINTF_TYPE_DOUBLE 8
#define XP_PRINTF_TYPE_CHARP 8
#define XP_PRINTF_TYPE_DOUBLE 9
#define XP_PRINTF_TYPE_FLOAT XP_PRINTF_TYPE_DOUBLE /* Floats are promoted to doubles */
#define XP_PRINTF_TYPE_LONGDOUBLE 9
#define XP_PRINTF_TYPE_VOIDP 10
#define XP_PRINTF_TYPE_INTMAX 11 /* Not currently implemented */
#define XP_PRINTF_TYPE_UINTMAX 12 /* Not currently implemented */
#define XP_PRINTF_TYPE_PTRDIFF 13 /* Not currently implemented */
#define XP_PRINTF_TYPE_SIZET 14
#define XP_PRINTF_TYPE_LONGDOUBLE 10
#define XP_PRINTF_TYPE_VOIDP 11
#define XP_PRINTF_TYPE_INTMAX 12 /* Not currently implemented */
#define XP_PRINTF_TYPE_UINTMAX 13 /* Not currently implemented */
#define XP_PRINTF_TYPE_PTRDIFF 14 /* Not currently implemented */
#define XP_PRINTF_TYPE_SIZET 15
#define XP_PRINTF_CONVERT (1<<31) /* OR with type to request a conversion - Not implemented */
......@@ -74,7 +74,7 @@ extern "C" {
void xp_asprintf_free(char *format);
char *xp_asprintf_start(const char *format);
char *xp_asprintf_next(char *format, int type, ...);
char *xp_asprintf_end(char *format);
char *xp_asprintf_end(char *format, size_t *endlen);
char *xp_asprintf(const char *format, ...);
char *xp_vasprintf(const char *format, va_list va);
int xp_printf_get_type(const char *format);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment