mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
printf: make printf parser recognise our pointer extension format
and call the hook to get a string for the pointer instead. https://bugzilla.gnome.org/show_bug.cgi?id=613081
This commit is contained in:
parent
fe7f7135e0
commit
5803da553c
5 changed files with 75 additions and 3 deletions
|
@ -105,6 +105,7 @@ printf_fetchargs (va_list args, arguments * a)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TYPE_POINTER:
|
case TYPE_POINTER:
|
||||||
|
case TYPE_POINTER_EXT:
|
||||||
ap->a.a_pointer = va_arg (args, void *);
|
ap->a.a_pointer = va_arg (args, void *);
|
||||||
break;
|
break;
|
||||||
case TYPE_COUNT_SCHAR_POINTER:
|
case TYPE_COUNT_SCHAR_POINTER:
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
/* Get va_list. */
|
/* Get va_list. */
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define POINTER_EXT_SIGNIFIER_CHAR '\a'
|
||||||
|
|
||||||
/* Argument types */
|
/* Argument types */
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -66,6 +67,7 @@ typedef enum
|
||||||
TYPE_WIDE_STRING,
|
TYPE_WIDE_STRING,
|
||||||
#endif
|
#endif
|
||||||
TYPE_POINTER,
|
TYPE_POINTER,
|
||||||
|
TYPE_POINTER_EXT,
|
||||||
TYPE_COUNT_SCHAR_POINTER,
|
TYPE_COUNT_SCHAR_POINTER,
|
||||||
TYPE_COUNT_SHORT_POINTER,
|
TYPE_COUNT_SHORT_POINTER,
|
||||||
TYPE_COUNT_INT_POINTER,
|
TYPE_COUNT_INT_POINTER,
|
||||||
|
@ -120,6 +122,9 @@ typedef struct
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
a;
|
a;
|
||||||
|
|
||||||
|
/* string to replace pointer argument with for TYPE_POINTER_EXT */
|
||||||
|
char *ext_string;
|
||||||
}
|
}
|
||||||
argument;
|
argument;
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,11 @@ printf_parse (const char *format, char_directives * d, arguments * a)
|
||||||
goto error; \
|
goto error; \
|
||||||
a->arg = memory; \
|
a->arg = memory; \
|
||||||
} \
|
} \
|
||||||
while (a->count <= n) \
|
while (a->count <= n) { \
|
||||||
a->arg[a->count++].type = TYPE_NONE; \
|
a->arg[a->count].type = TYPE_NONE; \
|
||||||
|
a->arg[a->count].ext_string = (char *) 0; \
|
||||||
|
++a->count; \
|
||||||
|
} \
|
||||||
if (a->arg[n].type == TYPE_NONE) \
|
if (a->arg[n].type == TYPE_NONE) \
|
||||||
a->arg[n].type = (_type_); \
|
a->arg[n].type = (_type_); \
|
||||||
else if (a->arg[n].type != (_type_)) \
|
else if (a->arg[n].type != (_type_)) \
|
||||||
|
@ -385,7 +388,17 @@ printf_parse (const char *format, char_directives * d, arguments * a)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'p':
|
case 'p':
|
||||||
type = TYPE_POINTER;
|
/* Note: cp points already to the char after the 'p' now */
|
||||||
|
if (cp[0] == POINTER_EXT_SIGNIFIER_CHAR && cp[1] != '\0') {
|
||||||
|
type = TYPE_POINTER_EXT;
|
||||||
|
dp->flags |= FLAG_PTR_EXT;
|
||||||
|
dp->ptr_ext_char = cp[1];
|
||||||
|
/* we do not use dp->conversion='s' on purpose here, so we
|
||||||
|
* can fall back to printing just the pointer with %p if the
|
||||||
|
* serialisation function returned NULL for some reason */
|
||||||
|
} else {
|
||||||
|
type = TYPE_POINTER;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#define FLAG_ALT 16 /* # flag */
|
#define FLAG_ALT 16 /* # flag */
|
||||||
#define FLAG_ZERO 32
|
#define FLAG_ZERO 32
|
||||||
|
|
||||||
|
#define FLAG_PTR_EXT 1024
|
||||||
|
|
||||||
/* A parsed directive. */
|
/* A parsed directive. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -46,6 +48,11 @@ typedef struct
|
||||||
int precision_arg_index;
|
int precision_arg_index;
|
||||||
char conversion; /* d i o u x X f e E g G c s p n U % but not C S */
|
char conversion; /* d i o u x X f e E g G c s p n U % but not C S */
|
||||||
int arg_index;
|
int arg_index;
|
||||||
|
|
||||||
|
/* extension char in case of TYPE_POINTER_EXT. We need to store this so
|
||||||
|
* we can pass it back to __gst_printf_pointer_extension_serialize()
|
||||||
|
* so it knows which pointer extension it is */
|
||||||
|
char ptr_ext_char;
|
||||||
}
|
}
|
||||||
char_directive;
|
char_directive;
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <limits.h> /* CHAR_BIT */
|
#include <limits.h> /* CHAR_BIT */
|
||||||
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
|
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
|
||||||
#include "printf-parse.h"
|
#include "printf-parse.h"
|
||||||
|
#include "printf-extension.h"
|
||||||
|
|
||||||
#ifdef HAVE_WCHAR_T
|
#ifdef HAVE_WCHAR_T
|
||||||
# ifdef HAVE_WCSLEN
|
# ifdef HAVE_WCSLEN
|
||||||
|
@ -223,6 +224,32 @@ print_long_long (char *buf,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
printf_postprocess_args (char_directives * directives, arguments * arguments)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < directives->count; ++i) {
|
||||||
|
char_directive *dp;
|
||||||
|
argument *a;
|
||||||
|
|
||||||
|
dp = &directives->dir[i];
|
||||||
|
a = &arguments->arg[dp->arg_index];
|
||||||
|
|
||||||
|
if (a->type == TYPE_POINTER_EXT) {
|
||||||
|
char fmt[4];
|
||||||
|
|
||||||
|
fmt[0] = 'p';
|
||||||
|
fmt[1] = POINTER_EXT_SIGNIFIER_CHAR;
|
||||||
|
fmt[2] = dp->ptr_ext_char;
|
||||||
|
fmt[3] = '\0';
|
||||||
|
|
||||||
|
a->ext_string =
|
||||||
|
__gst_printf_pointer_extension_serialize (fmt, a->a.a_pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +271,9 @@ vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* collect TYPE_POINTER_EXT argument strings */
|
||||||
|
printf_postprocess_args (&d, &a);
|
||||||
|
|
||||||
{
|
{
|
||||||
char *buf =
|
char *buf =
|
||||||
(char *) alloca (7 + d.max_width_length + d.max_precision_length + 6);
|
(char *) alloca (7 + d.max_width_length + d.max_precision_length + 6);
|
||||||
|
@ -521,6 +551,10 @@ vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
||||||
)
|
)
|
||||||
+ 1 /* turn floor into ceil */
|
+ 1 /* turn floor into ceil */
|
||||||
+ 2; /* account for leading 0x */
|
+ 2; /* account for leading 0x */
|
||||||
|
|
||||||
|
/* make sure we always have enough space for a plain %p, so + */
|
||||||
|
if (dp->flags & FLAG_PTR_EXT && a.arg[dp->arg_index].ext_string)
|
||||||
|
tmp_length += strlen (a.arg[dp->arg_index].ext_string);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -879,6 +913,18 @@ vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
||||||
case TYPE_POINTER:
|
case TYPE_POINTER:
|
||||||
{
|
{
|
||||||
void *arg = a.arg[dp->arg_index].a.a_pointer;
|
void *arg = a.arg[dp->arg_index].a.a_pointer;
|
||||||
|
SNPRINTF_BUF (arg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_POINTER_EXT:
|
||||||
|
{
|
||||||
|
void *arg = a.arg[dp->arg_index].a.a_pointer;
|
||||||
|
|
||||||
|
if (a.arg[dp->arg_index].ext_string != NULL) {
|
||||||
|
arg = a.arg[dp->arg_index].ext_string;
|
||||||
|
*p = 's';
|
||||||
|
}
|
||||||
|
|
||||||
SNPRINTF_BUF (arg);
|
SNPRINTF_BUF (arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue