Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6323 → Rev 6324

/contrib/toolchain/binutils/libiberty/Makefile
11,7 → 11,7
SRCS = \
alloca.c argv.c asprintf.c bcmp.c bcopy.c bzero.c \
choose-temp.c concat.c cp-demangle.c cp-demint.c \
cplus-dem.c crc32.c dwarfnames.c dyn-string.c fdmatch.c \
cplus-dem.c crc32.c d-demangle.c dwarfnames.c dyn-string.c fdmatch.c \
ffs.c fibheap.c filename_cmp.c floatformat.c fnmatch.c \
fopen_unlocked.c getopt.c getopt1.c getpwd.c \
getruntime.c hashtab.c hex.c index.c insque.c \
24,7 → 24,7
simple-object-xcoff.c sort.c spaces.c splay-tree.c \
stack-limit.c stpcpy.c stpncpy.c strcasecmp.c strerror.c\
strncasecmp.c strndup.c strnlen.c strverscmp.c \
timeval-utils.c unlink-if-ordinary.c vasprintf.c \
timeval-utils.c unlink-if-ordinary.c vasprintf.c vprintf-support.c \
xatexit.c xexit.c xmalloc.c xmemdup.c xstrdup.c \
xstrerror.c xstrndup.c
 
/contrib/toolchain/binutils/libiberty/asprintf.c
1,6 → 1,6
/* Like sprintf but provides a pointer to malloc'd storage, which must
be freed by the caller.
Copyright (C) 1997, 2003 Free Software Foundation, Inc.
Copyright (C) 1997, 2003, 2013 Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
 
This file is part of the libiberty library.
47,10 → 47,9
asprintf (char **buf, const char *fmt, ...)
{
int status;
VA_OPEN (ap, fmt);
VA_FIXEDARG (ap, char **, buf);
VA_FIXEDARG (ap, const char *, fmt);
va_list ap;
va_start (ap, fmt);
status = vasprintf (buf, fmt, ap);
VA_CLOSE (ap);
va_end (ap);
return status;
}
/contrib/toolchain/binutils/libiberty/choose-temp.c
34,7 → 34,6
#endif
 
#include "libiberty.h"
extern char *choose_tmpdir (void);
 
/* Name of temporary file.
mktemp requires 6 trailing X's. */
/contrib/toolchain/binutils/libiberty/concat.c
1,5 → 1,5
/* Concatenate variable number of strings.
Copyright (C) 1991, 1994, 2001, 2011 Free Software Foundation, Inc.
Copyright (C) 1991, 1994, 2001, 2011, 2013 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support
 
This file is part of the libiberty library.
25,23 → 25,11
@dots{}, @code{NULL})
 
Concatenate zero or more of strings and return the result in freshly
@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
available. The argument list is terminated by the first @code{NULL}
pointer encountered. Pointers to empty strings are ignored.
@code{xmalloc}ed memory. The argument list is terminated by the first
@code{NULL} pointer encountered. Pointers to empty strings are ignored.
 
@end deftypefn
 
NOTES
 
This function uses xmalloc() which is expected to be a front end
function to malloc() that deals with low memory situations. In
typical use, if malloc() returns NULL then xmalloc() diverts to an
error handler routine which never returns, and thus xmalloc will
never return a NULL pointer. If the client application wishes to
deal with low memory situations itself, it should supply an xmalloc
that just directly invokes malloc and blindly returns whatever
malloc returns.
 
*/
 
 
102,11 → 90,11
concat_length (const char *first, ...)
{
unsigned long length;
va_list args;
 
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
length = vconcat_length (first, args);
VA_CLOSE (args);
va_end (args);
 
return length;
}
117,13 → 105,12
concat_copy (char *dst, const char *first, ...)
{
char *save_dst;
va_list args;
 
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, dst);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
vconcat_copy (dst, first, args);
save_dst = dst; /* With K&R C, dst goes out of scope here. */
VA_CLOSE (args);
va_end (args);
 
return save_dst;
}
141,10 → 128,10
char *
concat_copy2 (const char *first, ...)
{
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
va_list args;
va_start (args, first);
vconcat_copy (libiberty_concat_ptr, first, args);
VA_CLOSE (args);
va_end (args);
 
return libiberty_concat_ptr;
}
153,18 → 140,17
concat (const char *first, ...)
{
char *newstr;
va_list args;
 
/* First compute the size of the result and get sufficient memory. */
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
VA_CLOSE (args);
va_end (args);
 
/* Now copy the individual pieces to the result string. */
VA_OPEN (args, first);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
vconcat_copy (newstr, first, args);
VA_CLOSE (args);
va_end (args);
 
return newstr;
}
191,22 → 177,19
reconcat (char *optr, const char *first, ...)
{
char *newstr;
va_list args;
 
/* First compute the size of the result and get sufficient memory. */
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, optr);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
VA_CLOSE (args);
va_end (args);
 
/* Now copy the individual pieces to the result string. */
VA_OPEN (args, first);
VA_FIXEDARG (args, char *, optr);
VA_FIXEDARG (args, const char *, first);
va_start (args, first);
vconcat_copy (newstr, first, args);
if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
free (optr);
VA_CLOSE (args);
va_end (args);
 
return newstr;
}
/contrib/toolchain/binutils/libiberty/config.h
9,10 → 9,10
/* #undef CRAY_STACKSEG_END */
 
/* Define to 1 if you have the <alloca.h> header file. */
/* #undef HAVE_ALLOCA_H */
#define HAVE_ALLOCA_H 1
 
/* Define to 1 if you have the `asprintf' function. */
/* #undef HAVE_ASPRINTF */
#define HAVE_ASPRINTF 1
 
/* Define to 1 if you have the `atexit' function. */
#define HAVE_ATEXIT 1
43,11 → 43,11
 
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
don't. */
#define HAVE_DECL_ASPRINTF 0
#define HAVE_DECL_ASPRINTF 1
 
/* Define to 1 if you have the declaration of `basename(char *)', and to 0 if
you don't. */
#define HAVE_DECL_BASENAME 0
#define HAVE_DECL_BASENAME 1
 
/* Define to 1 if you have the declaration of `calloc', and to 0 if you don't.
*/
86,7 → 86,7
 
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#define HAVE_DECL_VASPRINTF 0
#define HAVE_DECL_VASPRINTF 1
 
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
137,6 → 137,9
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
 
/* Define if you have the `long long' type. */
#define HAVE_LONG_LONG 1
 
/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
/* #undef HAVE_MACHINE_HAL_SYSINFO_H */
 
219,10 → 222,10
#define HAVE_SNPRINTF 1
 
/* Define to 1 if you have the `spawnve' function. */
#define HAVE_SPAWNVE 1
#define HAVE_SPAWNVE 0
 
/* Define to 1 if you have the `spawnvpe' function. */
#define HAVE_SPAWNVPE 1
#define HAVE_SPAWNVPE 0
 
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
240,7 → 243,7
/* #undef HAVE_STPNCPY */
 
/* Define to 1 if you have the `strcasecmp' function. */
/* #undef HAVE_STRCASECMP */
#define HAVE_STRCASECMP 1
 
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
264,7 → 267,7
/* #undef HAVE_STRNDUP */
 
/* Define to 1 if you have the `strnlen' function. */
/* #undef HAVE_STRNLEN */
#define HAVE_STRNLEN 1
 
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
281,6 → 284,9
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
 
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
 
/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
 
440,6 → 446,15
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
 
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
 
/* The size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
 
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
 
/* Define if you know the direction of stack growth for your system; otherwise
it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
473,6 → 488,16
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
 
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
 
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
 
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
 
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
 
/contrib/toolchain/binutils/libiberty/cp-demangle.c
1,5 → 1,5
/* Demangler for g++ V3 ABI.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014
Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
275,6 → 275,41
int allocation_failure;
};
 
/* Stack of components, innermost first, used to avoid loops. */
 
struct d_component_stack
{
/* This component. */
const struct demangle_component *dc;
/* This component's parent. */
const struct d_component_stack *parent;
};
 
/* A demangle component and some scope captured when it was first
traversed. */
 
struct d_saved_scope
{
/* The component whose scope this is. */
const struct demangle_component *container;
/* The list of templates, if any, that was current when this
scope was captured. */
struct d_print_template *templates;
};
 
/* Checkpoint structure to allow backtracking. This holds copies
of the fields of struct d_info that need to be restored
if a trial parse needs to be backtracked over. */
 
struct d_info_checkpoint
{
const char *n;
int next_comp;
int next_sub;
int did_subs;
int expansion;
};
 
enum { D_PRINT_BUFFER_LENGTH = 256 };
struct d_print_info
{
302,6 → 337,22
int pack_index;
/* Number of d_print_flush calls so far. */
unsigned long int flush_count;
/* Stack of components, innermost first, used to avoid loops. */
const struct d_component_stack *component_stack;
/* Array of saved scopes for evaluating substitutions. */
struct d_saved_scope *saved_scopes;
/* Index of the next unused saved scope in the above array. */
int next_saved_scope;
/* Number of saved scopes in the above array. */
int num_saved_scopes;
/* Array of templates for saving into scopes. */
struct d_print_template *copy_templates;
/* Index of the next unused copy template in the above array. */
int next_copy_template;
/* Number of copy templates in the above array. */
int num_copy_templates;
/* The nearest enclosing template, if any. */
const struct demangle_component *current_template;
};
 
#ifdef CP_DEMANGLE_DEBUG
428,6 → 479,10
 
static struct demangle_component *d_substitution (struct d_info *, int);
 
static void d_checkpoint (struct d_info *, struct d_info_checkpoint *);
 
static void d_backtrack (struct d_info *, struct d_info_checkpoint *);
 
static void d_growable_string_init (struct d_growable_string *, size_t);
 
static inline void
440,7 → 495,8
d_growable_string_callback_adapter (const char *, size_t, void *);
 
static void
d_print_init (struct d_print_info *, demangle_callbackref, void *);
d_print_init (struct d_print_info *, demangle_callbackref, void *,
const struct demangle_component *);
 
static inline void d_print_error (struct d_print_info *);
 
519,6 → 575,9
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
printf ("template parameter %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
printf ("function parameter %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_CTOR:
printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
d_dump (dc->u.s_ctor.name, indent + 2);
654,7 → 713,9
printf ("pointer to member type\n");
break;
case DEMANGLE_COMPONENT_FIXED_TYPE:
printf ("fixed-point type\n");
printf ("fixed-point type, accum? %d, sat? %d\n",
dc->u.s_fixed.accum, dc->u.s_fixed.sat);
d_dump (dc->u.s_fixed.length, indent + 2)
break;
case DEMANGLE_COMPONENT_ARGLIST:
printf ("argument list\n");
704,6 → 765,9
case DEMANGLE_COMPONENT_CHARACTER:
printf ("character '%c'\n", dc->u.s_character.character);
return;
case DEMANGLE_COMPONENT_NUMBER:
printf ("number %ld\n", dc->u.s_number.number);
return;
case DEMANGLE_COMPONENT_DECLTYPE:
printf ("decltype\n");
break;
1238,7 → 1302,12
static struct demangle_component *
d_abi_tags (struct d_info *di, struct demangle_component *dc)
{
struct demangle_component *hold_last_name;
char peek;
 
/* Preserve the last name, so the ABI tag doesn't clobber it. */
hold_last_name = di->last_name;
 
while (peek = d_peek_char (di),
peek == 'B')
{
1247,6 → 1316,9
tag = d_source_name (di);
dc = d_make_comp (di, DEMANGLE_COMPONENT_TAGGED_NAME, dc, tag);
}
 
di->last_name = hold_last_name;
 
return dc;
}
 
1276,7 → 1348,6
case 'Z':
return d_local_name (di);
 
case 'L':
case 'U':
return d_unqualified_name (di);
 
1323,6 → 1394,7
return dc;
}
 
case 'L':
default:
dc = d_unqualified_name (di);
if (d_peek_char (di) == 'I')
1718,8 → 1790,15
if (c1 == 'v' && IS_DIGIT (c2))
return d_make_extended_operator (di, c2 - '0', d_source_name (di));
else if (c1 == 'c' && c2 == 'v')
return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
cplus_demangle_type (di), NULL);
{
struct demangle_component *type;
int was_conversion = di->is_conversion;
 
di->is_conversion = ! di->is_expression;
type = cplus_demangle_type (di);
di->is_conversion = was_conversion;
return d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL);
}
else
{
/* LOW is the inclusive lower bound. */
2065,6 → 2144,9
case '3':
kind = gnu_v3_complete_object_allocating_ctor;
break;
case '4':
kind = gnu_v3_unified_ctor;
break;
case '5':
kind = gnu_v3_object_ctor_group;
break;
2090,6 → 2172,10
case '2':
kind = gnu_v3_base_object_dtor;
break;
/* digit '3' is not used */
case '4':
kind = gnu_v3_unified_dtor;
break;
case '5':
kind = gnu_v3_object_dtor_group;
break;
2268,14 → 2354,62
ret = d_template_param (di);
if (d_peek_char (di) == 'I')
{
/* This is <template-template-param> <template-args>. The
<template-template-param> part is a substitution
/* This may be <template-template-param> <template-args>.
If this is the type for a conversion operator, we can
have a <template-template-param> here only by following
a derivation like this:
 
<nested-name>
-> <template-prefix> <template-args>
-> <prefix> <template-unqualified-name> <template-args>
-> <unqualified-name> <template-unqualified-name> <template-args>
-> <source-name> <template-unqualified-name> <template-args>
-> <source-name> <operator-name> <template-args>
-> <source-name> cv <type> <template-args>
-> <source-name> cv <template-template-param> <template-args> <template-args>
 
where the <template-args> is followed by another.
Otherwise, we must have a derivation like this:
 
<nested-name>
-> <template-prefix> <template-args>
-> <prefix> <template-unqualified-name> <template-args>
-> <unqualified-name> <template-unqualified-name> <template-args>
-> <source-name> <template-unqualified-name> <template-args>
-> <source-name> <operator-name> <template-args>
-> <source-name> cv <type> <template-args>
-> <source-name> cv <template-param> <template-args>
 
where we need to leave the <template-args> to be processed
by d_prefix (following the <template-prefix>).
 
The <template-template-param> part is a substitution
candidate. */
if (! di->is_conversion)
{
if (! d_add_substitution (di, ret))
return NULL;
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
d_template_args (di));
}
else
{
struct demangle_component *args;
struct d_info_checkpoint checkpoint;
 
d_checkpoint (di, &checkpoint);
args = d_template_args (di);
if (d_peek_char (di) == 'I')
{
if (! d_add_substitution (di, ret))
return NULL;
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
args);
}
else
d_backtrack (di, &checkpoint);
}
}
break;
 
case 'S':
2344,6 → 2478,9
case 'U':
d_advance (di, 1);
ret = d_source_name (di);
if (d_peek_char (di) == 'I')
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
d_template_args (di));
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
cplus_demangle_type (di), ret);
break;
2960,8 → 3097,8
::= <expr-primary>
*/
 
static struct demangle_component *
d_expression (struct d_info *di)
static inline struct demangle_component *
d_expression_1 (struct d_info *di)
{
char peek;
 
2989,7 → 3126,7
{
d_advance (di, 2);
return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
d_expression (di), NULL);
d_expression_1 (di), NULL);
}
else if (peek == 'f' && d_peek_next_char (di) == 'p')
{
3094,7 → 3231,7
&& d_check_char (di, '_'))
operand = d_exprlist (di, 'E');
else
operand = d_expression (di);
operand = d_expression_1 (di);
 
if (suffix)
/* Indicate the suffix variant for d_print_comp. */
3114,7 → 3251,7
if (op_is_new_cast (op))
left = cplus_demangle_type (di);
else
left = d_expression (di);
left = d_expression_1 (di);
if (!strcmp (code, "cl"))
right = d_exprlist (di, 'E');
else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
3125,7 → 3262,7
right, d_template_args (di));
}
else
right = d_expression (di);
right = d_expression_1 (di);
 
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
d_make_comp (di,
3141,9 → 3278,9
if (!strcmp (code, "qu"))
{
/* ?: expression. */
first = d_expression (di);
second = d_expression (di);
third = d_expression (di);
first = d_expression_1 (di);
second = d_expression_1 (di);
third = d_expression_1 (di);
}
else if (code[0] == 'n')
{
3167,7 → 3304,7
else if (d_peek_char (di) == 'i'
&& d_peek_next_char (di) == 'l')
/* initializer-list. */
third = d_expression (di);
third = d_expression_1 (di);
else
return NULL;
}
3187,6 → 3324,18
}
}
 
static struct demangle_component *
d_expression (struct d_info *di)
{
struct demangle_component *ret;
int was_expression = di->is_expression;
 
di->is_expression = 1;
ret = d_expression_1 (di);
di->is_expression = was_expression;
return ret;
}
 
/* <expr-primary> ::= L <type> <(value) number> E
::= L <type> <(value) float> E
::= L <mangled-name> E
3549,6 → 3698,7
{
const char *s;
int len;
struct demangle_component *c;
 
if (p->set_last_name != NULL)
di->last_name = d_make_sub (di, p->set_last_name,
3564,14 → 3714,42
len = p->simple_len;
}
di->expansion += len;
return d_make_sub (di, s, len);
c = d_make_sub (di, s, len);
if (d_peek_char (di) == 'B')
{
/* If there are ABI tags on the abbreviation, it becomes
a substitution candidate. */
c = d_abi_tags (di, c);
d_add_substitution (di, c);
}
return c;
}
}
 
return NULL;
}
}
 
static void
d_checkpoint (struct d_info *di, struct d_info_checkpoint *checkpoint)
{
checkpoint->n = di->n;
checkpoint->next_comp = di->next_comp;
checkpoint->next_sub = di->next_sub;
checkpoint->did_subs = di->did_subs;
checkpoint->expansion = di->expansion;
}
 
static void
d_backtrack (struct d_info *di, struct d_info_checkpoint *checkpoint)
{
di->n = checkpoint->n;
di->next_comp = checkpoint->next_comp;
di->next_sub = checkpoint->next_sub;
di->did_subs = checkpoint->did_subs;
di->expansion = checkpoint->expansion;
}
 
/* Initialize a growable string. */
 
static void
3648,11 → 3826,145
d_growable_string_append_buffer (dgs, s, l);
}
 
/* Walk the tree, counting the number of templates encountered, and
the number of times a scope might be saved. These counts will be
used to allocate data structures for d_print_comp, so the logic
here must mirror the logic d_print_comp will use. It is not
important that the resulting numbers are exact, so long as they
are larger than the actual numbers encountered. */
 
static void
d_count_templates_scopes (int *num_templates, int *num_scopes,
const struct demangle_component *dc)
{
if (dc == NULL)
return;
 
switch (dc->type)
{
case DEMANGLE_COMPONENT_NAME:
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
case DEMANGLE_COMPONENT_SUB_STD:
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
case DEMANGLE_COMPONENT_OPERATOR:
case DEMANGLE_COMPONENT_CHARACTER:
case DEMANGLE_COMPONENT_NUMBER:
case DEMANGLE_COMPONENT_UNNAMED_TYPE:
break;
 
case DEMANGLE_COMPONENT_TEMPLATE:
(*num_templates)++;
goto recurse_left_right;
 
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
if (d_left (dc)->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
(*num_scopes)++;
goto recurse_left_right;
 
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
case DEMANGLE_COMPONENT_TYPED_NAME:
case DEMANGLE_COMPONENT_VTABLE:
case DEMANGLE_COMPONENT_VTT:
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
case DEMANGLE_COMPONENT_TYPEINFO:
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
case DEMANGLE_COMPONENT_TYPEINFO_FN:
case DEMANGLE_COMPONENT_THUNK:
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
case DEMANGLE_COMPONENT_JAVA_CLASS:
case DEMANGLE_COMPONENT_GUARD:
case DEMANGLE_COMPONENT_TLS_INIT:
case DEMANGLE_COMPONENT_TLS_WRAPPER:
case DEMANGLE_COMPONENT_REFTEMP:
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
case DEMANGLE_COMPONENT_VENDOR_TYPE:
case DEMANGLE_COMPONENT_FUNCTION_TYPE:
case DEMANGLE_COMPONENT_ARRAY_TYPE:
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
case DEMANGLE_COMPONENT_INITIALIZER_LIST:
case DEMANGLE_COMPONENT_CAST:
case DEMANGLE_COMPONENT_NULLARY:
case DEMANGLE_COMPONENT_UNARY:
case DEMANGLE_COMPONENT_BINARY:
case DEMANGLE_COMPONENT_BINARY_ARGS:
case DEMANGLE_COMPONENT_TRINARY:
case DEMANGLE_COMPONENT_TRINARY_ARG1:
case DEMANGLE_COMPONENT_TRINARY_ARG2:
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_DECLTYPE:
case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
case DEMANGLE_COMPONENT_PACK_EXPANSION:
case DEMANGLE_COMPONENT_TAGGED_NAME:
case DEMANGLE_COMPONENT_CLONE:
recurse_left_right:
d_count_templates_scopes (num_templates, num_scopes,
d_left (dc));
d_count_templates_scopes (num_templates, num_scopes,
d_right (dc));
break;
 
case DEMANGLE_COMPONENT_CTOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_ctor.name);
break;
 
case DEMANGLE_COMPONENT_DTOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_dtor.name);
break;
 
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_extended_operator.name);
break;
 
case DEMANGLE_COMPONENT_FIXED_TYPE:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_fixed.length);
break;
 
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
d_count_templates_scopes (num_templates, num_scopes,
d_left (dc));
break;
 
case DEMANGLE_COMPONENT_LAMBDA:
case DEMANGLE_COMPONENT_DEFAULT_ARG:
d_count_templates_scopes (num_templates, num_scopes,
dc->u.s_unary_num.sub);
break;
}
}
 
/* Initialize a print information structure. */
 
static void
d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
void *opaque)
void *opaque, const struct demangle_component *dc)
{
dpi->len = 0;
dpi->last_char = '\0';
3665,6 → 3977,22
dpi->opaque = opaque;
 
dpi->demangle_failure = 0;
 
dpi->component_stack = NULL;
 
dpi->saved_scopes = NULL;
dpi->next_saved_scope = 0;
dpi->num_saved_scopes = 0;
 
dpi->copy_templates = NULL;
dpi->next_copy_template = 0;
dpi->num_copy_templates = 0;
 
d_count_templates_scopes (&dpi->num_copy_templates,
&dpi->num_saved_scopes, dc);
dpi->num_copy_templates *= dpi->num_saved_scopes;
 
dpi->current_template = NULL;
}
 
/* Indicate that an error occurred during printing, and test for error. */
3750,9 → 4078,24
{
struct d_print_info dpi;
 
d_print_init (&dpi, callback, opaque);
d_print_init (&dpi, callback, opaque, dc);
 
{
#ifdef CP_DYNAMIC_ARRAYS
__extension__ struct d_saved_scope scopes[dpi.num_saved_scopes];
__extension__ struct d_print_template temps[dpi.num_copy_templates];
 
dpi.saved_scopes = scopes;
dpi.copy_templates = temps;
#else
dpi.saved_scopes = alloca (dpi.num_saved_scopes
* sizeof (*dpi.saved_scopes));
dpi.copy_templates = alloca (dpi.num_copy_templates
* sizeof (*dpi.copy_templates));
#endif
 
d_print_comp (&dpi, options, dc);
}
 
d_print_flush (&dpi);
 
3913,10 → 4256,66
d_append_char (dpi, ')');
}
 
/* Save the current scope. */
 
static void
d_save_scope (struct d_print_info *dpi,
const struct demangle_component *container)
{
struct d_saved_scope *scope;
struct d_print_template *src, **link;
 
if (dpi->next_saved_scope >= dpi->num_saved_scopes)
{
d_print_error (dpi);
return;
}
scope = &dpi->saved_scopes[dpi->next_saved_scope];
dpi->next_saved_scope++;
 
scope->container = container;
link = &scope->templates;
 
for (src = dpi->templates; src != NULL; src = src->next)
{
struct d_print_template *dst;
 
if (dpi->next_copy_template >= dpi->num_copy_templates)
{
d_print_error (dpi);
return;
}
dst = &dpi->copy_templates[dpi->next_copy_template];
dpi->next_copy_template++;
 
dst->template_decl = src->template_decl;
*link = dst;
link = &dst->next;
}
 
*link = NULL;
}
 
/* Attempt to locate a previously saved scope. Returns NULL if no
corresponding saved scope was found. */
 
static struct d_saved_scope *
d_get_saved_scope (struct d_print_info *dpi,
const struct demangle_component *container)
{
int i;
 
for (i = 0; i < dpi->next_saved_scope; i++)
if (dpi->saved_scopes[i].container == container)
return &dpi->saved_scopes[i];
 
return NULL;
}
 
/* Subroutine to handle components. */
 
static void
d_print_comp (struct d_print_info *dpi, int options,
d_print_comp_inner (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
/* Magic variable to let reference smashing skip over the next modifier
3923,6 → 4322,13
without needing to modify *dc. */
const struct demangle_component *mod_inner = NULL;
 
/* Variable used to store the current templates while a previously
captured scope is used. */
struct d_print_template *saved_templates;
 
/* Nonzero if templates have been stored in the above variable. */
int need_template_restore = 0;
 
if (dc == NULL)
{
d_print_error (dpi);
4085,7 → 4491,13
{
struct d_print_mod *hold_dpm;
struct demangle_component *dcl;
const struct demangle_component *hold_current;
 
/* This template may need to be referenced by a cast operator
contained in its subtree. */
hold_current = dpi->current_template;
dpi->current_template = dc;
 
/* Don't push modifiers into a template definition. Doing so
could give the wrong definition for a template argument.
Instead, treat the template essentially as a name. */
4121,6 → 4533,7
}
 
dpi->modifiers = hold_dpm;
dpi->current_template = hold_current;
 
return;
}
4291,12 → 4704,56
const struct demangle_component *sub = d_left (dc);
if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
{
struct demangle_component *a = d_lookup_template_argument (dpi, sub);
struct d_saved_scope *scope = d_get_saved_scope (dpi, sub);
struct demangle_component *a;
 
if (scope == NULL)
{
/* This is the first time SUB has been traversed.
We need to capture the current templates so
they can be restored if SUB is reentered as a
substitution. */
d_save_scope (dpi, sub);
if (d_print_saw_error (dpi))
return;
}
else
{
const struct d_component_stack *dcse;
int found_self_or_parent = 0;
 
/* This traversal is reentering SUB as a substition.
If we are not beneath SUB or DC in the tree then we
need to restore SUB's template stack temporarily. */
for (dcse = dpi->component_stack; dcse != NULL;
dcse = dcse->parent)
{
if (dcse->dc == sub
|| (dcse->dc == dc
&& dcse != dpi->component_stack))
{
found_self_or_parent = 1;
break;
}
}
 
if (!found_self_or_parent)
{
saved_templates = dpi->templates;
dpi->templates = scope->templates;
need_template_restore = 1;
}
}
 
a = d_lookup_template_argument (dpi, sub);
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
a = d_index_template_argument (a, dpi->pack_index);
 
if (a == NULL)
{
if (need_template_restore)
dpi->templates = saved_templates;
 
d_print_error (dpi);
return;
}
4344,6 → 4801,9
 
dpi->modifiers = dpm.next;
 
if (need_template_restore)
dpi->templates = saved_templates;
 
return;
}
 
4921,6 → 5381,21
}
}
 
static void
d_print_comp (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
struct d_component_stack self;
 
self.dc = dc;
self.parent = dpi->component_stack;
dpi->component_stack = &self;
 
d_print_comp_inner (dpi, options, dc);
 
dpi->component_stack = self.parent;
}
 
/* Print a Java dentifier. For Java we try to handle encoded extended
Unicode characters. The C++ ABI doesn't mention Unicode encoding,
so we don't it for C++. Characters are encoded as
5289,27 → 5764,31
d_print_cast (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
d_print_comp (dpi, options, d_left (dc));
else
{
struct d_print_mod *hold_dpm;
struct d_print_template dpt;
 
/* It appears that for a templated cast operator, we need to put
the template parameters in scope for the operator name, but
not for the parameters. The effect is that we need to handle
the template printing here. */
 
hold_dpm = dpi->modifiers;
dpi->modifiers = NULL;
 
/* For a cast operator, we need the template parameters from
the enclosing template in scope for processing the type. */
if (dpi->current_template != NULL)
{
dpt.next = dpi->templates;
dpi->templates = &dpt;
dpt.template_decl = d_left (dc);
dpt.template_decl = dpi->current_template;
}
 
if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
{
d_print_comp (dpi, options, d_left (dc));
if (dpi->current_template != NULL)
dpi->templates = dpt.next;
}
else
{
d_print_comp (dpi, options, d_left (d_left (dc)));
 
/* For a templated cast operator, we need to remove the template
parameters from scope after printing the operator name,
so we need to handle the template printing here. */
if (dpi->current_template != NULL)
dpi->templates = dpt.next;
 
if (d_last_char (dpi) == '<')
5321,8 → 5800,6
if (d_last_char (dpi) == '>')
d_append_char (dpi, ' ');
d_append_char (dpi, '>');
 
dpi->modifiers = hold_dpm;
}
}
 
5355,6 → 5832,8
di->last_name = NULL;
 
di->expansion = 0;
di->is_expression = 0;
di->is_conversion = 0;
}
 
/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI
5425,6 → 5904,8
NULL);
d_advance (&di, strlen (d_str (&di)));
break;
default:
abort (); /* We have listed all the cases. */
}
 
/* If DMGL_PARAMS is set, then if we didn't consume the entire
/contrib/toolchain/binutils/libiberty/cp-demangle.h
122,6 → 122,11
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
/* Non-zero if we are parsing an expression. */
int is_expression;
/* Non-zero if we are parsing the type operand of a conversion
operator, but not when in an expression. */
int is_conversion;
};
 
/* To avoid running past the ending '\0', don't:
/contrib/toolchain/binutils/libiberty/cplus-dem.c
306,6 → 306,12
}
,
{
DLANG_DEMANGLING_STYLE_STRING,
dlang_demangling,
"DLANG style demangling"
}
,
{
NULL, unknown_demangling, NULL
}
};
870,6 → 876,13
if (GNAT_DEMANGLING)
return ada_demangle (mangled, options);
 
if (DLANG_DEMANGLING)
{
ret = dlang_demangle (mangled, options);
if (ret)
return ret;
}
 
ret = internal_cplus_demangle (work, mangled);
squangle_mop_up (work);
return (ret);
1175,7 → 1188,12
if ((AUTO_DEMANGLING || GNU_DEMANGLING))
{
success = gnu_special (work, &mangled, &decl);
if (!success)
{
delete_work_stuff (work);
string_delete (&decl);
}
}
if (!success)
{
success = demangle_prefix (work, &mangled, &decl);
1218,10 → 1236,12
if (work -> btypevec != NULL)
{
free ((char *) work -> btypevec);
work->btypevec = NULL;
}
if (work -> ktypevec != NULL)
{
free ((char *) work -> ktypevec);
work->ktypevec = NULL;
}
}
 
3656,8 → 3676,11
string_delete (&temp);
}
else
{
string_delete (&temp);
break;
}
}
else if (**mangled == 'Q')
{
success = demangle_qualified (work, mangled, &decl,
/contrib/toolchain/binutils/libiberty/d-demangle.c
0,0 → 1,1594
/* Demangler for the D programming language
Copyright 2014, 2015 Free Software Foundation, Inc.
Written by Iain Buclaw (ibuclaw@gdcproject.org)
 
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited permission
to link the compiled version of this file into combinations with other
programs, and to distribute those combinations without any restriction
coming from the use of this file. (The Library Public License
restrictions do apply in other respects; for example, they cover
modification of the file, and distribution when not linked into a
combined executable.)
 
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/>. */
 
/* This file exports one function; dlang_demangle.
 
This file imports strtol for decoding mangled literals. */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
 
#include "safe-ctype.h"
 
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
 
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern long strtol (const char *nptr, char **endptr, int base);
#endif
 
#include <demangle.h>
#include "libiberty.h"
 
/* A mini string-handling package */
 
typedef struct string /* Beware: these aren't required to be */
{ /* '\0' terminated. */
char *b; /* pointer to start of string */
char *p; /* pointer after last character */
char *e; /* pointer after end of allocated space */
} string;
 
static void
string_need (string *s, int n)
{
int tem;
 
if (s->b == NULL)
{
if (n < 32)
{
n = 32;
}
s->p = s->b = XNEWVEC (char, n);
s->e = s->b + n;
}
else if (s->e - s->p < n)
{
tem = s->p - s->b;
n += tem;
n *= 2;
s->b = XRESIZEVEC (char, s->b, n);
s->p = s->b + tem;
s->e = s->b + n;
}
}
 
static void
string_delete (string *s)
{
if (s->b != NULL)
{
XDELETEVEC (s->b);
s->b = s->e = s->p = NULL;
}
}
 
static void
string_init (string *s)
{
s->b = s->p = s->e = NULL;
}
 
static int
string_length (string *s)
{
if (s->p == s->b)
{
return 0;
}
return s->p - s->b;
}
 
static void
string_setlength (string *s, int n)
{
if (n - string_length (s) < 0)
{
s->p = s->b + n;
}
}
 
static void
string_append (string *p, const char *s)
{
int n = strlen (s);
string_need (p, n);
memcpy (p->p, s, n);
p->p += n;
}
 
static void
string_appendn (string *p, const char *s, int n)
{
if (n != 0)
{
string_need (p, n);
memcpy (p->p, s, n);
p->p += n;
}
}
 
static void
string_prependn (string *p, const char *s, int n)
{
char *q;
 
if (n != 0)
{
string_need (p, n);
for (q = p->p - 1; q >= p->b; q--)
{
q[n] = q[0];
}
memcpy (p->b, s, n);
p->p += n;
}
}
 
static void
string_prepend (string *p, const char *s)
{
if (s != NULL && *s != '\0')
{
string_prependn (p, s, strlen (s));
}
}
 
/* What kinds of symbol we could be parsing. */
enum dlang_symbol_kinds
{
/* Top-level symbol, needs it's type checked. */
dlang_top_level,
/* Function symbol, needs it's type checked. */
dlang_function,
/* Strongly typed name, such as for classes, structs and enums. */
dlang_type_name,
/* Template identifier. */
dlang_template_ident,
/* Template symbol parameter. */
dlang_template_param
};
 
/* Prototypes for forward referenced functions */
static const char *dlang_function_args (string *, const char *);
 
static const char *dlang_type (string *, const char *);
 
static const char *dlang_value (string *, const char *, const char *, char);
 
static const char *dlang_parse_symbol (string *, const char *,
enum dlang_symbol_kinds);
 
static const char *dlang_parse_tuple (string *, const char *);
 
static const char *dlang_parse_template (string *, const char *, long);
 
 
/* Demangle the calling convention from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_call_convention (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
 
switch (*mangled)
{
case 'F': /* (D) */
mangled++;
break;
case 'U': /* (C) */
mangled++;
string_append (decl, "extern(C) ");
break;
case 'W': /* (Windows) */
mangled++;
string_append (decl, "extern(Windows) ");
break;
case 'V': /* (Pascal) */
mangled++;
string_append (decl, "extern(Pascal) ");
break;
case 'R': /* (C++) */
mangled++;
string_append (decl, "extern(C++) ");
break;
default:
return NULL;
}
 
return mangled;
}
 
/* Extract the type modifiers from MANGLED and append them to DECL.
Returns the remaining signature on success or NULL on failure. */
static const char *
dlang_type_modifiers (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
 
switch (*mangled)
{
case 'x': /* const */
mangled++;
string_append (decl, " const");
return mangled;
case 'y': /* immutable */
mangled++;
string_append (decl, " immutable");
return mangled;
case 'O': /* shared */
mangled++;
string_append (decl, " shared");
return dlang_type_modifiers (decl, mangled);
case 'N':
mangled++;
if (*mangled == 'g') /* wild */
{
mangled++;
string_append (decl, " inout");
return dlang_type_modifiers (decl, mangled);
}
else
return NULL;
 
default:
return mangled;
}
}
 
/* Demangle the D function attributes from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_attributes (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
 
while (*mangled == 'N')
{
mangled++;
switch (*mangled)
{
case 'a': /* pure */
mangled++;
string_append (decl, "pure ");
continue;
case 'b': /* nothrow */
mangled++;
string_append (decl, "nothrow ");
continue;
case 'c': /* ref */
mangled++;
string_append (decl, "ref ");
continue;
case 'd': /* @property */
mangled++;
string_append (decl, "@property ");
continue;
case 'e': /* @trusted */
mangled++;
string_append (decl, "@trusted ");
continue;
case 'f': /* @safe */
mangled++;
string_append (decl, "@safe ");
continue;
case 'g':
case 'h':
case 'k':
/* inout parameter is represented as 'Ng'.
vector parameter is represented as 'Nh'.
return paramenter is represented as 'Nk'.
If we see this, then we know we're really in the
parameter list. Rewind and break. */
mangled--;
break;
case 'i': /* @nogc */
mangled++;
string_append (decl, "@nogc ");
continue;
case 'j': /* return */
mangled++;
string_append (decl, "return ");
continue;
 
default: /* unknown attribute */
return NULL;
}
break;
}
 
return mangled;
}
 
/* Demangle the function type from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_function_type (string *decl, const char *mangled)
{
string attr, args, type;
size_t szattr, szargs, sztype;
 
if (mangled == NULL || *mangled == '\0')
return NULL;
 
/* The order of the mangled string is:
CallConvention FuncAttrs Arguments ArgClose Type
 
The demangled string is re-ordered as:
CallConvention Type Arguments FuncAttrs
*/
string_init (&attr);
string_init (&args);
string_init (&type);
 
/* Function call convention. */
mangled = dlang_call_convention (decl, mangled);
 
/* Function attributes. */
mangled = dlang_attributes (&attr, mangled);
szattr = string_length (&attr);
 
/* Function arguments. */
mangled = dlang_function_args (&args, mangled);
szargs = string_length (&args);
 
/* Function return type. */
mangled = dlang_type (&type, mangled);
sztype = string_length (&type);
 
/* Append to decl in order. */
string_appendn (decl, type.b, sztype);
string_append (decl, "(");
string_appendn (decl, args.b, szargs);
string_append (decl, ") ");
string_appendn (decl, attr.b, szattr);
 
string_delete (&attr);
string_delete (&args);
string_delete (&type);
return mangled;
}
 
/* Demangle the argument list from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_function_args (string *decl, const char *mangled)
{
size_t n = 0;
 
while (mangled && *mangled != '\0')
{
switch (*mangled)
{
case 'X': /* (variadic T t...) style. */
mangled++;
string_append (decl, "...");
return mangled;
case 'Y': /* (variadic T t, ...) style. */
mangled++;
string_append (decl, ", ...");
return mangled;
case 'Z': /* Normal function. */
mangled++;
return mangled;
}
 
if (n++)
string_append (decl, ", ");
 
if (*mangled == 'M') /* scope(T) */
{
mangled++;
string_append (decl, "scope ");
}
 
if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
{
mangled += 2;
string_append (decl, "return ");
}
 
switch (*mangled)
{
case 'J': /* out(T) */
mangled++;
string_append (decl, "out ");
break;
case 'K': /* ref(T) */
mangled++;
string_append (decl, "ref ");
break;
case 'L': /* lazy(T) */
mangled++;
string_append (decl, "lazy ");
break;
}
mangled = dlang_type (decl, mangled);
}
 
return mangled;
}
 
/* Demangle the type from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_type (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
 
switch (*mangled)
{
case 'O': /* shared(T) */
mangled++;
string_append (decl, "shared(");
mangled = dlang_type (decl, mangled);
string_append (decl, ")");
return mangled;
case 'x': /* const(T) */
mangled++;
string_append (decl, "const(");
mangled = dlang_type (decl, mangled);
string_append (decl, ")");
return mangled;
case 'y': /* immutable(T) */
mangled++;
string_append (decl, "immutable(");
mangled = dlang_type (decl, mangled);
string_append (decl, ")");
return mangled;
case 'N':
mangled++;
if (*mangled == 'g') /* wild(T) */
{
mangled++;
string_append (decl, "inout(");
mangled = dlang_type (decl, mangled);
string_append (decl, ")");
return mangled;
}
else if (*mangled == 'h') /* vector(T) */
{
mangled++;
string_append (decl, "__vector(");
mangled = dlang_type (decl, mangled);
string_append (decl, ")");
return mangled;
}
else
return NULL;
case 'A': /* dynamic array (T[]) */
mangled++;
mangled = dlang_type (decl, mangled);
string_append (decl, "[]");
return mangled;
case 'G': /* static array (T[N]) */
{
const char *numptr;
size_t num = 0;
mangled++;
 
numptr = mangled;
while (ISDIGIT (*mangled))
{
num++;
mangled++;
}
mangled = dlang_type (decl, mangled);
string_append (decl, "[");
string_appendn (decl, numptr, num);
string_append (decl, "]");
return mangled;
}
case 'H': /* associative array (T[T]) */
{
string type;
size_t sztype;
mangled++;
 
string_init (&type);
mangled = dlang_type (&type, mangled);
sztype = string_length (&type);
 
mangled = dlang_type (decl, mangled);
string_append (decl, "[");
string_appendn (decl, type.b, sztype);
string_append (decl, "]");
 
string_delete (&type);
return mangled;
}
case 'P': /* pointer (T*) */
mangled++;
mangled = dlang_type (decl, mangled);
string_append (decl, "*");
return mangled;
case 'I': /* ident T */
case 'C': /* class T */
case 'S': /* struct T */
case 'E': /* enum T */
case 'T': /* typedef T */
mangled++;
return dlang_parse_symbol (decl, mangled, dlang_type_name);
case 'D': /* delegate T */
{
string mods;
size_t szmods;
mangled++;
 
string_init (&mods);
mangled = dlang_type_modifiers (&mods, mangled);
szmods = string_length (&mods);
 
mangled = dlang_function_type (decl, mangled);
string_append (decl, "delegate");
string_appendn (decl, mods.b, szmods);
 
string_delete (&mods);
return mangled;
}
case 'B': /* tuple T */
mangled++;
return dlang_parse_tuple (decl, mangled);
 
/* Function types */
case 'F': case 'U': case 'W':
case 'V': case 'R':
mangled = dlang_function_type (decl, mangled);
string_append (decl, "function");
return mangled;
 
/* Basic types */
case 'n':
mangled++;
string_append (decl, "none");
return mangled;
case 'v':
mangled++;
string_append (decl, "void");
return mangled;
case 'g':
mangled++;
string_append (decl, "byte");
return mangled;
case 'h':
mangled++;
string_append (decl, "ubyte");
return mangled;
case 's':
mangled++;
string_append (decl, "short");
return mangled;
case 't':
mangled++;
string_append (decl, "ushort");
return mangled;
case 'i':
mangled++;
string_append (decl, "int");
return mangled;
case 'k':
mangled++;
string_append (decl, "uint");
return mangled;
case 'l':
mangled++;
string_append (decl, "long");
return mangled;
case 'm':
mangled++;
string_append (decl, "ulong");
return mangled;
case 'f':
mangled++;
string_append (decl, "float");
return mangled;
case 'd':
mangled++;
string_append (decl, "double");
return mangled;
case 'e':
mangled++;
string_append (decl, "real");
return mangled;
 
/* Imaginary and Complex types */
case 'o':
mangled++;
string_append (decl, "ifloat");
return mangled;
case 'p':
mangled++;
string_append (decl, "idouble");
return mangled;
case 'j':
mangled++;
string_append (decl, "ireal");
return mangled;
case 'q':
mangled++;
string_append (decl, "cfloat");
return mangled;
case 'r':
mangled++;
string_append (decl, "cdouble");
return mangled;
case 'c':
mangled++;
string_append (decl, "creal");
return mangled;
 
/* Other types */
case 'b':
mangled++;
string_append (decl, "bool");
return mangled;
case 'a':
mangled++;
string_append (decl, "char");
return mangled;
case 'u':
mangled++;
string_append (decl, "wchar");
return mangled;
case 'w':
mangled++;
string_append (decl, "dchar");
return mangled;
case 'z':
mangled++;
switch (*mangled)
{
case 'i':
mangled++;
string_append (decl, "cent");
return mangled;
case 'k':
mangled++;
string_append (decl, "ucent");
return mangled;
}
return NULL;
 
default: /* unhandled */
return NULL;
}
}
 
/* Extract the identifier from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_identifier (string *decl, const char *mangled,
enum dlang_symbol_kinds kind)
{
char *endptr;
long len;
 
if (mangled == NULL || *mangled == '\0')
return NULL;
 
len = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || len <= 0)
return NULL;
 
/* In template parameter symbols, the first character of the mangled
name can be a digit. This causes ambiguity issues because the
digits of the two numbers are adjacent. */
if (kind == dlang_template_param)
{
long psize = len;
char *pend;
int saved = string_length (decl);
 
/* Work backwards until a match is found. */
for (pend = endptr; endptr != NULL; pend--)
{
mangled = pend;
 
/* Reached the beginning of the pointer to the name length,
try parsing the entire symbol. */
if (psize == 0)
{
psize = len;
pend = endptr;
endptr = NULL;
}
 
/* Check whether template parameter is a function with a valid
return type or an untyped identifier. */
if (ISDIGIT (*mangled))
mangled = dlang_parse_symbol (decl, mangled, dlang_template_ident);
else if (strncmp (mangled, "_D", 2) == 0)
{
mangled += 2;
mangled = dlang_parse_symbol (decl, mangled, dlang_function);
}
 
/* Check for name length mismatch. */
if (mangled && (mangled - pend) == psize)
return mangled;
 
psize /= 10;
string_setlength (decl, saved);
}
 
/* No match on any combinations. */
return NULL;
}
else
{
if (strlen (endptr) < (size_t) len)
return NULL;
 
mangled = endptr;
 
/* May be a template instance. */
if (len >= 5 && strncmp (mangled, "__T", 3) == 0)
{
/* Template symbol. */
if (ISDIGIT (mangled[3]) && mangled[3] != '0')
return dlang_parse_template (decl, mangled, len);
 
return NULL;
}
 
switch (len)
{
case 6:
if (strncmp (mangled, "__ctor", len) == 0)
{
/* Constructor symbol for a class/struct. */
string_append (decl, "this");
mangled += len;
return mangled;
}
else if (strncmp (mangled, "__dtor", len) == 0)
{
/* Destructor symbol for a class/struct. */
string_append (decl, "~this");
mangled += len;
return mangled;
}
else if (strncmp (mangled, "__initZ", len+1) == 0)
{
/* The static initialiser for a given symbol. */
string_append (decl, "init$");
mangled += len;
return mangled;
}
else if (strncmp (mangled, "__vtblZ", len+1) == 0)
{
/* The vtable symbol for a given class. */
string_prepend (decl, "vtable for ");
string_setlength (decl, string_length (decl) - 1);
mangled += len;
return mangled;
}
break;
 
case 7:
if (strncmp (mangled, "__ClassZ", len+1) == 0)
{
/* The classinfo symbol for a given class. */
string_prepend (decl, "ClassInfo for ");
string_setlength (decl, string_length (decl) - 1);
mangled += len;
return mangled;
}
break;
 
case 10:
if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
{
/* Postblit symbol for a struct. */
string_append (decl, "this(this)");
mangled += len + 3;
return mangled;
}
break;
 
case 11:
if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
{
/* The interface symbol for a given class. */
string_prepend (decl, "Interface for ");
string_setlength (decl, string_length (decl) - 1);
mangled += len;
return mangled;
}
break;
 
case 12:
if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
{
/* The ModuleInfo symbol for a given module. */
string_prepend (decl, "ModuleInfo for ");
string_setlength (decl, string_length (decl) - 1);
mangled += len;
return mangled;
}
break;
}
 
string_appendn (decl, mangled, len);
mangled += len;
}
 
return mangled;
}
 
/* Extract the integer value from MANGLED and append it to DECL,
where TYPE is the type it should be represented as.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_integer (string *decl, const char *mangled, char type)
{
if (type == 'a' || type == 'u' || type == 'w')
{
/* Parse character value. */
char value[10];
int pos = 10;
int width = 0;
char *endptr;
long val = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || val < 0)
return NULL;
 
string_append (decl, "'");
 
if (type == 'a' && val >= 0x20 && val < 0x7F)
{
/* Represent as a character literal. */
char c = (char) val;
string_appendn (decl, &c, 1);
}
else
{
/* Represent as a hexadecimal value. */
switch (type)
{
case 'a': /* char */
string_append (decl, "\\x");
width = 2;
break;
case 'u': /* wchar */
string_append (decl, "\\u");
width = 4;
break;
case 'w': /* dchar */
string_append (decl, "\\U");
width = 8;
break;
}
 
while (val > 0)
{
int digit = val % 16;
 
if (digit < 10)
value[--pos] = (char)(digit + '0');
else
value[--pos] = (char)((digit - 10) + 'a');
 
val /= 16;
width--;
}
 
for (; width > 0; width--)
value[--pos] = '0';
 
string_appendn (decl, &(value[pos]), 10 - pos);
}
string_append (decl, "'");
mangled = endptr;
}
else if (type == 'b')
{
/* Parse boolean value. */
char *endptr;
long val = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || val < 0)
return NULL;
 
string_append (decl, val ? "true" : "false");
mangled = endptr;
}
else
{
/* Parse integer value. */
const char *numptr = mangled;
size_t num = 0;
 
while (ISDIGIT (*mangled))
{
num++;
mangled++;
}
string_appendn (decl, numptr, num);
 
/* Append suffix. */
switch (type)
{
case 'h': /* ubyte */
case 't': /* ushort */
case 'k': /* uint */
string_append (decl, "u");
break;
case 'l': /* long */
string_append (decl, "L");
break;
case 'm': /* ulong */
string_append (decl, "uL");
break;
}
}
 
return mangled;
}
 
/* Extract the floating-point value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_real (string *decl, const char *mangled)
{
char buffer[64];
int len = 0;
 
/* Handle NAN and +-INF. */
if (strncmp (mangled, "NAN", 3) == 0)
{
string_append (decl, "NaN");
mangled += 3;
return mangled;
}
else if (strncmp (mangled, "INF", 3) == 0)
{
string_append (decl, "Inf");
mangled += 3;
return mangled;
}
else if (strncmp (mangled, "NINF", 4) == 0)
{
string_append (decl, "-Inf");
mangled += 4;
return mangled;
}
 
/* Hexadecimal prefix and leading bit. */
if (*mangled == 'N')
{
buffer[len++] = '-';
mangled++;
}
 
if (!ISXDIGIT (*mangled))
return NULL;
 
buffer[len++] = '0';
buffer[len++] = 'x';
buffer[len++] = *mangled;
buffer[len++] = '.';
mangled++;
 
/* Significand. */
while (ISXDIGIT (*mangled))
{
buffer[len++] = *mangled;
mangled++;
}
 
/* Exponent. */
if (*mangled != 'P')
return NULL;
 
buffer[len++] = 'p';
mangled++;
 
if (*mangled == 'N')
{
buffer[len++] = '-';
mangled++;
}
 
while (ISDIGIT (*mangled))
{
buffer[len++] = *mangled;
mangled++;
}
 
/* Write out the demangled hexadecimal, rather than trying to
convert the buffer into a floating-point value. */
buffer[len] = '\0';
len = strlen (buffer);
string_appendn (decl, buffer, len);
return mangled;
}
 
/* Convert VAL from an ascii hexdigit to value. */
static char
ascii2hex (char val)
{
if (val >= 'a' && val <= 'f')
return (val - 'a' + 10);
 
if (val >= 'A' && val <= 'F')
return (val - 'A' + 10);
 
if (val >= '0' && val <= '9')
return (val - '0');
 
return 0;
}
 
/* Extract the string value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_string (string *decl, const char *mangled)
{
char type = *mangled;
char *endptr;
long len;
 
mangled++;
len = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || len < 0)
return NULL;
 
mangled = endptr;
if (*mangled != '_')
return NULL;
 
mangled++;
string_append (decl, "\"");
while (len--)
{
if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1]))
{
char a = ascii2hex (mangled[0]);
char b = ascii2hex (mangled[1]);
char val = (a << 4) | b;
 
/* Sanitize white and non-printable characters. */
switch (val)
{
case ' ':
string_append (decl, " ");
break;
case '\t':
string_append (decl, "\\t");
break;
case '\n':
string_append (decl, "\\n");
break;
case '\r':
string_append (decl, "\\r");
break;
case '\f':
string_append (decl, "\\f");
break;
case '\v':
string_append (decl, "\\v");
break;
 
default:
if (ISPRINT (val))
string_appendn (decl, &val, 1);
else
{
string_append (decl, "\\x");
string_appendn (decl, mangled, 2);
}
}
}
else
return NULL;
 
mangled += 2;
}
string_append (decl, "\"");
 
if (type != 'a')
string_appendn (decl, &type, 1);
 
return mangled;
}
 
/* Extract the static array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_arrayliteral (string *decl, const char *mangled)
{
char *endptr;
long elements = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || elements < 0)
return NULL;
 
mangled = endptr;
string_append (decl, "[");
while (elements--)
{
mangled = dlang_value (decl, mangled, NULL, '\0');
if (elements != 0)
string_append (decl, ", ");
}
 
string_append (decl, "]");
return mangled;
}
 
/* Extract the associative array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_assocarray (string *decl, const char *mangled)
{
char *endptr;
long elements = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || elements < 0)
return NULL;
 
mangled = endptr;
string_append (decl, "[");
while (elements--)
{
mangled = dlang_value (decl, mangled, NULL, '\0');
string_append (decl, ":");
mangled = dlang_value (decl, mangled, NULL, '\0');
 
if (elements != 0)
string_append (decl, ", ");
}
 
string_append (decl, "]");
return mangled;
}
 
/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_structlit (string *decl, const char *mangled, const char *name)
{
char *endptr;
long args = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || args < 0)
return NULL;
 
mangled = endptr;
if (name != NULL)
string_append (decl, name);
 
string_append (decl, "(");
while (args--)
{
mangled = dlang_value (decl, mangled, NULL, '\0');
if (args != 0)
string_append (decl, ", ");
}
 
string_append (decl, ")");
return mangled;
}
 
/* Extract the value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_value (string *decl, const char *mangled, const char *name, char type)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
 
switch (*mangled)
{
/* Null value. */
case 'n':
mangled++;
string_append (decl, "null");
break;
 
/* Integral values. */
case 'N':
mangled++;
string_append (decl, "-");
mangled = dlang_parse_integer (decl, mangled, type);
break;
 
case 'i':
mangled++;
if (*mangled < '0' || *mangled > '9')
return NULL;
/* Fall through */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
mangled = dlang_parse_integer (decl, mangled, type);
break;
 
/* Real value. */
case 'e':
mangled++;
mangled = dlang_parse_real (decl, mangled);
break;
 
/* Complex value. */
case 'c':
mangled++;
mangled = dlang_parse_real (decl, mangled);
string_append (decl, "+");
if (mangled == NULL || *mangled != 'c')
return NULL;
mangled++;
mangled = dlang_parse_real (decl, mangled);
string_append (decl, "i");
break;
 
/* String values. */
case 'a': /* UTF8 */
case 'w': /* UTF16 */
case 'd': /* UTF32 */
mangled = dlang_parse_string (decl, mangled);
break;
 
/* Array values. */
case 'A':
mangled++;
if (type == 'H')
mangled = dlang_parse_assocarray (decl, mangled);
else
mangled = dlang_parse_arrayliteral (decl, mangled);
break;
 
/* Struct values. */
case 'S':
mangled++;
mangled = dlang_parse_structlit (decl, mangled, name);
break;
 
default:
return NULL;
}
 
return mangled;
}
 
/* Extract the type modifiers from MANGLED and return the string
length that it consumes in MANGLED on success or 0 on failure. */
static int
dlang_type_modifier_p (const char *mangled)
{
int i;
 
switch (*mangled)
{
case 'x': case 'y':
return 1;
 
case 'O':
mangled++;
i = dlang_type_modifier_p (mangled);
return i + 1;
 
case 'N':
mangled++;
if (*mangled == 'g')
{
mangled++;
i = dlang_type_modifier_p (mangled);
return i + 2;
}
}
 
return 0;
}
 
/* Extract the function calling convention from MANGLED and
return 1 on success or 0 on failure. */
static int
dlang_call_convention_p (const char *mangled)
{
/* Prefix for functions needing 'this' */
if (*mangled == 'M')
{
mangled++;
/* Also skip over any type modifiers. */
mangled += dlang_type_modifier_p (mangled);
}
 
switch (*mangled)
{
case 'F': case 'U': case 'V':
case 'W': case 'R':
return 1;
 
default:
return 0;
}
}
 
/* Extract and demangle the symbol in MANGLED and append it to DECL.
Returns the remaining signature on success or NULL on failure. */
static const char *
dlang_parse_symbol (string *decl, const char *mangled,
enum dlang_symbol_kinds kind)
{
int saved;
size_t n = 0;
do
{
if (n++)
string_append (decl, ".");
 
mangled = dlang_identifier (decl, mangled, kind);
 
if (mangled && dlang_call_convention_p (mangled))
{
string mods;
const char *start = NULL;
int checkpoint = 0;
 
/* Skip over 'this' parameter. */
if (*mangled == 'M')
mangled++;
 
/* We have reached here because we expect an extern(Pascal) function.
However this is so rare, that it is more likely a template value
parameter. Since this can't be assumed, first attempt parsing
the symbol as a function, and then back out on failure. */
if (*mangled == 'V')
{
start = mangled;
checkpoint = string_length (decl);
}
 
/* Save the type modifiers for appending at the end. */
string_init (&mods);
mangled = dlang_type_modifiers (&mods, mangled);
 
/* Skip over calling convention and attributes in qualified name. */
saved = string_length (decl);
mangled = dlang_call_convention (decl, mangled);
mangled = dlang_attributes (decl, mangled);
string_setlength (decl, saved);
 
string_append (decl, "(");
mangled = dlang_function_args (decl, mangled);
string_append (decl, ")");
 
/* Add any const/immutable/shared modifier. */
string_appendn (decl, mods.b, string_length (&mods));
string_delete (&mods);
 
if (mangled == NULL && checkpoint != 0)
{
mangled = start;
string_setlength (decl, checkpoint);
}
}
}
while (mangled && ISDIGIT (*mangled));
 
/* Only top-level symbols or function template parameters have
a type that needs checking. */
if (kind == dlang_top_level || kind == dlang_function)
{
/* Artificial symbols end with 'Z' and have no type. */
if (mangled && *mangled == 'Z')
mangled++;
else
{
saved = string_length (decl);
mangled = dlang_type (decl, mangled);
string_setlength (decl, saved);
}
 
/* Check that the entire symbol was successfully demangled. */
if (kind == dlang_top_level)
{
if (mangled == NULL || *mangled != '\0')
return NULL;
}
}
 
return mangled;
}
 
/* Demangle the tuple from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_parse_tuple (string *decl, const char *mangled)
{
char *endptr;
long elements = strtol (mangled, &endptr, 10);
 
if (endptr == NULL || elements < 0)
return NULL;
 
mangled = endptr;
string_append (decl, "Tuple!(");
 
while (elements--)
{
mangled = dlang_type (decl, mangled);
if (elements != 0)
string_append (decl, ", ");
}
 
string_append (decl, ")");
return mangled;
}
 
/* Demangle the argument list from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
dlang_template_args (string *decl, const char *mangled)
{
size_t n = 0;
 
while (mangled && *mangled != '\0')
{
switch (*mangled)
{
case 'Z': /* End of parameter list. */
mangled++;
return mangled;
}
 
if (n++)
string_append (decl, ", ");
 
/* Skip over specialised template prefix. */
if (*mangled == 'H')
mangled++;
 
switch (*mangled)
{
case 'S': /* Symbol parameter. */
mangled++;
mangled = dlang_parse_symbol (decl, mangled, dlang_template_param);
break;
case 'T': /* Type parameter. */
mangled++;
mangled = dlang_type (decl, mangled);
break;
case 'V': /* Value parameter. */
{
string name;
char type;
 
/* Peek at the type. */
mangled++;
type = *mangled;
 
/* In the few instances where the type is actually desired in
the output, it should precede the value from dlang_value. */
string_init (&name);
mangled = dlang_type (&name, mangled);
string_need (&name, 1);
*(name.p) = '\0';
 
mangled = dlang_value (decl, mangled, name.b, type);
string_delete (&name);
break;
}
 
default:
return NULL;
}
}
 
return mangled;
}
 
/* Extract and demangle the template symbol in MANGLED, expected to
be made up of LEN characters, and append it to DECL.
Returns the remaining signature on success or NULL on failure. */
static const char *
dlang_parse_template (string *decl, const char *mangled, long len)
{
const char *start = mangled;
 
/* Template instance names have the types and values of its parameters
encoded into it.
 
TemplateInstanceName:
Number __T LName TemplateArgs Z
^
The start pointer should be at the above location, and LEN should be
the value of the decoded number.
*/
if (strncmp (mangled, "__T", 3) != 0)
return NULL;
 
mangled += 3;
 
/* Template identifier. */
mangled = dlang_identifier (decl, mangled, dlang_template_ident);
 
/* Template arguments. */
string_append (decl, "!(");
mangled = dlang_template_args (decl, mangled);
string_append (decl, ")");
 
/* Check for template name length mismatch. */
if (mangled && (mangled - start) != len)
return NULL;
 
return mangled;
}
 
/* Extract and demangle the symbol in MANGLED. Returns the demangled
signature on success or NULL on failure. */
 
char *
dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
string decl;
char *demangled = NULL;
 
if (mangled == NULL || *mangled == '\0')
return NULL;
 
if (strncmp (mangled, "_D", 2) != 0)
return NULL;
 
string_init (&decl);
 
if (strcmp (mangled, "_Dmain") == 0)
{
string_append (&decl, "D main");
}
else
{
mangled += 2;
 
if (dlang_parse_symbol (&decl, mangled, dlang_top_level) == NULL)
string_delete (&decl);
}
 
if (string_length (&decl) > 0)
{
string_need (&decl, 1);
*(decl.p) = '\0';
demangled = decl.b;
}
 
return demangled;
}
 
/contrib/toolchain/binutils/libiberty/dvo_ch7xxx.c
0,0 → 1,368
/**************************************************************************
 
Copyright © 2006 Dave Airlie
 
All Rights Reserved.
 
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
 
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
**************************************************************************/
 
#include "dvo.h"
 
#define CH7xxx_REG_VID 0x4a
#define CH7xxx_REG_DID 0x4b
 
#define CH7011_VID 0x83 /* 7010 as well */
#define CH7010B_VID 0x05
#define CH7009A_VID 0x84
#define CH7009B_VID 0x85
#define CH7301_VID 0x95
 
#define CH7xxx_VID 0x84
#define CH7xxx_DID 0x17
#define CH7010_DID 0x16
 
#define CH7xxx_NUM_REGS 0x4c
 
#define CH7xxx_CM 0x1c
#define CH7xxx_CM_XCM (1<<0)
#define CH7xxx_CM_MCP (1<<2)
#define CH7xxx_INPUT_CLOCK 0x1d
#define CH7xxx_GPIO 0x1e
#define CH7xxx_GPIO_HPIR (1<<3)
#define CH7xxx_IDF 0x1f
 
#define CH7xxx_IDF_HSP (1<<3)
#define CH7xxx_IDF_VSP (1<<4)
 
#define CH7xxx_CONNECTION_DETECT 0x20
#define CH7xxx_CDET_DVI (1<<5)
 
#define CH7301_DAC_CNTL 0x21
#define CH7301_HOTPLUG 0x23
#define CH7xxx_TCTL 0x31
#define CH7xxx_TVCO 0x32
#define CH7xxx_TPCP 0x33
#define CH7xxx_TPD 0x34
#define CH7xxx_TPVT 0x35
#define CH7xxx_TLPF 0x36
#define CH7xxx_TCT 0x37
#define CH7301_TEST_PATTERN 0x48
 
#define CH7xxx_PM 0x49
#define CH7xxx_PM_FPD (1<<0)
#define CH7301_PM_DACPD0 (1<<1)
#define CH7301_PM_DACPD1 (1<<2)
#define CH7301_PM_DACPD2 (1<<3)
#define CH7xxx_PM_DVIL (1<<6)
#define CH7xxx_PM_DVIP (1<<7)
 
#define CH7301_SYNC_POLARITY 0x56
#define CH7301_SYNC_RGB_YUV (1<<0)
#define CH7301_SYNC_POL_DVI (1<<5)
 
/** @file
* driver for the Chrontel 7xxx DVI chip over DVO.
*/
 
static struct ch7xxx_id_struct {
uint8_t vid;
char *name;
} ch7xxx_ids[] = {
{ CH7011_VID, "CH7011" },
{ CH7010B_VID, "CH7010B" },
{ CH7009A_VID, "CH7009A" },
{ CH7009B_VID, "CH7009B" },
{ CH7301_VID, "CH7301" },
};
 
static struct ch7xxx_did_struct {
uint8_t did;
char *name;
} ch7xxx_dids[] = {
{ CH7xxx_DID, "CH7XXX" },
{ CH7010_DID, "CH7010B" },
};
 
struct ch7xxx_priv {
bool quiet;
};
 
static char *ch7xxx_get_id(uint8_t vid)
{
int i;
 
for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
if (ch7xxx_ids[i].vid == vid)
return ch7xxx_ids[i].name;
}
 
return NULL;
}
 
static char *ch7xxx_get_did(uint8_t did)
{
int i;
 
for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
if (ch7xxx_dids[i].did == did)
return ch7xxx_dids[i].name;
}
 
return NULL;
}
 
/** Reads an 8 bit register */
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
{
struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
struct i2c_adapter *adapter = dvo->i2c_bus;
u8 out_buf[2];
u8 in_buf[2];
 
struct i2c_msg msgs[] = {
{
.addr = dvo->slave_addr,
.flags = 0,
.len = 1,
.buf = out_buf,
},
{
.addr = dvo->slave_addr,
.flags = I2C_M_RD,
.len = 1,
.buf = in_buf,
}
};
 
out_buf[0] = addr;
out_buf[1] = 0;
 
if (i2c_transfer(adapter, msgs, 2) == 2) {
*ch = in_buf[0];
return true;
}
 
if (!ch7xxx->quiet) {
DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
addr, adapter->name, dvo->slave_addr);
}
return false;
}
 
/** Writes an 8 bit register */
static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
{
struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
struct i2c_adapter *adapter = dvo->i2c_bus;
uint8_t out_buf[2];
struct i2c_msg msg = {
.addr = dvo->slave_addr,
.flags = 0,
.len = 2,
.buf = out_buf,
};
 
out_buf[0] = addr;
out_buf[1] = ch;
 
if (i2c_transfer(adapter, &msg, 1) == 1)
return true;
 
if (!ch7xxx->quiet) {
DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, adapter->name, dvo->slave_addr);
}
 
return false;
}
 
static bool ch7xxx_init(struct intel_dvo_device *dvo,
struct i2c_adapter *adapter)
{
/* this will detect the CH7xxx chip on the specified i2c bus */
struct ch7xxx_priv *ch7xxx;
uint8_t vendor, device;
char *name, *devid;
 
ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
if (ch7xxx == NULL)
return false;
 
dvo->i2c_bus = adapter;
dvo->dev_priv = ch7xxx;
ch7xxx->quiet = true;
 
if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
goto out;
 
name = ch7xxx_get_id(vendor);
if (!name) {
DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
"slave %d.\n",
vendor, adapter->name, dvo->slave_addr);
goto out;
}
 
 
if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
goto out;
 
devid = ch7xxx_get_did(device);
if (!devid) {
DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
"slave %d.\n",
vendor, adapter->name, dvo->slave_addr);
goto out;
}
 
ch7xxx->quiet = false;
DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
name, vendor, device);
return true;
out:
kfree(ch7xxx);
return false;
}
 
static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
{
uint8_t cdet, orig_pm, pm;
 
ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
 
pm = orig_pm;
pm &= ~CH7xxx_PM_FPD;
pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
 
ch7xxx_writeb(dvo, CH7xxx_PM, pm);
 
ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
 
ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
 
if (cdet & CH7xxx_CDET_DVI)
return connector_status_connected;
return connector_status_disconnected;
}
 
static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
struct drm_display_mode *mode)
{
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
 
return MODE_OK;
}
 
static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
uint8_t tvco, tpcp, tpd, tlpf, idf;
 
if (mode->clock <= 65000) {
tvco = 0x23;
tpcp = 0x08;
tpd = 0x16;
tlpf = 0x60;
} else {
tvco = 0x2d;
tpcp = 0x06;
tpd = 0x26;
tlpf = 0xa0;
}
 
ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
 
ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
 
idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
idf |= CH7xxx_IDF_HSP;
 
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
idf |= CH7xxx_IDF_VSP;
 
ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
}
 
/* set the CH7xxx power state */
static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
{
if (enable)
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
else
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
}
 
static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)
{
u8 val;
 
ch7xxx_readb(dvo, CH7xxx_PM, &val);
 
if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
return true;
else
return false;
}
 
static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
{
int i;
 
for (i = 0; i < CH7xxx_NUM_REGS; i++) {
uint8_t val;
if ((i % 8) == 0)
DRM_DEBUG_KMS("\n %02X: ", i);
ch7xxx_readb(dvo, i, &val);
DRM_DEBUG_KMS("%02X ", val);
}
}
 
static void ch7xxx_destroy(struct intel_dvo_device *dvo)
{
struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
 
if (ch7xxx) {
kfree(ch7xxx);
dvo->dev_priv = NULL;
}
}
 
struct intel_dvo_dev_ops ch7xxx_ops = {
.init = ch7xxx_init,
.detect = ch7xxx_detect,
.mode_valid = ch7xxx_mode_valid,
.mode_set = ch7xxx_mode_set,
.dpms = ch7xxx_dpms,
.get_hw_state = ch7xxx_get_hw_state,
.dump_regs = ch7xxx_dump_regs,
.destroy = ch7xxx_destroy,
};
/contrib/toolchain/binutils/libiberty/filename_cmp.c
24,8 → 24,13
#include <string.h>
#endif
 
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
 
#include "filenames.h"
#include "safe-ctype.h"
#include "libiberty.h"
 
/*
 
190,3 → 195,27
/* The casts are for -Wc++-compat. */
return filename_cmp ((const char *) s1, (const char *) s2) == 0;
}
 
/*
 
@deftypefn Extension int canonical_filename_eq (const char *@var{a}, const char *@var{b})
 
Return non-zero if file names @var{a} and @var{b} are equivalent.
This function compares the canonical versions of the filenames as returned by
@code{lrealpath()}, so that so that different file names pointing to the same
underlying file are treated as being identical.
 
@end deftypefn
 
*/
 
int
canonical_filename_eq (const char * a, const char * b)
{
char * ca = lrealpath(a);
char * cb = lrealpath(b);
int res = filename_eq (ca, cb);
free (ca);
free (cb);
return res;
}
/contrib/toolchain/binutils/libiberty/floatformat.c
1,5 → 1,5
/* IEEE floating point support routines, for GDB, the GNU Debugger.
Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010, 2012
Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010, 2012, 2015
Free Software Foundation, Inc.
 
This file is part of GDB.
19,7 → 19,9
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
 
/* This is needed to pick up the NAN macro on some systems. */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
 
#ifdef HAVE_CONFIG_H
#include "config.h"
/contrib/toolchain/binutils/libiberty/libiberty.ar
0,0 → 1,8
crs libiberty.a alloca.o argv.o asprintf.o bcmp.o bcopy.o bzero.o choose-temp.o concat.o cp-demangle.o cp-demint.o
cplus-dem.o crc32.o dwarfnames.o dyn-string.o fdmatch.o ffs.o fibheap.o filename_cmp.o floatformat.o fnmatch.o
fopen_unlocked.o getopt.o getopt1.o getpwd.o getruntime.o hashtab.o hex.o index.o insque.o lbasename.o lrealpath.o
make-relative-prefix.o make-temp-file.o md5.o memmem.o mempcpy.o objalloc.o obstack.o partition.o physmem.o random.o
regex.o rindex.o safe-ctype.o setenv.o setproctitle.o sha1.o sigsetmask.o simple-object.o simple-object-coff.o
simple-object-elf.o simple-object-mach-o.o simple-object-xcoff.o sort.o spaces.o splay-tree.o stack-limit.o stpcpy.o
stpncpy.o strcasecmp.o strerror.o strncasecmp.o strndup.o strnlen.o strverscmp.o timeval-utils.o unlink-if-ordinary.o
vasprintf.o xatexit.o xexit.o xmalloc.o xmemdup.o xstrdup.o xstrerror.o xstrndup.o
/contrib/toolchain/binutils/libiberty/make-temp-file.c
93,7 → 93,7
 
/*
 
@deftypefn Replacement char* choose_tmpdir ()
@deftypefn Replacement const char* choose_tmpdir ()
 
Returns a pointer to a directory path suitable for creating temporary
files in.
102,7 → 102,7
 
*/
 
char *
const char *
choose_tmpdir (void)
{
return "/tmp0/1/";
/contrib/toolchain/binutils/libiberty/mkstemps.c
35,6 → 35,8
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#elif HAVE_TIME_H
#include <time.h>
#endif
#include "ansidecl.h"
 
/contrib/toolchain/binutils/libiberty/obstack.c
1,36 → 1,33
/* obstack.c - subroutines used implicitly by object stack macros
Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
Copyright (C) 1988-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
 
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
USA. */
 
#ifdef HAVE_CONFIG_H
#ifdef _LIBC
# include <obstack.h>
#else
#include <config.h>
# include "obstack.h"
#endif
 
#include "obstack.h"
/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in
obstack.h must be incremented whenever callers compiled using an old
obstack.h can no longer properly call the functions in this file. */
 
/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
incremented whenever callers compiled using an old obstack.h can no
longer properly call the functions in this obstack.c. */
#define OBSTACK_INTERFACE_VERSION 1
 
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself, and the installed library
supports the same library interface we do. This code is part of the GNU
37,115 → 34,90
C Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object
program understand 'configure --with-gnu-libc' and omit the object
files, it is simpler to just do this in the source for each such file. */
 
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
#include <gnu-versions.h>
#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
#define ELIDE_CODE
# if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \
|| (_GNU_OBSTACK_INTERFACE_VERSION == 1 \
&& _OBSTACK_INTERFACE_VERSION == 2 \
&& defined SIZEOF_INT && defined SIZEOF_SIZE_T \
&& SIZEOF_INT == SIZEOF_SIZE_T))
# define _OBSTACK_ELIDE_CODE
#endif
#endif
 
#ifndef _OBSTACK_ELIDE_CODE
/* If GCC, or if an oddball (testing?) host that #defines __alignof__,
use the already-supplied __alignof__. Otherwise, this must be Gnulib
(as glibc assumes GCC); defer to Gnulib's alignof_type. */
# if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__
# if defined __cplusplus
template <class type> struct alignof_helper { char __slot1; type __slot2; };
# define __alignof__(type) offsetof (alignof_helper<type>, __slot2)
# else
# define __alignof__(type) \
offsetof (struct { char __slot1; type __slot2; }, __slot2)
# endif
# endif
# include <stdlib.h>
# include <stdint.h>
 
#ifndef ELIDE_CODE
# ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
# endif
 
/* Determine default alignment. */
 
#define POINTER void *
 
/* Determine default alignment. */
struct fooalign {char x; double d;};
#define DEFAULT_ALIGNMENT \
((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
union fooround {long x; double d;};
#define DEFAULT_ROUNDING (sizeof (union fooround))
DEFAULT_ROUNDING. So we prepare for it to do that.
 
/* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work;
in such a case, redefine COPYING_UNIT to `long' (if that works)
or `char' as a last resort. */
#ifndef COPYING_UNIT
#define COPYING_UNIT int
#endif
DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h. */
#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \
MAX (__alignof__ (uintmax_t), \
__alignof__ (void *)))
#define DEFAULT_ROUNDING MAX (sizeof (long double), \
MAX (sizeof (uintmax_t), \
sizeof (void *)))
 
/* Call functions with either the traditional malloc/free calling
interface, or the mmalloc/mfree interface (that adds an extra first
argument), based on the value of use_extra_arg. */
 
/* The functions allocating more room by calling `obstack_chunk_alloc'
jump to the handler pointed to by `obstack_alloc_failed_handler'.
This variable by default points to the internal function
`print_and_abort'. */
static void print_and_abort (void);
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
static void *
call_chunkfun (struct obstack *h, size_t size)
{
if (h->use_extra_arg)
return h->chunkfun.extra (h->extra_arg, size);
else
return h->chunkfun.plain (size);
}
 
/* Exit value used when `print_and_abort' is used. */
#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
int obstack_exit_failure = EXIT_FAILURE;
static void
call_freefun (struct obstack *h, void *old_chunk)
{
if (h->use_extra_arg)
h->freefun.extra (h->extra_arg, old_chunk);
else
h->freefun.plain (old_chunk);
}
 
/* The non-GNU-C macros copy the obstack into this global variable
to avoid multiple evaluation. */
 
struct obstack *_obstack;
 
/* Define a macro that either calls functions with the traditional malloc/free
calling interface, or calls functions with the mmalloc/mfree interface
(that adds an extra first argument), based on the state of use_extra_arg.
For free, do not use ?:, since some compilers, like the MIPS compilers,
do not allow (expr) ? void : void. */
 
#if defined (__STDC__) && __STDC__
#define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
 
#define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
else \
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
} while (0)
#else
#define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
 
#define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
else \
(*(void (*) ()) (h)->freefun) ((old_chunk)); \
} while (0)
#endif
 
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
and FREEFUN the function to free them.
 
Return nonzero if successful, zero if out of memory.
To recover from an out of memory error,
free up some memory, then call this again. */
Return nonzero if successful, calls obstack_alloc_failed_handler if
allocation fails. */
 
int
_obstack_begin (struct obstack *h, int size, int alignment,
POINTER (*chunkfun) (long), void (*freefun) (void *))
static int
_obstack_begin_worker (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
{
register struct _obstack_chunk *chunk; /* points to new chunk */
struct _obstack_chunk *chunk; /* points to new chunk */
 
if (alignment == 0)
alignment = (int) DEFAULT_ALIGNMENT;
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
163,18 → 135,16
size = 4096 - extra;
}
 
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
 
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
h->next_free = h->object_base = chunk->contents;
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
h->chunk = chunk;
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1);
h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
183,49 → 153,29
}
 
int
_obstack_begin_1 (struct obstack *h, int size, int alignment,
POINTER (*chunkfun) (POINTER, long),
void (*freefun) (POINTER, POINTER), POINTER arg)
_obstack_begin (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (size_t),
void (*freefun) (void *))
{
register struct _obstack_chunk *chunk; /* points to new chunk */
h->chunkfun.plain = chunkfun;
h->freefun.plain = freefun;
h->use_extra_arg = 0;
return _obstack_begin_worker (h, size, alignment);
}
 
if (alignment == 0)
alignment = (int) DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
int
_obstack_begin_1 (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (void *, size_t),
void (*freefun) (void *, void *),
void *arg)
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
 
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
 
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->chunkfun.extra = chunkfun;
h->freefun.extra = freefun;
h->extra_arg = arg;
h->use_extra_arg = 1;
 
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
h->next_free = h->object_base = chunk->contents;
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
h->alloc_failed = 0;
return 1;
return _obstack_begin_worker (h, size, alignment);
}
 
/* Allocate a new current chunk for the obstack *H
235,22 → 185,25
to the beginning of the new one. */
 
void
_obstack_newchunk (struct obstack *h, int length)
_obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
{
register struct _obstack_chunk *old_chunk = h->chunk;
register struct _obstack_chunk *new_chunk;
register long new_size;
register long obj_size = h->next_free - h->object_base;
register long i;
long already;
struct _obstack_chunk *old_chunk = h->chunk;
struct _obstack_chunk *new_chunk = 0;
size_t obj_size = h->next_free - h->object_base;
char *object_base;
 
/* Compute size for new chunk. */
new_size = (obj_size + length) + (obj_size >> 3) + 100;
size_t sum1 = obj_size + length;
size_t sum2 = sum1 + h->alignment_mask;
size_t new_size = sum2 + (obj_size >> 3) + 100;
if (new_size < sum2)
new_size = sum2;
if (new_size < h->chunk_size)
new_size = h->chunk_size;
 
/* Allocate and initialize the new chunk. */
new_chunk = CALL_CHUNKFUN (h, new_size);
if (obj_size <= sum1 && sum1 <= sum2)
new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler) ();
h->chunk = new_chunk;
257,36 → 210,26
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
 
/* Move the existing object to the new chunk.
Word at a time is fast and is safe if the object
is sufficiently aligned. */
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
{
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
i >= 0; i--)
((COPYING_UNIT *)new_chunk->contents)[i]
= ((COPYING_UNIT *)h->object_base)[i];
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
}
else
already = 0;
/* Copy remaining bytes one by one. */
for (i = already; i < obj_size; i++)
new_chunk->contents[i] = h->object_base[i];
/* Compute an aligned object_base in the new chunk */
object_base =
__PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
 
