/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); |