mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 07:38:16 +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;
|
||||
#endif
|
||||
case TYPE_POINTER:
|
||||
case TYPE_POINTER_EXT:
|
||||
ap->a.a_pointer = va_arg (args, void *);
|
||||
break;
|
||||
case TYPE_COUNT_SCHAR_POINTER:
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
/* Get va_list. */
|
||||
#include <stdarg.h>
|
||||
|
||||
#define POINTER_EXT_SIGNIFIER_CHAR '\a'
|
||||
|
||||
/* Argument types */
|
||||
typedef enum
|
||||
|
@ -66,6 +67,7 @@ typedef enum
|
|||
TYPE_WIDE_STRING,
|
||||
#endif
|
||||
TYPE_POINTER,
|
||||
TYPE_POINTER_EXT,
|
||||
TYPE_COUNT_SCHAR_POINTER,
|
||||
TYPE_COUNT_SHORT_POINTER,
|
||||
TYPE_COUNT_INT_POINTER,
|
||||
|
@ -120,6 +122,9 @@ typedef struct
|
|||
#endif
|
||||
}
|
||||
a;
|
||||
|
||||
/* string to replace pointer argument with for TYPE_POINTER_EXT */
|
||||
char *ext_string;
|
||||
}
|
||||
argument;
|
||||
|
||||
|
|
|
@ -80,8 +80,11 @@ printf_parse (const char *format, char_directives * d, arguments * a)
|
|||
goto error; \
|
||||
a->arg = memory; \
|
||||
} \
|
||||
while (a->count <= n) \
|
||||
a->arg[a->count++].type = TYPE_NONE; \
|
||||
while (a->count <= n) { \
|
||||
a->arg[a->count].type = TYPE_NONE; \
|
||||
a->arg[a->count].ext_string = (char *) 0; \
|
||||
++a->count; \
|
||||
} \
|
||||
if (a->arg[n].type == TYPE_NONE) \
|
||||
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;
|
||||
#endif
|
||||
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;
|
||||
case 'n':
|
||||
#ifdef HAVE_LONG_LONG
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#define FLAG_ALT 16 /* # flag */
|
||||
#define FLAG_ZERO 32
|
||||
|
||||
#define FLAG_PTR_EXT 1024
|
||||
|
||||
/* A parsed directive. */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -46,6 +48,11 @@ typedef struct
|
|||
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 */
|
||||
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;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <limits.h> /* CHAR_BIT */
|
||||
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
|
||||
#include "printf-parse.h"
|
||||
#include "printf-extension.h"
|
||||
|
||||
#ifdef HAVE_WCHAR_T
|
||||
# ifdef HAVE_WCSLEN
|
||||
|
@ -223,6 +224,32 @@ print_long_long (char *buf,
|
|||
}
|
||||
#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 *
|
||||
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;
|
||||
}
|
||||
|
||||
/* collect TYPE_POINTER_EXT argument strings */
|
||||
printf_postprocess_args (&d, &a);
|
||||
|
||||
{
|
||||
char *buf =
|
||||
(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 */
|
||||
+ 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;
|
||||
|
||||
default:
|
||||
|
@ -879,6 +913,18 @@ vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
|
|||
case TYPE_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);
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue