* parse.c (write_exp_string): Complete rewrite to store string
authorFred Fish <fnf@specifix.com>
Wed, 25 Nov 1992 15:46:57 +0000 (15:46 +0000)
committerFred Fish <fnf@specifix.com>
Wed, 25 Nov 1992 15:46:57 +0000 (15:46 +0000)
contants as a leading explicit length, followed by the string data,
followed by a trailing explicit length.
* eval.c (evaluate_subexp), expprint.c (print_subexp),
parse.c (length_of_subexp), parse.c (prefixify_subexp):
Use recorded explicit length of strings in expression elements,
rather than strlen.  Adjust code to skip over strings stored in
expression elements, and code to access strings, to account for
new leading explicit size expression element.
* parse.c (length_of_subexp):  Test for minimum endpos of 1, not
0, to avoid negative expression element indices.
* valops.c (search_struct_method):  Minor whitespace change.

gdb/ChangeLog
gdb/parse.c

index 3ecc17526b4d186ede7e102e55e038e41a72ce44..e3c58f7c0c2e9fff5266783acf48025107262fd7 100644 (file)
@@ -1,3 +1,18 @@
+Wed Nov 25 07:17:13 1992  Fred Fish  (fnf@cygnus.com)
+
+       * parse.c (write_exp_string):  Complete rewrite to store string
+       contants as a leading explicit length, followed by the string data,
+       followed by a trailing explicit length.
+       * eval.c (evaluate_subexp), expprint.c (print_subexp),
+       parse.c (length_of_subexp), parse.c (prefixify_subexp):
+       Use recorded explicit length of strings in expression elements,
+       rather than strlen.  Adjust code to skip over strings stored in
+       expression elements, and code to access strings, to account for
+       new leading explicit size expression element.
+       * parse.c (length_of_subexp):  Test for minimum endpos of 1, not
+       0, to avoid negative expression element indices.
+       * valops.c (search_struct_method):  Minor whitespace change.    
+
 Mon Nov 23 11:14:15 1992  Fred Fish  (fnf@cygnus.com)
 
        * c-exp.y (yylex):  Add tempbuf, tempbufindex, and tempbufsize,
index 4090302f01fbd7807d4ac66d2dbfdf6daee6de57..2ce1ea7e522e040ff3fe5d956afd7d418995c13b 100644 (file)
@@ -200,27 +200,62 @@ write_exp_elt_intern (expelt)
 }
 
 /* Add a string constant to the end of the expression.
-   Follow it by its length in bytes, as a separate exp_element.  */
+
+   String constants are stored by first writing an expression element
+   that contains the length of the string, then stuffing the string
+   constant itself into however many expression elements are needed
+   to hold it, and then writing another expression element that contains
+   the length of the string.  I.E. an expression element at each end of
+   the string records the string length, so you can skip over the 
+   expression elements containing the actual string bytes from either
+   end of the string.  Note that this also allows gdb to handle
+   strings with embedded null bytes, as is required for some languages.
+
+   Don't be fooled by the fact that the string is null byte terminated,
+   this is strictly for the convenience of debugging gdb itself.  Gdb
+   Gdb does not depend up the string being null terminated, since the
+   actual length is recorded in expression elements at each end of the
+   string.  The null byte is taken into consideration when computing how
+   many expression elements are required to hold the string constant, of
+   course. */
+
 
 void
 write_exp_string (str)
      struct stoken str;
 {
   register int len = str.length;
-  register int lenelt
-    = (len + sizeof (union exp_element)) / sizeof (union exp_element);
+  register int lenelt;
+  register char *strdata;
 
-  expout_ptr += lenelt;
+  /* Compute the number of expression elements required to hold the string
+     (including a null byte terminator), along with one expression element
+     at each end to record the actual string length (not including the
+     null byte terminator). */
 
-  if (expout_ptr >= expout_size)
+  lenelt = 2 + (len + sizeof (union exp_element)) / sizeof (union exp_element);
+
+  /* Ensure that we have enough available expression elements to store
+     everything. */
+
+  if ((expout_ptr + lenelt) >= expout_size)
     {
-      expout_size = max (expout_size * 2, expout_ptr + 10);
+      expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
       expout = (struct expression *)
        xrealloc ((char *) expout, (sizeof (struct expression)
                           + (expout_size * sizeof (union exp_element))));
     }
-  memcpy ((char *) &expout->elts[expout_ptr - lenelt], str.ptr, len);
-  ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0;
+
+  /* Write the leading length expression element (which advances the current
+     expression element index), then write the string constant followed by a
+     terminating null byte, and then write the trailing length expression
+     element. */
+
+  write_exp_elt_longcst ((LONGEST) len);
+  strdata = (char *) &expout->elts[expout_ptr];
+  memcpy (strdata, str.ptr, len);
+  *(strdata + len) = '\0';
+  expout_ptr += lenelt - 2;
   write_exp_elt_longcst ((LONGEST) len);
 }
 \f
