diff options
Diffstat (limited to 'gdb/valprint.c')
-rw-r--r-- | gdb/valprint.c | 1393 |
1 files changed, 0 insertions, 1393 deletions
diff --git a/gdb/valprint.c b/gdb/valprint.c deleted file mode 100644 index 2bf1f88..0000000 --- a/gdb/valprint.c +++ /dev/null @@ -1,1393 +0,0 @@ -/* Print values for GNU debugger gdb. - Copyright (C) 1986, 1988, 1989 Free Software Foundation, Inc. - -This file is part of GDB. - -GDB 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 1, or (at your option) -any later version. - -GDB 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 GDB; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> -#include "defs.h" -#include "param.h" -#include "symtab.h" -#include "value.h" - -/* GNU software is only expected to run on systems with 32-bit integers. */ -#define UINT_MAX 0xffffffff - -/* Maximum number of chars to print for a string pointer value - or vector contents, or UINT_MAX for no limit. */ - -static unsigned int print_max; - -static void type_print_varspec_suffix (); -static void type_print_varspec_prefix (); -static void type_print_base (); -static void type_print_method_args (); - - -char **unsigned_type_table; -char **signed_type_table; -char **float_type_table; - - -/* Print repeat counts if there are more than this - many repetitions of an element in an array. */ -#define REPEAT_COUNT_THRESHOLD 10 - -/* Print the character string STRING, printing at most LENGTH characters. - Printing stops early if the number hits print_max; repeat counts - are printed as appropriate. Print ellipses at the end if we - had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */ - -void -print_string (stream, string, length, force_ellipses) - FILE *stream; - char *string; - unsigned int length; - int force_ellipses; -{ - register unsigned int i; - unsigned int things_printed = 0; - int in_quotes = 0; - int need_comma = 0; - - if (length == 0) - { - fputs_filtered ("\"\"", stdout); - return; - } - - for (i = 0; i < length && things_printed < print_max; ++i) - { - /* Position of the character we are examining - to see whether it is repeated. */ - unsigned int rep1; - /* Number of repititions we have detected so far. */ - unsigned int reps; - - QUIT; - - if (need_comma) - { - fputs_filtered (", ", stream); - need_comma = 0; - } - - rep1 = i + 1; - reps = 1; - while (rep1 < length && string[rep1] == string[i]) - { - ++rep1; - ++reps; - } - - if (reps > REPEAT_COUNT_THRESHOLD) - { - if (in_quotes) - { - fputs_filtered ("\", ", stream); - in_quotes = 0; - } - fputs_filtered ("'", stream); - printchar (string[i], stream, '\''); - fprintf_filtered (stream, "' <repeats %u times>", reps); - i = rep1 - 1; - things_printed += REPEAT_COUNT_THRESHOLD; - need_comma = 1; - } - else - { - if (!in_quotes) - { - fputs_filtered ("\"", stream); - in_quotes = 1; - } - printchar (string[i], stream, '"'); - ++things_printed; - } - } - - /* Terminate the quotes if necessary. */ - if (in_quotes) - fputs_filtered ("\"", stream); - - if (force_ellipses || i < length) - fputs_filtered ("...", stream); -} - -/* Print the value VAL in C-ish syntax on stream STREAM. - FORMAT is a format-letter, or 0 for print in natural format of data type. - If the object printed is a string pointer, returns - the number of string bytes printed. */ - -int -value_print (val, stream, format, pretty) - value val; - FILE *stream; - char format; - enum val_prettyprint pretty; -{ - register unsigned int i, n, typelen; - - /* A "repeated" value really contains several values in a row. - They are made by the @ operator. - Print such values as if they were arrays. */ - - if (VALUE_REPEATED (val)) - { - n = VALUE_REPETITIONS (val); - typelen = TYPE_LENGTH (VALUE_TYPE (val)); - fprintf_filtered (stream, "{"); - /* Print arrays of characters using string syntax. */ - if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT - && format == 0) - print_string (stream, VALUE_CONTENTS (val), n, 0); - else - { - unsigned int things_printed = 0; - - for (i = 0; i < n && things_printed < print_max; i++) - { - /* Position of the array element we are examining to see - whether it is repeated. */ - unsigned int rep1; - /* Number of repititions we have detected so far. */ - unsigned int reps; - - if (i != 0) - fprintf_filtered (stream, ", "); - - rep1 = i + 1; - reps = 1; - while (rep1 < n - && !bcmp (VALUE_CONTENTS (val) + typelen * i, - VALUE_CONTENTS (val) + typelen * rep1, typelen)) - { - ++reps; - ++rep1; - } - - if (reps > REPEAT_COUNT_THRESHOLD) - { - val_print (VALUE_TYPE (val), - VALUE_CONTENTS (val) + typelen * i, - VALUE_ADDRESS (val) + typelen * i, - stream, format, 1, 0, pretty); - fprintf (stream, " <repeats %u times>", reps); - i = rep1 - 1; - things_printed += REPEAT_COUNT_THRESHOLD; - } - else - { - val_print (VALUE_TYPE (val), - VALUE_CONTENTS (val) + typelen * i, - VALUE_ADDRESS (val) + typelen * i, - stream, format, 1, 0, pretty); - things_printed++; - } - } - if (i < n) - fprintf_filtered (stream, "..."); - } - fprintf_filtered (stream, "}"); - return n * typelen; - } - else - { - /* If it is a pointer, indicate what it points to. - - Print type also if it is a reference. - - C++: if it is a member pointer, we will take care - of that when we print it. */ - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR - || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF) - { - fprintf_filtered (stream, "("); - type_print (VALUE_TYPE (val), "", stream, -1); - fprintf_filtered (stream, ") "); - - /* If this is a function pointer, try to print what - function it is pointing to by name. */ - if (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (val))) - == TYPE_CODE_FUNC) - { - print_address (((int *) VALUE_CONTENTS (val))[0], stream); - /* Return value is irrelevant except for string pointers. */ - return 0; - } - } - return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), - VALUE_ADDRESS (val), stream, format, 1, 0, pretty); - } -} - -static int prettyprint; /* Controls prettyprinting of structures. */ -int unionprint; /* Controls printing of nested unions. */ - -/* Print data of type TYPE located at VALADDR (within GDB), - which came from the inferior at address ADDRESS, - onto stdio stream STREAM according to FORMAT - (a letter or 0 for natural format). - - If the data are a string pointer, returns the number of - sting characters printed. - - if DEREF_REF is nonzero, then dereference references, - otherwise just print them like pointers. - - The PRETTY parameter controls prettyprinting. */ - -int -val_print (type, valaddr, address, stream, format, - deref_ref, recurse, pretty) - struct type *type; - char *valaddr; - CORE_ADDR address; - FILE *stream; - char format; - int deref_ref; - int recurse; - enum val_prettyprint pretty; -{ - register unsigned int i; - int len, n_baseclasses; - struct type *elttype; - int eltlen; - LONGEST val; - unsigned char c; - - if (pretty == Val_pretty_default) - { - pretty = prettyprint ? Val_prettyprint : Val_no_prettyprint; - } - - QUIT; - - if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) - { - fprintf_filtered (stream, "<Type not defined in this context>"); - fflush (stream); - return 0; - } - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (TYPE_LENGTH (type) >= 0 - && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) - { - elttype = TYPE_TARGET_TYPE (type); - eltlen = TYPE_LENGTH (elttype); - len = TYPE_LENGTH (type) / eltlen; - fprintf_filtered (stream, "{"); - /* For an array of chars, print with string syntax. */ - if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT - && format == 0) - print_string (stream, valaddr, len, 0); - else - { - unsigned int things_printed = 0; - - for (i = 0; i < len && things_printed < print_max; i++) - { - /* Position of the array element we are examining to see - whether it is repeated. */ - unsigned int rep1; - /* Number of repititions we have detected so far. */ - unsigned int reps; - - if (i > 0) - fprintf_filtered (stream, ", "); - - rep1 = i + 1; - reps = 1; - while (rep1 < len - && !bcmp (valaddr + i * eltlen, - valaddr + rep1 * eltlen, eltlen)) - { - ++reps; - ++rep1; - } - - if (reps > REPEAT_COUNT_THRESHOLD) - { - val_print (elttype, valaddr + i * eltlen, - 0, stream, format, deref_ref, - recurse + 1, pretty); - fprintf_filtered (stream, " <repeats %u times>", reps); - i = rep1 - 1; - things_printed += REPEAT_COUNT_THRESHOLD; - } - else - { - val_print (elttype, valaddr + i * eltlen, - 0, stream, format, deref_ref, - recurse + 1, pretty); - things_printed++; - } - } - if (i < len) - fprintf_filtered (stream, "..."); - } - fprintf_filtered (stream, "}"); - break; - } - /* Array of unspecified length: treat like pointer to first elt. */ - valaddr = (char *) &address; - - case TYPE_CODE_PTR: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD) - { - struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)); - struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)); - struct fn_field *f; - int j, len2; - char *kind = ""; - - val = unpack_long (builtin_type_int, valaddr); - if (val < 128) - { - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (TYPE_FN_FIELD_VOFFSET (f, j) == val) - { - kind = "virtual"; - goto common; - } - } - } - } - else - { - struct symbol *sym = find_pc_function ((CORE_ADDR) val); - if (sym == 0) - error ("invalid pointer to member function"); - len = TYPE_NFN_FIELDS (domain); - for (i = 0; i < len; i++) - { - f = TYPE_FN_FIELDLIST1 (domain, i); - len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); - - for (j = 0; j < len2; j++) - { - QUIT; - if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) - goto common; - } - } - } - common: - if (i < len) - { - fprintf_filtered (stream, "&"); - type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); - fprintf (stream, kind); - if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' - && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", - TYPE_FN_FIELDLIST_NAME (domain, i), 0, stream); - else - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j), "", - TYPE_FN_FIELDLIST_NAME (domain, i), 0, stream); - break; - } - fprintf_filtered (stream, "("); - type_print (type, "", stream, -1); - fprintf_filtered (stream, ") %d", (int) val >> 3); - } - else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER) - { - struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)); - struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)); - char *kind = ""; - - /* VAL is a byte offset into the structure type DOMAIN. - Find the name of the field for that offset and - print it. */ - int extra = 0; - int bits = 0; - len = TYPE_NFIELDS (domain); - /* @@ Make VAL into bit offset */ - val = unpack_long (builtin_type_int, valaddr) << 3; - for (i = 0; i < len; i++) - { - int bitpos = TYPE_FIELD_BITPOS (domain, i); - QUIT; - if (val == bitpos) - break; - if (val < bitpos && i > 0) - { - int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target)); - /* Somehow pointing into a field. */ - i -= 1; - extra = (val - TYPE_FIELD_BITPOS (domain, i)); - if (extra & 0x3) - bits = 1; - else - extra >>= 3; - break; - } - } - if (i < len) - { - fprintf_filtered (stream, "&"); - type_print_base (domain, stream, 0, 0); - fprintf_filtered (stream, "::"); - fputs_filtered (TYPE_FIELD_NAME (domain, i), stream); - if (extra) - fprintf_filtered (stream, " + %d bytes", extra); - if (bits) - fprintf_filtered (stream, " (offset in bits)"); - break; - } - fprintf_filtered (stream, "%d", val >> 3); - } - else - { - fprintf_filtered (stream, "0x%x", * (int *) valaddr); - /* For a pointer to char or unsigned char, - also print the string pointed to, unless pointer is null. */ - - /* For an array of chars, print with string syntax. */ - elttype = TYPE_TARGET_TYPE (type); - i = 0; /* Number of characters printed. */ - if (TYPE_LENGTH (elttype) == 1 - && TYPE_CODE (elttype) == TYPE_CODE_INT - && format == 0 - && unpack_long (type, valaddr) != 0 - /* If print_max is UINT_MAX, the alloca below will fail. - In that case don't try to print the string. */ - && print_max < UINT_MAX) - { - fprintf_filtered (stream, " "); - - /* Get first character. */ - if (read_memory ( (CORE_ADDR) unpack_long (type, valaddr), - &c, 1)) - { - /* First address out of bounds. */ - fprintf_filtered (stream, "<Address 0x%x out of bounds>", - (* (int *) valaddr)); - break; - } - else - { - /* A real string. */ - int out_of_bounds = 0; - char *string = (char *) alloca (print_max); - - /* If the loop ends by us hitting print_max characters, - we need to have elipses at the end. */ - int force_ellipses = 1; - - /* This loop only fetches print_max characters, even - though print_string might want to print more - (with repeated characters). This is so that - we don't spend forever fetching if we print - a long string consisting of the same character - repeated. */ - while (i < print_max) - { - QUIT; - if (read_memory ((CORE_ADDR) unpack_long (type, valaddr) - + i, &c, 1)) - { - out_of_bounds = 1; - force_ellipses = 0; - break; - } - else if (c == '\0') - { - force_ellipses = 0; - break; - } - else - string[i++] = c; - } - - if (i != 0) - print_string (stream, string, i, force_ellipses); - if (out_of_bounds) - fprintf_filtered (stream, - " <Address 0x%x out of bounds>", - (*(int *) valaddr) + i); - } - - fflush (stream); - } - /* Return number of characters printed, plus one for the - terminating null if we have "reached the end". */ - return i + (print_max && i != print_max); - } - break; - - case TYPE_CODE_MEMBER: - error ("not implemented: member type in val_print"); - break; - - case TYPE_CODE_REF: - fprintf_filtered (stream, "(0x%x &) = ", * (int *) valaddr); - /* De-reference the reference. */ - if (deref_ref) - { - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF) - { - value val = value_at (TYPE_TARGET_TYPE (type), * (int *) valaddr); - val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), - VALUE_ADDRESS (val), stream, format, - deref_ref, recurse + 1, pretty); - } - else - fprintf_filtered (stream, "???"); - } - break; - - case TYPE_CODE_UNION: - if (recurse && !unionprint) - { - fprintf_filtered (stream, "{...}"); - break; - } - /* Fall through. */ - case TYPE_CODE_STRUCT: - fprintf_filtered (stream, "{"); - len = TYPE_NFIELDS (type); - n_baseclasses = TYPE_N_BASECLASSES (type); - for (i = 1; i <= n_baseclasses; i++) - { - fprintf_filtered (stream, "\n"); - if (pretty) - print_spaces_filtered (2 + 2 * recurse, stream); - fputs_filtered ("<", stream); - fputs_filtered (TYPE_NAME (TYPE_BASECLASS (type, i)), stream); - fputs_filtered ("> = ", stream); - val_print (TYPE_FIELD_TYPE (type, 0), - valaddr + TYPE_FIELD_BITPOS (type, i-1) / 8, - 0, stream, 0, 0, recurse + 1, pretty); - } - if (i > 1) { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 + 2 * recurse, stream); - fputs_filtered ("members of ", stream); - fputs_filtered (TYPE_NAME (type), stream); - fputs_filtered (": ", stream); - } - if (!len && i == 1) - fprintf_filtered (stream, "<No data fields>"); - else - { - for (i -= 1; i < len; i++) - { - if (i > n_baseclasses) fprintf_filtered (stream, ", "); - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 + 2 * recurse, stream); - } - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - fputs_filtered (" = ", stream); - /* check if static field */ - if (TYPE_FIELD_STATIC (type, i)) - { - value v; - - v = value_static_field (type, TYPE_FIELD_NAME (type, i), i); - val_print (TYPE_FIELD_TYPE (type, i), - VALUE_CONTENTS (v), 0, stream, format, - deref_ref, recurse + 1, pretty); - } - else if (TYPE_FIELD_PACKED (type, i)) - { - char *valp = (char *) & val; - union {int i; char c;} test; - test.i = 1; - if (test.c != 1) - valp += sizeof val - TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); - val = unpack_field_as_long (type, valaddr, i); - val_print (TYPE_FIELD_TYPE (type, i), valp, 0, - stream, format, deref_ref, recurse + 1, pretty); - } - else - { - val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / 8, - 0, stream, format, deref_ref, - recurse + 1, pretty); - } - } - if (pretty) - { - fprintf_filtered (stream, "\n"); - print_spaces_filtered (2 * recurse, stream); - } - } - fprintf_filtered (stream, "}"); - break; - - case TYPE_CODE_ENUM: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (builtin_type_int, valaddr); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_BITPOS (type, i)) - break; - } - if (i < len) - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - else - fprintf_filtered (stream, "%d", (int) val); - break; - - case TYPE_CODE_FUNC: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - fprintf_filtered (stream, "0x%x", address); - break; - - case TYPE_CODE_INT: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } -#ifdef PRINT_TYPELESS_INTEGER - PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr)); -#else -#ifndef LONG_LONG - fprintf_filtered (stream, - TYPE_UNSIGNED (type) ? "%u" : "%d", - unpack_long (type, valaddr)); -#else - fprintf_filtered (stream, - TYPE_UNSIGNED (type) ? "%llu" : "%lld", - unpack_long (type, valaddr)); -#endif -#endif - - if (TYPE_LENGTH (type) == 1) - { - fprintf_filtered (stream, " '"); - printchar ((unsigned char) unpack_long (type, valaddr), - stream, '\''); - fprintf_filtered (stream, "'"); - } - break; - - case TYPE_CODE_FLT: - if (format) - { - print_scalar_formatted (valaddr, type, format, 0, stream); - break; - } -#ifdef IEEE_FLOAT - if (is_nan ((char *) valaddr, TYPE_LENGTH (type))) - { - fprintf_filtered (stream, "NaN"); - break; - } -#endif - { - double doub; - int inv; - - doub = unpack_double (type, valaddr, &inv); - if (inv) - fprintf_filtered (stream, "Invalid float value"); - else - fprintf_filtered (stream, - TYPE_LENGTH (type) <= 4? "%.6g": "%.16g", doub); - } - break; - - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - - default: - error ("Invalid type code in symbol table."); - } - fflush (stream); - return 0; -} - -#ifdef IEEE_FLOAT - -/* Nonzero if ARG (a double) is a NAN. */ - -int -is_nan (fp, len) - char *fp; - int len; -{ - int lowhalf, highhalf; - union ieee - { - long i[2]; /* ASSUMED 32 BITS */ - float f; /* ASSUMED 32 BITS */ - double d; /* ASSUMED 64 BITS */ - } *arg; - - arg = (union ieee *)fp; - - /* - * Single precision float. - */ - if (len == sizeof(long)) - { - highhalf = arg->i[0]; - return ((((highhalf >> 23) & 0xFF) == 0xFF) - && 0 != (highhalf & 0x7FFFFF)); - } - - /* Separate the high and low words of the double. - Distinguish big and little-endian machines. */ -#ifdef WORDS_BIG_ENDIAN - lowhalf = arg->i[1], highhalf = arg->i[0]; -#else - lowhalf = arg->i[0], highhalf = arg->i[1]; -#endif - - /* Nan: exponent is the maximum possible, and fraction is nonzero. */ - return (((highhalf>>20) & 0x7ff) == 0x7ff - && ! ((highhalf & 0xfffff == 0) && (lowhalf == 0))); -} -#endif - -/* Print a description of a type TYPE - in the form of a declaration of a variable named VARSTRING. - Output goes to STREAM (via stdio). - If SHOW is positive, we show the contents of the outermost level - of structure even if there is a type name that could be used instead. - If SHOW is negative, we never show the details of elements' types. */ - -void -type_print (type, varstring, stream, show) - struct type *type; - char *varstring; - FILE *stream; - int show; -{ - type_print_1 (type, varstring, stream, show, 0); -} - -/* LEVEL is the depth to indent lines by. */ - -void -type_print_1 (type, varstring, stream, show, level) - struct type *type; - char *varstring; - FILE *stream; - int show; - int level; -{ - register enum type_code code; - type_print_base (type, stream, show, level); - code = TYPE_CODE (type); - if ((varstring && *varstring) - || - /* Need a space if going to print stars or brackets; - but not if we will print just a type name. */ - ((show > 0 || TYPE_NAME (type) == 0) - && - (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC - || code == TYPE_CODE_METHOD - || code == TYPE_CODE_ARRAY - || code == TYPE_CODE_MEMBER - || code == TYPE_CODE_REF))) - fprintf_filtered (stream, " "); - type_print_varspec_prefix (type, stream, show, 0); - fputs_filtered (varstring, stream); - type_print_varspec_suffix (type, stream, show, 0); -} - -/* Print the method arguments ARGS to the file STREAM. */ -static void -type_print_method_args (args, prefix, varstring, staticp, stream) - struct type **args; - char *prefix, *varstring; - int staticp; - FILE *stream; -{ - int i; - - fputs_filtered (" ", stream); - fputs_filtered (prefix, stream); - fputs_filtered (varstring, stream); - fputs_filtered (" (", stream); - if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID) - { - i = !staticp; /* skip the class variable */ - while (1) - { - type_print (args[i++], "", stream, 0); - if (!args[i]) - { - fprintf_filtered (stream, " ..."); - break; - } - else if (args[i]->code != TYPE_CODE_VOID) - { - fprintf_filtered (stream, ", "); - } - else break; - } - } - fprintf_filtered (stream, ")"); -} - -/* If TYPE is a derived type, then print out derivation - information. Print out all layers of the type heirarchy - until we encounter one with multiple inheritance. - At that point, print out that ply, and return. */ -static void -type_print_derivation_info (stream, type) - FILE *stream; - struct type *type; -{ - char *name; - int i, n_baseclasses = TYPE_N_BASECLASSES (type); - struct type *basetype = 0; - - while (type && n_baseclasses == 1) - { - basetype = TYPE_BASECLASS (type, 1); - if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype))) - { - while (*name != ' ') name++; - fprintf_filtered (stream, ": %s%s ", - TYPE_VIA_PUBLIC (basetype) ? "public" : "private", - TYPE_VIA_VIRTUAL (basetype) ? " virtual" : ""); - fputs_filtered (name + 1, stream); - fputs_filtered (" ", stream); - } - n_baseclasses = TYPE_N_BASECLASSES (basetype); - type = basetype; - } - - if (type) - { - if (n_baseclasses != 0) - fprintf_filtered (stream, ": "); - for (i = 1; i <= n_baseclasses; i++) - { - basetype = TYPE_BASECLASS (type, i); - if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype))) - { - while (*name != ' ') name++; - fprintf_filtered (stream, "%s%s ", - TYPE_VIA_PUBLIC (basetype) ? "public" : "private", - TYPE_VIA_VIRTUAL (basetype) ? " virtual" : ""); - fputs_filtered (name + 1, stream); - } - if (i < n_baseclasses) - fprintf_filtered (stream, ", "); - } - fprintf_filtered (stream, " "); - } -} - -/* Print any asterisks or open-parentheses needed before the - variable name (to describe its type). - - On outermost call, pass 0 for PASSED_A_PTR. - On outermost call, SHOW > 0 means should ignore - any typename for TYPE and show its details. - SHOW is always zero on recursive calls. */ - -static void -type_print_varspec_prefix (type, stream, show, passed_a_ptr) - struct type *type; - FILE *stream; - int show; - int passed_a_ptr; -{ - if (type == 0) - return; - - if (TYPE_NAME (type) && show <= 0) - return; - - QUIT; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_PTR: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); - fprintf_filtered (stream, "*"); - break; - - case TYPE_CODE_MEMBER: - if (passed_a_ptr) - fprintf_filtered (stream, "("); - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, - 0); - fprintf_filtered (stream, " "); - type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, - passed_a_ptr); - fprintf_filtered (stream, "::"); - break; - - case TYPE_CODE_METHOD: - if (passed_a_ptr) - fprintf (stream, "("); - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, - 0); - fprintf_filtered (stream, " "); - type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, - passed_a_ptr); - fprintf_filtered (stream, "::"); - break; - - case TYPE_CODE_REF: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); - fprintf_filtered (stream, "&"); - break; - - case TYPE_CODE_FUNC: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, - 0); - if (passed_a_ptr) - fprintf_filtered (stream, "("); - break; - - case TYPE_CODE_ARRAY: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, - 0); - if (passed_a_ptr) - fprintf_filtered (stream, "("); - } -} - -/* Print any array sizes, function arguments or close parentheses - needed after the variable name (to describe its type). - Args work like type_print_varspec_prefix. */ - -static void -type_print_varspec_suffix (type, stream, show, passed_a_ptr) - struct type *type; - FILE *stream; - int show; - int passed_a_ptr; -{ - if (type == 0) - return; - - if (TYPE_NAME (type) && show <= 0) - return; - - QUIT; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - - fprintf_filtered (stream, "["); - if (TYPE_LENGTH (type) >= 0 - && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) - fprintf_filtered (stream, "%d", - (TYPE_LENGTH (type) - / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); - fprintf_filtered (stream, "]"); - - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - 0); - break; - - case TYPE_CODE_MEMBER: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); - break; - - case TYPE_CODE_METHOD: - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); - if (passed_a_ptr) - { - int i; - struct type **args = TYPE_ARG_TYPES (type); - - fprintf_filtered (stream, "("); - if (args[1] == 0) - fprintf_filtered (stream, "..."); - else for (i = 1; args[i] != 0 && args[i]->code != TYPE_CODE_VOID; i++) - { - type_print_1 (args[i], "", stream, -1, 0); - if (args[i+1] == 0) - fprintf_filtered (stream, "..."); - else if (args[i+1]->code != TYPE_CODE_VOID) - fprintf_filtered (stream, ","); - } - fprintf_filtered (stream, ")"); - } - break; - - case TYPE_CODE_PTR: - case TYPE_CODE_REF: - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1); - break; - - case TYPE_CODE_FUNC: - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - passed_a_ptr); - if (passed_a_ptr) - fprintf_filtered (stream, ")"); - fprintf_filtered (stream, "()"); - break; - } -} - -/* Print the name of the type (or the ultimate pointer target, - function value or array element), or the description of a - structure or union. - - SHOW nonzero means don't print this type as just its name; - show its real definition even if it has a name. - SHOW zero means print just typename or struct tag if there is one - SHOW negative means abbreviate structure elements. - SHOW is decremented for printing of structure elements. - - LEVEL is the depth to indent by. - We increase it for some recursive calls. */ - -static void -type_print_base (type, stream, show, level) - struct type *type; - FILE *stream; - int show; - int level; -{ - char *name; - register int i; - register int len; - register int lastval; - - QUIT; - - if (type == 0) - { - fprintf_filtered (stream, "type unknown"); - return; - } - - if (TYPE_NAME (type) && show <= 0) - { - fputs_filtered (TYPE_NAME (type), stream); - return; - } - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - case TYPE_CODE_PTR: - case TYPE_CODE_MEMBER: - case TYPE_CODE_REF: - case TYPE_CODE_FUNC: - case TYPE_CODE_METHOD: - type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); - break; - - case TYPE_CODE_STRUCT: - fprintf_filtered (stream, "struct "); - goto struct_union; - - case TYPE_CODE_UNION: - fprintf_filtered (stream, "union "); - struct_union: - if (TYPE_NAME (type) && (name = TYPE_NAME (type))) - { - while (*name != ' ') name++; - fputs_filtered (name + 1, stream); - fputs_filtered (" ", stream); - } - if (show < 0) - fprintf_filtered (stream, "{...}"); - else - { - int i; - - type_print_derivation_info (stream, type); - - fprintf_filtered (stream, "{"); - len = TYPE_NFIELDS (type); - if (len) - fprintf_filtered (stream, "\n"); - else - { - if (TYPE_FLAGS (type) & TYPE_FLAG_STUB) - fprintf_filtered (stream, "<incomplete type>\n"); - else - fprintf_filtered (stream, "<no data fields>\n"); - } - - /* If there is a base class for this type, - do not print the field that it occupies. */ - for (i = TYPE_N_BASECLASSES (type); i < len; i++) - { - QUIT; - /* Don't print out virtual function table. */ - if (! strncmp (TYPE_FIELD_NAME (type, i), - "_vptr$", 6)) - continue; - - print_spaces_filtered (level + 4, stream); - if (TYPE_FIELD_STATIC (type, i)) - { - fprintf_filtered (stream, "static "); - } - type_print_1 (TYPE_FIELD_TYPE (type, i), - TYPE_FIELD_NAME (type, i), - stream, show - 1, level + 4); - if (!TYPE_FIELD_STATIC (type, i) - && TYPE_FIELD_PACKED (type, i)) - { - /* It is a bitfield. This code does not attempt - to look at the bitpos and reconstruct filler, - unnamed fields. This would lead to misleading - results if the compiler does not put out fields - for such things (I don't know what it does). */ - fprintf_filtered (stream, " : %d", - TYPE_FIELD_BITSIZE (type, i)); - } - fprintf_filtered (stream, ";\n"); - } - - /* C++: print out the methods */ - len = TYPE_NFN_FIELDS (type); - if (len) fprintf_filtered (stream, "\n"); - for (i = 0; i < len; i++) - { - struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); - int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); - - for (j = 0; j < len2; j++) - { - QUIT; - print_spaces_filtered (level + 4, stream); - if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) - fprintf_filtered (stream, "virtual "); - else if (TYPE_FN_FIELD_STATIC_P (f, j)) - fprintf_filtered (stream, "static "); - type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, 0); - if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' - && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", - TYPE_FN_FIELDLIST_NAME (type, i), 0, stream); - else - type_print_method_args - (TYPE_FN_FIELD_ARGS (f, j), "", - TYPE_FN_FIELDLIST_NAME (type, i), - TYPE_FN_FIELD_STATIC_P (f, j), stream); - - fprintf_filtered (stream, ";\n"); - } - if (len2) fprintf_filtered (stream, "\n"); - } - - print_spaces_filtered (level, stream); - fprintf_filtered (stream, "}"); - } - break; - - case TYPE_CODE_ENUM: - fprintf_filtered (stream, "enum "); - if (TYPE_NAME (type)) - { - name = TYPE_NAME (type); - while (*name != ' ') name++; - fputs_filtered (name + 1, stream); - fputs_filtered (" ", stream); - } - if (show < 0) - fprintf_filtered (stream, "{...}"); - else - { - fprintf_filtered (stream, "{"); - len = TYPE_NFIELDS (type); - lastval = 0; - for (i = 0; i < len; i++) - { - QUIT; - if (i) fprintf_filtered (stream, ", "); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - if (lastval != TYPE_FIELD_BITPOS (type, i)) - { - fprintf_filtered (stream, " : %d", TYPE_FIELD_BITPOS (type, i)); - lastval = TYPE_FIELD_BITPOS (type, i); - } - lastval++; - } - fprintf_filtered (stream, "}"); - } - break; - - case TYPE_CODE_INT: - if (TYPE_UNSIGNED (type)) - name = unsigned_type_table[TYPE_LENGTH (type)]; - else - name = signed_type_table[TYPE_LENGTH (type)]; - fputs_filtered (name, stream); - break; - - case TYPE_CODE_FLT: - name = float_type_table[TYPE_LENGTH (type)]; - fputs_filtered (name, stream); - break; - - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - - case 0: - fprintf_filtered (stream, "struct unknown"); - break; - - default: - error ("Invalid type code in symbol table."); - } -} - -static void -set_maximum_command (arg) - char *arg; -{ - if (!arg) error_no_arg ("value for maximum elements to print"); - print_max = parse_and_eval_address (arg); - if (print_max == 0) - print_max = UINT_MAX; -} - -static void -set_prettyprint_command (arg, from_tty) - char *arg; - int from_tty; -{ - prettyprint = parse_binary_operation ("set prettyprint", arg); -} - -static void -set_unionprint_command (arg, from_tty) - char *arg; - int from_tty; -{ - unionprint = parse_binary_operation ("set unionprint", arg); -} - -format_info (arg, from_tty) - char *arg; - int from_tty; -{ - if (arg) - error ("\"info format\" does not take any arguments."); - printf ("Prettyprinting of structures is %s.\n", - prettyprint ? "on" : "off"); - printf ("Printing of unions interior to structures is %s.\n", - unionprint ? "on" : "off"); - if (print_max == UINT_MAX) - printf_filtered - ("There is no maximum number of array elements printed.\n"); - else - printf_filtered - ("The maximum number of array elements printed is %d.\n", print_max); -} - -extern struct cmd_list_element *setlist; - -void -_initialize_valprint () -{ - add_cmd ("array-max", class_vars, set_maximum_command, - "Set NUMBER as limit on string chars or array elements to print.\n\ -\"set array-max 0\" causes there to be no limit.", - &setlist); - - add_cmd ("prettyprint", class_support, set_prettyprint_command, - "Turn prettyprinting of structures on and off.", - &setlist); - add_alias_cmd ("pp", "prettyprint", class_support, 1, &setlist); - - add_cmd ("unionprint", class_support, set_unionprint_command, - "Turn printing of unions interior to structures on and off.", - &setlist); - - add_info ("format", format_info, - "Show current settings of data formatting options."); - - /* Give people the defaults which they are used to. */ - prettyprint = 0; - unionprint = 1; - - print_max = 200; - - unsigned_type_table - = (char **) xmalloc ((1 + sizeof (unsigned LONGEST)) * sizeof (char *)); - bzero (unsigned_type_table, (1 + sizeof (unsigned LONGEST))); - unsigned_type_table[sizeof (unsigned char)] = "unsigned char"; - unsigned_type_table[sizeof (unsigned short)] = "unsigned short"; - unsigned_type_table[sizeof (unsigned long)] = "unsigned long"; - unsigned_type_table[sizeof (unsigned int)] = "unsigned int"; -#ifdef LONG_LONG - unsigned_type_table[sizeof (unsigned long long)] = "unsigned long long"; -#endif - - signed_type_table - = (char **) xmalloc ((1 + sizeof (LONGEST)) * sizeof (char *)); - bzero (signed_type_table, (1 + sizeof (LONGEST))); - signed_type_table[sizeof (char)] = "char"; - signed_type_table[sizeof (short)] = "short"; - signed_type_table[sizeof (long)] = "long"; - signed_type_table[sizeof (int)] = "int"; -#ifdef LONG_LONG - signed_type_table[sizeof (long long)] = "long long"; -#endif - - float_type_table - = (char **) xmalloc ((1 + sizeof (double)) * sizeof (char *)); - bzero (float_type_table, (1 + sizeof (double))); - float_type_table[sizeof (float)] = "float"; - float_type_table[sizeof (double)] = "double"; -} - |