* 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 ****
+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,
* 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,
**** 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 ****
{
error (msg ? msg : "Invalid syntax in expression.");
}
+\f
+/* 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, " <repeats %u times>", 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);
+}
+
\f
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
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*/
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*/
%%
+/* 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;
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);
}
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.
*/
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;
token, such as a character literal. */
switch (*lexptr)
{
+ case 'C':
+ case 'c':
case '\'':
token = match_character_literal ();
if (token != 0)
}
}
+\f
+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.");
+}
+
\f
/* Table of operators and their precedences for printing expressions. */
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 */
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;
/* 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);
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",
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:
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:
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 };
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 */
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 */
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 */
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 */
#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"
else
error("Invalid syntax in expression");
}
+
+\f
+/* 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, " <repeats %u times>", 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);
+}
+
\f
/* Table of operators and their precedences for printing expressions. */
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 */