* defs.h (sevenbit_strings): Add declaration.
authorFred Fish <fnf@specifix.com>
Sat, 21 Nov 1992 06:10:08 +0000 (06:10 +0000)
committerFred Fish <fnf@specifix.com>
Sat, 21 Nov 1992 06:10:08 +0000 (06:10 +0000)
* 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
gdb/c-exp.y
gdb/ch-exp.y
gdb/command.c
gdb/expprint.c
gdb/language.c
gdb/language.h
gdb/m2-exp.y

index 271f95d09f3c018772f993075082f450e0ce5903..991de8e2dd6044db93af8ce0f30e4c321aa6b868 100644 (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 ****
index e806629da461629d56f95988273d95f2d0844152..2ba3c8cc2b9cf6b4686616692ba773157e833563 100644 (file)
@@ -1470,6 +1470,163 @@ yyerror (msg)
 {
   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.  */
@@ -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*/
index c7e7c7c8306b43b06611a7702632587a82523652..1875ea6cccea830266fd5762cade163ec0c69608 100644 (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++ != '\'')
-    {
-      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)
     }
 }
 
+\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.  */
 
@@ -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 */
index 9c1943321902f4a5b77801bfe150f20975611e8d..e12db1b5f74c91679922985b451689c06694d44b 100644 (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;
index 357c8904625a55157ec865020e89eb83b1436b84..d71a1c0b23047c0ca7edcfef518915d027571063 100644 (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:
index a20053c4adbe56c292303ba1eea18c27563620f0..5a6c689f21975985c008b6c86692fafa9ca91d9f 100644 (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 */
index 2cc6a3bb605b2c0ecdf3b99d1ea66f2411dda8a0..0e240f50a9045f277e99858409ae67cc8de243fa 100644 (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"
index bfaf2649f2d0f675f0d5d1ffaf3866a54cdbc1a6..ae92d96faf9f4c1b0349cd2a3afde9e80d468672 100644 (file)
@@ -1174,6 +1174,172 @@ yyerror(msg)
    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.  */
 
@@ -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 */