/* Move the existing object to the new chunk. */
memcpy (object_base, h->object_base, obj_size);
 
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */
if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
if (!h->maybe_empty_object
&& (h->object_base
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
CALL_FREEFUN (h, old_chunk);
call_freefun (h, old_chunk);
}
 
h->object_base = new_chunk->contents;
h->object_base = object_base;
h->next_free = h->object_base + obj_size;
/* The new chunk certainly contains no empty object yet. */
h->maybe_empty_object = 0;
298,19 → 241,19
 
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
obstack.h because it is just for debugging. */
int _obstack_allocated_p (struct obstack *h, POINTER obj);
int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
 
int
_obstack_allocated_p (struct obstack *h, POINTER obj)
_obstack_allocated_p (struct obstack *h, void *obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
 
lp = (h)->chunk;
/* We use >= rather than > since the object cannot be exactly at
the beginning of the chunk but might be an empty object exactly
at the end of an adjacent chunk. */
while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
lp = plp;
321,25 → 264,20
/* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */
 
#undef obstack_free
 
/* This function has two names with identical definitions.
This is the first one, called from non-ANSI code. */
 
void
_obstack_free (struct obstack *h, POINTER obj)
_obstack_free (struct obstack *h, void *obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
 
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
call_freefun (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
356,43 → 294,11
abort ();
}
 
/* This function is used from ANSI code. */
 
void
obstack_free (struct obstack *h, POINTER obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
 
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
{
h->object_base = h->next_free = (char *) (obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
else if (obj != 0)
/* obj is not in any of the chunks! */
abort ();
}
int
_OBSTACK_SIZE_T
_obstack_memory_used (struct obstack *h)
{
register struct _obstack_chunk* lp;
register int nbytes = 0;
struct _obstack_chunk *lp;
_OBSTACK_SIZE_T nbytes = 0;
 
for (lp = h->chunk; lp != 0; lp = lp->prev)
{
401,110 → 307,70
return nbytes;
}
# ifndef _OBSTACK_NO_ERROR_HANDLER
/* Define the error handler. */
#ifndef _
# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
# include <stdio.h>
 
/* Exit value used when 'print_and_abort' is used. */
# ifdef _LIBC
int obstack_exit_failure = EXIT_FAILURE;
# else
# ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
# endif
# define obstack_exit_failure EXIT_FAILURE
# endif
 
# if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
# include <libintl.h>
# ifndef _
# define _(Str) gettext (Str)
# define _(msgid) gettext (msgid)
# endif
# else
# define _(Str) (Str)
# ifndef _
# define _(msgid) (msgid)
# endif
#endif
 
static void
# if !(defined _Noreturn \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112))
# if ((defined __GNUC__ \
&& (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))) \
|| (defined __SUNPRO_C && __SUNPRO_C >= 0x5110))
# define _Noreturn __attribute__ ((__noreturn__))
# elif defined _MSC_VER && _MSC_VER >= 1200
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn
# endif
# endif
 
# ifdef _LIBC
# include <libio/iolibio.h>
# endif
 
static _Noreturn void
print_and_abort (void)
{
fputs (_("memory exhausted\n"), stderr);
/* Don't change any of these strings. Yes, it would be possible to add
the newline to the string and use fputs or so. But this must not
happen because the "memory exhausted" message appears in other places
like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */
# ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
# else
fprintf (stderr, "%s\n", _("memory exhausted"));
# endif
exit (obstack_exit_failure);
}
#if 0
/* These are now turned off because the applications do not use it
and it uses bcopy via obstack_grow, which causes trouble on sysV. */
 
/* Now define the functional versions of the obstack macros.
Define them to simply use the corresponding macros to do the job. */
 
/* The function names appear in parentheses in order to prevent
the macro-definitions of the names from being expanded there. */
 
POINTER (obstack_base) (struct obstack *obstack)
{
return obstack_base (obstack);
}
 
POINTER (obstack_next_free) (struct obstack *obstack)
{
return obstack_next_free (obstack);
}
 
int (obstack_object_size) (struct obstack *obstack)
{
return obstack_object_size (obstack);
}
 
int (obstack_room) (struct obstack *obstack)
{
return obstack_room (obstack);
}
 
int (obstack_make_room) (struct obstack *obstack, int length)
{
return obstack_make_room (obstack, length);
}
 
void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
{
obstack_grow (obstack, pointer, length);
}
 
void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
{
obstack_grow0 (obstack, pointer, length);
}
 
void (obstack_1grow) (struct obstack *obstack, int character)
{
obstack_1grow (obstack, character);
}
 
void (obstack_blank) (struct obstack *obstack, int length)
{
obstack_blank (obstack, length);
}
 
void (obstack_1grow_fast) (struct obstack *obstack, int character)
{
obstack_1grow_fast (obstack, character);
}
 
void (obstack_blank_fast) (struct obstack *obstack, int length)
{
obstack_blank_fast (obstack, length);
}
 
POINTER (obstack_finish) (struct obstack *obstack)
{
return obstack_finish (obstack);
}
 
POINTER (obstack_alloc) (struct obstack *obstack, int length)
{
return obstack_alloc (obstack, length);
}
 
POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
{
return obstack_copy (obstack, pointer, length);
}
 
POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
{
return obstack_copy0 (obstack, pointer, length);
}
 
#endif /* 0 */
 
#endif /* !ELIDE_CODE */
/* The functions allocating more room by calling 'obstack_chunk_alloc'
jump to the handler pointed to by 'obstack_alloc_failed_handler'.
This can be set to a user defined function which should either
abort gracefully or use longjump - but shouldn't return. This
variable by default points to the internal function
'print_and_abort'. */
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
# endif /* !_OBSTACK_NO_ERROR_HANDLER */
#endif /* !_OBSTACK_ELIDE_CODE */
/contrib/toolchain/binutils/libiberty/pex-common.h
104,7 → 104,7
/* Open file NAME for writing. If BINARY is non-zero, open in
binary mode. Return >= 0 on success, -1 on error. */
int (*open_write) (struct pex_obj *, const char */* name */,
int /* binary */);
int /* binary */, int /* append */);
/* Execute a child process. FLAGS, EXECUTABLE, ARGV, ERR are from
pex_run. IN, OUT, ERRDES, TOCLOSE are all descriptors, from
open_read, open_write, or pipe, or they are one of STDIN_FILE_NO,
/contrib/toolchain/binutils/libiberty/regex.c
151,7 → 151,7
# include <string.h>
# ifndef bzero
# ifndef _LIBC
# define bzero(s, n) (memset (s, '\0', n), (s))
# define bzero(s, n) ((void) memset (s, '\0', n))
# else
# define bzero(s, n) __bzero (s, n)
# endif
8093,12 → 8093,12
#if defined HAVE_MEMPCPY || defined _LIBC
*((char *) mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
#else
memcpy (errbuf, msg, errbuf_size - 1);
(void) memcpy (errbuf, msg, errbuf_size - 1);
errbuf[errbuf_size - 1] = 0;
#endif
}
else
memcpy (errbuf, msg, msg_size);
(void) memcpy (errbuf, msg, msg_size);
}
 
return msg_size;
/contrib/toolchain/binutils/libiberty/sigsetmask.c
15,7 → 15,6
 
*/
 
#define _POSIX_SOURCE
#include <ansidecl.h>
/* Including <sys/types.h> seems to be needed by ISC. */
#include <sys/types.h>
/contrib/toolchain/binutils/libiberty/simple-object-elf.c
698,6 → 698,7
unsigned char buf[sizeof (Elf64_External_Ehdr)];
simple_object_write_section *section;
unsigned int shnum;
unsigned int shstrndx;
 
fns = attrs->type_functions;
cl = attrs->ei_class;
743,9 → 744,17
(cl == ELFCLASS32
? sizeof (Elf32_External_Shdr)
: sizeof (Elf64_External_Shdr)));
ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, shnum);
ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half,
shnum == 0 ? 0 : shnum - 1);
ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half,
shnum >= SHN_LORESERVE ? 0 : shnum);
if (shnum == 0)
shstrndx = 0;
else
{
shstrndx = shnum - 1;
if (shstrndx >= SHN_LORESERVE)
shstrndx = SHN_XINDEX;
}
ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx);
 
return simple_object_internal_write (descriptor, 0, buf, ehdr_size,
errmsg, err);
758,8 → 767,8
off_t offset, unsigned int sh_name,
unsigned int sh_type, unsigned int sh_flags,
unsigned int sh_offset, unsigned int sh_size,
unsigned int sh_addralign, const char **errmsg,
int *err)
unsigned int sh_link, unsigned int sh_addralign,
const char **errmsg, int *err)
{
struct simple_object_elf_attributes *attrs =
(struct simple_object_elf_attributes *) sobj->data;
781,7 → 790,7
ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags);
ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset);
ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size);
/* sh_link left as zero. */
ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link);
/* sh_info left as zero. */
ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign);
/* sh_entsize left as zero. */
812,6 → 821,8
unsigned int shnum;
size_t shdr_offset;
size_t sh_offset;
unsigned int first_sh_size;
unsigned int first_sh_link;
size_t sh_name;
unsigned char zero;
 
842,8 → 853,17
shdr_offset = ehdr_size;
sh_offset = shdr_offset + shnum * shdr_size;
 
if (shnum < SHN_LORESERVE)
first_sh_size = 0;
else
first_sh_size = shnum;
if (shnum - 1 < SHN_LORESERVE)
first_sh_link = 0;
else
first_sh_link = shnum - 1;
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
0, 0, 0, 0, 0, 0, &errmsg, err))
0, 0, 0, 0, first_sh_size, first_sh_link,
0, &errmsg, err))
return errmsg;
 
shdr_offset += shdr_size;
887,7 → 907,7
 
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
sh_name, SHT_PROGBITS, 0, sh_offset,
sh_size, 1U << section->align,
sh_size, 0, 1U << section->align,
&errmsg, err))
return errmsg;
 
898,7 → 918,7
 
if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset,
sh_name, SHT_STRTAB, 0, sh_offset,
sh_name + strlen (".shstrtab") + 1,
sh_name + strlen (".shstrtab") + 1, 0,
1, &errmsg, err))
return errmsg;
 
/contrib/toolchain/binutils/libiberty/simple-object.c
63,8 → 63,6
unsigned char *buffer, size_t size,
const char **errmsg, int *err)
{
ssize_t got;
 
if (lseek (descriptor, offset, SEEK_SET) < 0)
{
*errmsg = "lseek";
72,15 → 70,26
return 0;
}
 
got = read (descriptor, buffer, size);
if (got < 0)
do
{
ssize_t got = read (descriptor, buffer, size);
if (got == 0)
break;
else if (got > 0)
{
buffer += got;
size -= got;
}
else if (errno != EINTR)
{
*errmsg = "read";
*err = errno;
return 0;
}
}
while (size > 0);
 
if ((size_t) got < size)
if (size > 0)
{
*errmsg = "file too short";
*err = 0;
98,8 → 107,6
const unsigned char *buffer, size_t size,
const char **errmsg, int *err)
{
ssize_t wrote;
 
if (lseek (descriptor, offset, SEEK_SET) < 0)
{
*errmsg = "lseek";
107,15 → 114,26
return 0;
}
 
wrote = write (descriptor, buffer, size);
if (wrote < 0)
do
{
ssize_t wrote = write (descriptor, buffer, size);
if (wrote == 0)
break;
else if (wrote > 0)
{
buffer += wrote;
size -= wrote;
}
else if (errno != EINTR)
{
*errmsg = "write";
*err = errno;
return 0;
}
}
while (size > 0);
 
if ((size_t) wrote < size)
if (size > 0)
{
*errmsg = "short write";
*err = 0;
/contrib/toolchain/binutils/libiberty/strerror.c
469,8 → 469,13
 
#else
 
 
#ifndef sys_nerr
extern int sys_nerr;
#endif
#ifndef sys_errlist
extern char *sys_errlist[];
#endif
 
#endif
 
/contrib/toolchain/binutils/libiberty/vasprintf.c
1,6 → 1,6
/* Like vsprintf but provides a pointer to malloc'd storage, which must
be freed by the caller.
Copyright (C) 1994, 2003, 2011 Free Software Foundation, Inc.
Copyright (C) 1994, 2003, 2011, 2013 Free Software Foundation, Inc.
 
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
14,9 → 14,9
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
License along with libiberty; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
Floor, Boston, MA 02110-1301, USA. */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
33,10 → 33,10
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern unsigned long strtoul ();
extern PTR malloc ();
#endif
#include "libiberty.h"
#include "vprintf-support.h"
 
#ifdef TEST
int global_total_width;
64,81 → 64,7
static int
int_vasprintf (char **result, const char *format, va_list args)
{
const char *p = format;
/* Add one to make sure that it is never zero, which might cause malloc
to return NULL. */
int total_width = strlen (format) + 1;
va_list ap;
 
#ifdef va_copy
va_copy (ap, args);
#else
memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list));
#endif
 
while (*p != '\0')
{
if (*p++ == '%')
{
while (strchr ("-+ #0", *p))
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
if (*p == '.')
{
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
}
while (strchr ("hlL", *p))
++p;
/* Should be big enough for any format specifier except %s and floats. */
total_width += 30;
switch (*p)
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'c':
(void) va_arg (ap, int);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
(void) va_arg (ap, double);
/* Since an ieee double can have an exponent of 307, we'll
make the buffer wide enough to cover the gross case. */
total_width += 307;
break;
case 's':
total_width += strlen (va_arg (ap, char *));
break;
case 'p':
case 'n':
(void) va_arg (ap, char *);
break;
}
p++;
}
}
#ifdef va_copy
va_end (ap);
#endif
int total_width = libiberty_vprintf_buffer_size (format, args);
#ifdef TEST
global_total_width = total_width;
#endif
165,10 → 91,10
checkit (const char *format, ...)
{
char *result;
VA_OPEN (args, format);
VA_FIXEDARG (args, const char *, format);
va_list args;
va_start (args, format);
vasprintf (&result, format, args);
VA_CLOSE (args);
va_end (args);
 
if (strlen (result) < (size_t) global_total_width)
printf ("PASS: ");
/contrib/toolchain/binutils/libiberty/vprintf-support.c
0,0 → 1,119
/* Estimate the length of the string generated by a vprintf-like
function. Used by vasprintf and xvasprintf.
Copyright (C) 1994, 2003, 2011, 2013, 2014 Free Software Foundation, Inc.
 
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
Floor, Boston, MA 02110-1301, USA. */
 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ansidecl.h>
#include <stdarg.h>
#if !defined (va_copy) && defined (__va_copy)
# define va_copy(d,s) __va_copy((d),(s))
#endif
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern unsigned long strtoul ();
#endif
#include "libiberty.h"
 
int
libiberty_vprintf_buffer_size (const char *format, va_list args)
{
const char *p = format;
/* Add one to make sure that it is never zero, which might cause malloc
to return NULL. */
int total_width = strlen (format) + 1;
va_list ap;
 
#ifdef va_copy
va_copy (ap, args);
#else
memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list));
#endif
 
while (*p != '\0')
{
if (*p++ == '%')
{
while (strchr ("-+ #0", *p))
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
if (*p == '.')
{
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char **) &p, 10);
}
while (strchr ("hlL", *p))
++p;
/* Should be big enough for any format specifier except %s and floats. */
total_width += 30;
switch (*p)
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'c':
(void) va_arg (ap, int);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
(void) va_arg (ap, double);
/* Since an ieee double can have an exponent of 307, we'll
make the buffer wide enough to cover the gross case. */
total_width += 307;
break;
case 's':
total_width += strlen (va_arg (ap, char *));
break;
case 'p':
case 'n':
(void) va_arg (ap, char *);
break;
}
p++;
}
}
#ifdef va_copy
va_end (ap);
#endif
return total_width;
}
/contrib/toolchain/binutils/libiberty/vprintf-support.h
0,0 → 1,22
/* Estimate the length of the string generated by a vprintf-like
function. Use by vasprintf and xvasprintf.
Copyright (C) 1994, 2003, 2011, 2013, 2014 Free Software Foundation, Inc.
 
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
Floor, Boston, MA 02110-1301, USA. */
 
 
extern int libiberty_vprintf_buffer_size (const char *, va_list);