From 5d074aa97723ff99cdeef26b3cf90e2095f3a566 Mon Sep 17 00:00:00 2001 From: Fred Fish Date: Sat, 21 Nov 1992 06:10:08 +0000 Subject: [PATCH] * defs.h (sevenbit_strings): Add declaration. * defs.h (printchar): Replace with gdb_printchar. * language.h (language_defn): Add new function pointers la_printchar and la_printstr, to do language dependent printing of characters and strings. * language.h (local_printchar, local_printstr): New macros to call language dependent functions pointed to by la_printchar and la_printstr respectively. * c-exp.y (emit_char, c_printchar, c_printstr): New language dependent functions for printing characters and strings. * c-exp.y (c_language_defn, cplus_language_defn): Add c_printchar and c_printstr. * command.c (do_setshow_command): Rename printchar use to gdb_printchar. * expprint.c (print_subexp): Replace C style string output with call to local_printstr. * language.c (unk_lang_printchar, unk_lang_printstr): New stubs, currently errors. * language.c (unknown_language_defn, auto_language_defn, local_language_defn): Add unk_lang_printchar and unk_lang_printstr. * m2-exp.y (emit_char, m2_printchar, m2_printstr): New language dependent functions to print characters and strings. * m2-exp.y (m2_language_defn): Add m2_printchar and m2_printstr. * utils.c (printchar): Renamed to gdb_printchar. * valprint.c (print_string): Remove prototype, function moved to c-exp.y, where it becomes c_printstr. * valprint.c (print_max): Made global for reference from the language dependent printing routines in *-exp.y. * valprint.c (repeat_count_threshold): New variable with function of old REPEAT_COUNT_THREHOLD define, but now settable by user. Change all references to old macro to references to new variable. * valprint.c (value_print, val_print): Replace calls to print_string with calls to local_printstr. * valprint.c (val_print): Replace C style character printing with call to local_printchar. * valprint.c (val_print): Add case for TYPE_CODE_CHAR. * valprint.c (_initialize_valprint): Add add_show_from_set call for setting up repeat_count_threshold as print variable. **** start-sanitize-chill **** * ch-exp.y (decode_integer_value): New function. * ch-exp.y (decode_integer_literal): Use decode_integer_value. * ch-exp.y (chill_printchar, chill_printstr): New language dependent functions for printing characters and strings. * ch-exp.y (chill_language_defn): Add chill_printchar and chill_printstr. **** end-sanitize-chill **** --- gdb/ChangeLog | 55 +++++++++++- gdb/c-exp.y | 161 ++++++++++++++++++++++++++++++++++ gdb/ch-exp.y | 231 ++++++++++++++++++++++++++++++++----------------- gdb/command.c | 2 +- gdb/expprint.c | 44 +++++----- gdb/language.c | 24 +++++ gdb/language.h | 7 ++ gdb/m2-exp.y | 168 +++++++++++++++++++++++++++++++++++ 8 files changed, 591 insertions(+), 101 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 271f95d09f3..991de8e2dd6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,53 @@ +Fri Nov 20 21:35:57 1992 Fred Fish (fnf@cygnus.com) + + * defs.h (sevenbit_strings): Add declaration. + * defs.h (printchar): Replace with gdb_printchar. + * language.h (language_defn): Add new function pointers + la_printchar and la_printstr, to do language dependent + printing of characters and strings. + * language.h (local_printchar, local_printstr): New macros + to call language dependent functions pointed to by la_printchar + and la_printstr respectively. + * c-exp.y (emit_char, c_printchar, c_printstr): New language + dependent functions for printing characters and strings. + * c-exp.y (c_language_defn, cplus_language_defn): Add + c_printchar and c_printstr. + * command.c (do_setshow_command): Rename printchar use to + gdb_printchar. + * expprint.c (print_subexp): Replace C style string output + with call to local_printstr. + * language.c (unk_lang_printchar, unk_lang_printstr): + New stubs, currently errors. + * language.c (unknown_language_defn, auto_language_defn, + local_language_defn): Add unk_lang_printchar and + unk_lang_printstr. + * m2-exp.y (emit_char, m2_printchar, m2_printstr): New + language dependent functions to print characters and strings. + * m2-exp.y (m2_language_defn): Add m2_printchar and m2_printstr. + * utils.c (printchar): Renamed to gdb_printchar. + * valprint.c (print_string): Remove prototype, function moved + to c-exp.y, where it becomes c_printstr. + * valprint.c (print_max): Made global for reference from the + language dependent printing routines in *-exp.y. + * valprint.c (repeat_count_threshold): New variable with function + of old REPEAT_COUNT_THREHOLD define, but now settable by user. + Change all references to old macro to references to new variable. + * valprint.c (value_print, val_print): Replace calls to + print_string with calls to local_printstr. + * valprint.c (val_print): Replace C style character printing + with call to local_printchar. + * valprint.c (val_print): Add case for TYPE_CODE_CHAR. + * valprint.c (_initialize_valprint): Add add_show_from_set + call for setting up repeat_count_threshold as print variable. + **** start-sanitize-chill **** + * ch-exp.y (decode_integer_value): New function. + * ch-exp.y (decode_integer_literal): Use decode_integer_value. + * ch-exp.y (chill_printchar, chill_printstr): New language + dependent functions for printing characters and strings. + * ch-exp.y (chill_language_defn): Add chill_printchar and + chill_printstr. + **** end-sanitize-chill **** + Wed Nov 18 15:05:45 1992 Ian Lance Taylor (ian@cygnus.com) * remote-vx.c (vx_kill): just warn if we can't contact the board, @@ -27,6 +77,8 @@ Wed Nov 18 14:27:47 1992 Fred Fish (fnf@cygnus.com) * c-exp.y (c_language_defn): Update for new format handling. * m2-exp.y (m2_language_defn): Update for new format handling. * dbxread.c (language.h): Include for partial-stab.h use. + * mipsread.c (expression.h, language.h): Include for + partial-stab.h use. * defs.h (local_hex_format, local_hex_format_custom, local_hex_string, local_hex_string_custom): Move to language.h. * language.c (local_hex_format_custom, local_hex_string, @@ -39,7 +91,8 @@ Wed Nov 18 14:27:47 1992 Fred Fish (fnf@cygnus.com) **** start-sanitize-chill **** * c-exp.y (chill_language_defn): Update for new format handling. * ch-exp.y (CHARACTER_LITERAL): Add support to yylex. - * ch-exp.y (match_integer_literal): Add function. + * ch-exp.y (decode_integer_literal): Add function + * ch-exp.y (match_integer_literal): Use decode_integer_literal. * ch-exp.y (builtin_type_chill_char): Add definition. * gdbtypes.h (builtin_type_chill_char): Add declaration. **** end-sanitize-chill **** diff --git a/gdb/c-exp.y b/gdb/c-exp.y index e806629da46..2ba3c8cc2b9 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1470,6 +1470,163 @@ yyerror (msg) { error (msg ? msg : "Invalid syntax in expression."); } + +/* Print the character C on STREAM as part of the contents of a literal + string whose delimiter is QUOTER. Note that that format for printing + characters and strings is language specific. */ + +static void +emit_char (c, stream, quoter) + register int c; + FILE *stream; + int quoter; +{ + + c &= 0xFF; /* Avoid sign bit follies */ + + if ( c < 0x20 || /* Low control chars */ + (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ + (sevenbit_strings && c >= 0x80)) { /* high order bit set */ + switch (c) + { + case '\n': + fputs_filtered ("\\n", stream); + break; + case '\b': + fputs_filtered ("\\b", stream); + break; + case '\t': + fputs_filtered ("\\t", stream); + break; + case '\f': + fputs_filtered ("\\f", stream); + break; + case '\r': + fputs_filtered ("\\r", stream); + break; + case '\033': + fputs_filtered ("\\e", stream); + break; + case '\007': + fputs_filtered ("\\a", stream); + break; + default: + fprintf_filtered (stream, "\\%.3o", (unsigned int) c); + break; + } + } else { + if (c == '\\' || c == quoter) + { + fputs_filtered ("\\", stream); + } + fprintf_filtered (stream, "%c", c); + } +} + +static void +c_printchar (c, stream) + int c; + FILE *stream; +{ + fputs_filtered ("'", stream); + emit_char (c, stream, '\''); + fputs_filtered ("'", stream); +} + +/* 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. */ + +static void +c_printstr (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; + extern int inspect_it; + extern int repeat_count_threshold; + extern int print_max; + + 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 repetitions 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) + { + if (inspect_it) + fputs_filtered ("\\\", ", stream); + else + fputs_filtered ("\", ", stream); + in_quotes = 0; + } + c_printchar (string[i], stream); + fprintf_filtered (stream, " ", reps); + i = rep1 - 1; + things_printed += repeat_count_threshold; + need_comma = 1; + } + else + { + if (!in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + in_quotes = 1; + } + emit_char (string[i], stream, '"'); + ++things_printed; + } + } + + /* Terminate the quotes if necessary. */ + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + } + + if (force_ellipses || i < length) + fputs_filtered ("...", stream); +} + /* Table mapping opcodes into strings for printing operators and precedences of the operators. */ @@ -1561,6 +1718,8 @@ const struct language_defn c_language_defn = { type_check_off, c_parse, c_error, + c_printchar, /* Print a character constant */ + c_printstr, /* Function to print string constant */ &BUILTIN_TYPE_LONGEST, /* longest signed integral type */ &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */ &builtin_type_double, /* longest floating point type */ /*FIXME*/ @@ -1580,6 +1739,8 @@ const struct language_defn cplus_language_defn = { type_check_off, c_parse, c_error, + c_printchar, /* Print a character constant */ + c_printstr, /* Function to print string constant */ &BUILTIN_TYPE_LONGEST, /* longest signed integral type */ &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */ &builtin_type_double, /* longest floating point type */ /*FIXME*/ diff --git a/gdb/ch-exp.y b/gdb/ch-exp.y index c7e7c7c8306..1875ea6ccce 100644 --- a/gdb/ch-exp.y +++ b/gdb/ch-exp.y @@ -765,10 +765,75 @@ buffer_location : FIXME { $$ = 0; } %% +/* Start looking for a value composed of valid digits as set by the base + in use. Note that '_' characters are valid anywhere, in any quantity, + and are simply ignored. Since we must find at least one valid digit, + or reject this token as an integer literal, we keep track of how many + digits we have encountered. */ + +static int +decode_integer_value (base, tokptrptr, ivalptr) + int base; + char **tokptrptr; + int *ivalptr; +{ + char *tokptr = *tokptrptr; + int temp; + int digits = 0; + + while (*tokptr != '\0') + { + temp = tolower (*tokptr); + tokptr++; + switch (temp) + { + case '_': + continue; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + temp -= '0'; + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + temp -= 'a'; + temp += 10; + break; + default: + temp = base; + break; + } + if (temp < base) + { + digits++; + *ivalptr *= base; + *ivalptr += temp; + } + else + { + /* Found something not in domain for current base. */ + tokptr--; /* Unconsume what gave us indigestion. */ + break; + } + } + + /* If we didn't find any digits, then we don't have a valid integer + value, so reject the entire token. Otherwise, update the lexical + scan pointer, and return non-zero for success. */ + + if (digits == 0) + { + return (0); + } + else + { + *tokptrptr = tokptr; + return (1); + } +} + static int decode_integer_literal (valptr, tokptrptr) -int *valptr; -char **tokptrptr; + int *valptr; + char **tokptrptr; { char *tokptr = *tokptrptr; int base = 0; @@ -818,54 +883,15 @@ char **tokptrptr; return (0); } - /* Start looking for a value composed of valid digits as set by the base - in use. Note that '_' characters are valid anywhere, in any quantity, - and are simply ignored. Since we must find at least one valid digit, - or reject this token as an integer literal, we keep track of how many - digits we have encountered. */ - - while (*tokptr != '\0') - { - temp = tolower (*tokptr); - tokptr++; - switch (temp) - { - case '_': - continue; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - temp -= '0'; - break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - temp -= 'a'; - temp += 10; - break; - default: - temp = base; - break; - } - if (temp < base) - { - digits++; - ival *= base; - ival += temp; - } - else - { - /* Found something not in domain for current base. */ - tokptr--; /* Unconsume what gave us indigestion. */ - break; - } - } - - /* If we didn't find any digits, then we don't have a valid integer - literal, so reject the entire token. Also, if we have an explicit + /* Attempt to decode whatever follows as an integer value in the + indicated base, updating the token pointer in the process and + computing the value into ival. Also, if we have an explicit base, then the next character must not be a single quote, or we - have a bitstring literal, so reject the entire token in this case - as well. Otherwise, update the lexical scan pointer, and return - non-zero for success. */ - - if (digits == 0) + have a bitstring literal, so reject the entire token in this case. + Otherwise, update the lexical scan pointer, and return non-zero + for success. */ + + if (!decode_integer_value (base, &tokptr, &ival)) { return (0); } @@ -888,6 +914,9 @@ char **tokptrptr; EX: 'a' '^(7)' '^(7,8)' + As a GNU chill extension, the syntax C'xx' is also recognized as a + character literal, where xx is a hex value for the character. + Returns CHARACTER_LITERAL if a match is found. */ @@ -897,43 +926,51 @@ match_character_literal () char *tokptr = lexptr; int ival = 0; - /* All character literals must start with a single quote. If we don't - find it, don't bother looking any further. */ - - if (*tokptr++ != '\'') - { - return (0); - } - - /* Determine which form we have, either a control sequence or the - single character form. */ - - if ((*tokptr == '^') && (*(tokptr + 1) == '(')) + if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\'')) { - /* Match and decode a control sequence. Return zero if we don't - find a valid integer literal, or if the next unconsumed character - after the integer literal is not the trailing ')'. - FIXME: We currently don't handle the multiple integer literal - form. */ + /* We have a GNU chill extension form, so skip the leading "C'", + decode the hex value, and then ensure that we have a trailing + single quote character. */ tokptr += 2; - if (!decode_integer_literal (&ival, &tokptr) || (*tokptr++ != ')')) + if (!decode_integer_value (16, &tokptr, &ival) || (*tokptr != '\'')) { return (0); } + tokptr++; } - else + else if (*tokptr == '\'') { - ival = *tokptr++; - } - - /* The trailing quote has not yet been consumed. If we don't find - it, then we have no match. */ + tokptr++; - if (*tokptr++ != '\'') - { - return (0); + /* Determine which form we have, either a control sequence or the + single character form. */ + + if ((*tokptr == '^') && (*(tokptr + 1) == '(')) + { + /* Match and decode a control sequence. Return zero if we don't + find a valid integer literal, or if the next unconsumed character + after the integer literal is not the trailing ')'. + FIXME: We currently don't handle the multiple integer literal + form. */ + tokptr += 2; + if (!decode_integer_literal (&ival, &tokptr) || (*tokptr++ != ')')) + { + return (0); + } + } + else + { + ival = *tokptr++; + } + + /* The trailing quote has not yet been consumed. If we don't find + it, then we have no match. */ + + if (*tokptr++ != '\'') + { + return (0); + } } - yylval.typed_val.val = ival; yylval.typed_val.type = builtin_type_chill_char; lexptr = tokptr; @@ -1084,6 +1121,8 @@ yylex () token, such as a character literal. */ switch (*lexptr) { + case 'C': + case 'c': case '\'': token = match_character_literal (); if (token != 0) @@ -1174,6 +1213,42 @@ yyerror (msg) } } + +static void +chill_printchar (c, stream) + register int c; + FILE *stream; +{ + c &= 0xFF; /* Avoid sign bit follies */ + + if ( c < 0x20 || /* Low control chars */ + (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ + (sevenbit_strings && c >= 0x80)) /* high order bit set */ + { + fprintf_filtered (stream, "C'%.2x'", (unsigned int) c); + } + else + { + fprintf_filtered (stream, "'%c'", c); + } +} + +/* 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. + */ + +static void +chill_printstr (stream, string, length, force_ellipses) + FILE *stream; + char *string; + unsigned int length; + int force_ellipses; +{ + error ("internal error - unimplemented function chill_printstr called."); +} + /* Table of operators and their precedences for printing expressions. */ @@ -1224,6 +1299,8 @@ const struct language_defn chill_language_defn = { type_check_on, chill_parse, /* parser */ chill_error, /* parser error function */ + chill_printchar, /* print a character constant */ + chill_printstr, /* function to print a string constant */ &BUILTIN_TYPE_LONGEST, /* longest signed integral type */ &BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */ &builtin_type_chill_real, /* longest floating point type */ diff --git a/gdb/command.c b/gdb/command.c index 9c194332190..e12db1b5f74 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -1081,7 +1081,7 @@ do_setshow_command (arg, from_tty, c) unsigned char *p; fputs_filtered ("\"", stdout); for (p = *(unsigned char **) c->var; *p != '\0'; p++) - printchar (*p, stdout, '"'); + gdb_printchar (*p, stdout, '"'); fputs_filtered ("\"", stdout); } break; diff --git a/gdb/expprint.c b/gdb/expprint.c index 357c8904625..d71a1c0b230 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -74,9 +74,12 @@ print_subexp (exp, pos, stream, prec) /* Common ops */ case OP_SCOPE: + myprec = PREC_PREFIX; + assoc = 0; (*pos) += 2; - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered ("::", stream); + print_subexp (exp, pos, stream, + (enum precedence) ((int) myprec + assoc)); + fputs_filtered (" :: ", stream); nargs = strlen (&exp->elts[pc + 2].string); (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element); @@ -114,6 +117,13 @@ print_subexp (exp, pos, stream, prec) reg_names[longest_to_int (exp->elts[pc + 1].longconst)]); return; + case OP_BOOL: + (*pos) += 2; + fprintf_filtered (stream, "%s", + longest_to_int (exp->elts[pc + 1].longconst) + ? "TRUE" : "FALSE"); + return; + case OP_INTERNALVAR: (*pos) += 2; fprintf_filtered (stream, "$%s", @@ -137,10 +147,10 @@ print_subexp (exp, pos, stream, prec) case OP_STRING: nargs = strlen (&exp->elts[pc + 1].string); (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element); - fputs_filtered ("\"", stream); - for (tem = 0; tem < nargs; tem++) - printchar ((&exp->elts[pc + 1].string)[tem], stream, '"'); - fputs_filtered ("\"", stream); + /* local_printstr will print using the current repeat count threshold. + If necessary, we can temporarily set it to zero, or pass it as an + additional parameter to local_printstr. -fnf */ + local_printstr (stream, &exp->elts[pc + 1].string, nargs, 0); return; case TERNOP_COND: @@ -160,30 +170,20 @@ print_subexp (exp, pos, stream, prec) return; case STRUCTOP_STRUCT: - tem = strlen (&exp->elts[pc + 2].string); - (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); + tem = strlen (&exp->elts[pc + 1].string); + (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered (".", stream); - if (exp->elts[pc + 1].type) - { - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered ("::", stream); - } - fputs_filtered (&exp->elts[pc + 2].string, stream); + fputs_filtered (&exp->elts[pc + 1].string, stream); return; /* Will not occur for Modula-2 */ case STRUCTOP_PTR: - tem = strlen (&exp->elts[pc + 2].string); - (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); + tem = strlen (&exp->elts[pc + 1].string); + (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("->", stream); - if (exp->elts[pc + 1].type) - { - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered ("::", stream); - } - fputs_filtered (&exp->elts[pc + 2].string, stream); + fputs_filtered (&exp->elts[pc + 1].string, stream); return; case BINOP_SUBSCRIPT: diff --git a/gdb/language.c b/gdb/language.c index a20053c4adb..5a6c689f219 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -1098,6 +1098,24 @@ unk_lang_error (msg) error ("Attempted to parse an expression with unknown language"); } +static void +unk_lang_printchar (c, stream) + register int c; + FILE *stream; +{ + error ("internal error - unimplemented function unk_lang_printchar called."); +} + +static void +unk_lang_printstr (stream, string, length, force_ellipses) + FILE *stream; + char *string; + unsigned int length; + int force_ellipses; +{ + error ("internal error - unimplemented function unk_lang_printstr called."); +} + static struct type ** const (unknown_builtin_types[]) = { 0 }; static const struct op_print unk_op_print_tab[] = { 0 }; @@ -1109,6 +1127,8 @@ const struct language_defn unknown_language_defn = { type_check_off, unk_lang_parser, unk_lang_error, + unk_lang_printchar, /* Print character constant */ + unk_lang_printstr, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ @@ -1129,6 +1149,8 @@ const struct language_defn auto_language_defn = { type_check_off, unk_lang_parser, unk_lang_error, + unk_lang_printchar, /* Print character constant */ + unk_lang_printstr, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ @@ -1148,6 +1170,8 @@ const struct language_defn local_language_defn = { type_check_off, unk_lang_parser, unk_lang_error, + unk_lang_printchar, /* Print character constant */ + unk_lang_printstr, &builtin_type_error, /* longest signed integral type */ &builtin_type_error, /* longest unsigned integral type */ &builtin_type_error, /* longest floating point type */ diff --git a/gdb/language.h b/gdb/language.h index 2cc6a3bb605..0e240f50a90 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -106,6 +106,8 @@ struct language_defn { enum type_check la_type_check; /* Default type checking */ int (*la_parser) PARAMS((void)); /* Parser function */ void (*la_error) PARAMS ((char *)); /* Parser error function */ + void (*la_printchar) PARAMS ((int, FILE *)); + void (*la_printstr) PARAMS ((FILE *, char *, unsigned int, int)); struct type **la_longest_int; /* Longest signed integral type */ struct type **la_longest_unsigned_int; /* Longest uns integral type */ struct type **la_longest_float; /* Longest floating point type */ @@ -215,6 +217,11 @@ set_language PARAMS ((enum language)); #define local_hex_format_suffix() \ (current_language->la_hex_format.la_format_suffix) +#define local_printchar(ch, stream) \ + (current_language->la_printchar(ch, stream)) +#define local_printstr(stream, string, length, force_ellipses) \ + (current_language->la_printstr(stream, string, length, force_ellipses)) + /* Return a format string for printf that will print a number in one of the local (language-specific) formats. Result is static and is overwritten by the next call. Takes printf options like "08" or "l" diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index bfaf2649f2d..ae92d96faf9 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -1174,6 +1174,172 @@ yyerror(msg) else error("Invalid syntax in expression"); } + + +/* Print the character C on STREAM as part of the contents of a literal + string whose delimiter is QUOTER. Note that that format for printing + characters and strings is language specific. + FIXME: This is a copy of the same function from c-exp.y. It should + be replaced with a true Modula version. + */ + +static void +emit_char (c, stream, quoter) + register int c; + FILE *stream; + int quoter; +{ + + c &= 0xFF; /* Avoid sign bit follies */ + + if ( c < 0x20 || /* Low control chars */ + (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ + (sevenbit_strings && c >= 0x80)) { /* high order bit set */ + switch (c) + { + case '\n': + fputs_filtered ("\\n", stream); + break; + case '\b': + fputs_filtered ("\\b", stream); + break; + case '\t': + fputs_filtered ("\\t", stream); + break; + case '\f': + fputs_filtered ("\\f", stream); + break; + case '\r': + fputs_filtered ("\\r", stream); + break; + case '\033': + fputs_filtered ("\\e", stream); + break; + case '\007': + fputs_filtered ("\\a", stream); + break; + default: + fprintf_filtered (stream, "\\%.3o", (unsigned int) c); + break; + } + } else { + if (c == '\\' || c == quoter) + { + fputs_filtered ("\\", stream); + } + fprintf_filtered (stream, "%c", c); + } +} + +/* FIXME: This is a copy of the same function from c-exp.y. It should + be replaced with a true Modula version. */ + +static void +m2_printchar (c, stream) + int c; + FILE *stream; +{ + fputs_filtered ("'", stream); + emit_char (c, stream, '\''); + fputs_filtered ("'", stream); +} + +/* 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. + FIXME: This is a copy of the same function from c-exp.y. It should + be replaced with a true Modula version. */ + +static void +m2_printstr (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; + extern int inspect_it; + extern int repeat_count_threshold; + extern int print_max; + + 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 repetitions 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) + { + if (inspect_it) + fputs_filtered ("\\\", ", stream); + else + fputs_filtered ("\", ", stream); + in_quotes = 0; + } + c_printchar (string[i], stream); + fprintf_filtered (stream, " ", reps); + i = rep1 - 1; + things_printed += repeat_count_threshold; + need_comma = 1; + } + else + { + if (!in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + in_quotes = 1; + } + emit_char (string[i], stream, '"'); + ++things_printed; + } + } + + /* Terminate the quotes if necessary. */ + if (in_quotes) + { + if (inspect_it) + fputs_filtered ("\\\"", stream); + else + fputs_filtered ("\"", stream); + } + + if (force_ellipses || i < length) + fputs_filtered ("...", stream); +} + /* Table of operators and their precedences for printing expressions. */ @@ -1227,6 +1393,8 @@ const struct language_defn m2_language_defn = { type_check_on, m2_parse, /* parser */ m2_error, /* parser error function */ + m2_printchar, /* Print character constant */ + m2_printstr, /* function to print string constant */ &builtin_type_m2_int, /* longest signed integral type */ &builtin_type_m2_card, /* longest unsigned integral type */ &builtin_type_m2_real, /* longest floating point type */ -- 2.30.2