@@ -268,7 +303,7 @@ length_of_subexp (expr, endpos)
   register int args = 0;
   register int i;
 
-  if (endpos < 0)
+  if (endpos < 1)
     error ("?error in length_of_subexp");
 
   i = (int) expr->elts[endpos - 1].opcode;
@@ -277,7 +312,7 @@ length_of_subexp (expr, endpos)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 4 + ((expr->elts[endpos - 2].longconst
+      oplen = 5 + ((longest_to_int (expr->elts[endpos - 2].longconst)
                    + sizeof (union exp_element))
                   / sizeof (union exp_element));
       break;
@@ -298,13 +333,12 @@ length_of_subexp (expr, endpos)
 
     case OP_FUNCALL:
       oplen = 3;
-      args = 1 + expr->elts[endpos - 2].longconst;
+      args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
       break;
 
     case UNOP_MAX:
     case UNOP_MIN:
       oplen = 3;
-      args = 0;
       break;
 
    case BINOP_VAL:
@@ -329,9 +363,10 @@ length_of_subexp (expr, endpos)
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       args = 1;
+      /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 3 + ((expr->elts[endpos - 2].longconst
+      oplen = 4 + ((longest_to_int (expr->elts[endpos - 2].longconst)
                    + sizeof (union exp_element))
                   / sizeof (union exp_element));
       break;
@@ -343,7 +378,7 @@ length_of_subexp (expr, endpos)
       /* Modula-2 */
    case BINOP_MULTI_SUBSCRIPT:
       oplen=3;
-      args = 1 + expr->elts[endpos- 2].longconst;
+      args = 1 + longest_to_int (expr->elts[endpos- 2].longconst);
       break;
 
     case BINOP_ASSIGN_MODIFY:
@@ -395,7 +430,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 4 + ((inexpr->elts[inend - 2].longconst
+      oplen = 5 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
                    + sizeof (union exp_element))
                   / sizeof (union exp_element));
       break;
@@ -416,13 +451,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
 
     case OP_FUNCALL:
       oplen = 3;
-      args = 1 + inexpr->elts[inend - 2].longconst;
+      args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
 
     case UNOP_MIN:
     case UNOP_MAX:
       oplen = 3;
-      args = 0;
       break;
 
     case UNOP_CAST:
@@ -446,12 +480,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
    case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       args = 1;
+      /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 3 + ((inexpr->elts[inend - 2].longconst
+      oplen = 4 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
                    + sizeof (union exp_element))
                   / sizeof (union exp_element));
-                  
       break;
 
     case TERNOP_COND:
@@ -466,7 +500,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       /* Modula-2 */
    case BINOP_MULTI_SUBSCRIPT:
       oplen=3;
-      args = 1 + inexpr->elts[inend - 2].longconst;
+      args = 1 + longest_to_int (inexpr->elts[inend - 2].longconst);
       break;
 
       /* C++ */