* 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 ****
This commit is contained in:
Fred Fish 1992-11-21 06:10:08 +00:00
parent 242d9c06b2
commit 5d074aa977
8 changed files with 594 additions and 104 deletions

View File

@ -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 ****

View File

@ -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, " <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);
}
/* 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*/

View File

@ -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++ != '\'')
if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\''))
{
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. */
/* 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 if (*tokptr == '\'')
{
tokptr++;
/* 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);
}
}
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 */

View File

@ -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;

View File

@ -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:

View File

@ -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 */

View File

@ -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"

View File

@ -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, " <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);
}
/* 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 */