Date: Thu, 17 Jun 1999 10:32:51 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: Robert Hoehne cc: djgpp-workers AT delorie DOT com Subject: Entering float/long double values in GDB Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com The following changes correct the bug in GDB 4.18 whereby it would refuse to accept long double or float numbers that end with L or F when debugging a C/C++ program, and a similar bug in Java support. It seems that either nobody has ever tried to use that feature (it's undocumented, btw), or there are some versions of sscanf out there which eat up the suffix as part of floating point conversion, although ANSI and Posix explicitly forbid that. These are generic GDB bugs, so perhaps I should report them elsewhere? *** gdb/c-exp.y~0 Wed Jan 6 16:52:16 1999 --- gdb/c-exp.y Wed Jun 16 21:36:30 1999 *************** parse_number (p, len, parsed_float, puti *** 947,976 **** if (parsed_float) { /* It's a float since it contains a point or an exponent. */ ! char c; int num = 0; /* number of tokens scanned by scanf */ char saved_char = p[len]; p[len] = 0; /* null-terminate the token */ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) ! num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c); else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) ! num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c); else { #ifdef SCANF_HAS_LONG_DOUBLE ! num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c); #else /* Scan it into a double, then assign it to the long double. This at least wins with values representable in the range of doubles. */ double temp; ! num = sscanf (p, "%lg%c", &temp,&c); putithere->typed_val_float.dval = temp; #endif } p[len] = saved_char; /* restore the input stream */ ! if (num != 1) /* check scanf found ONLY a float ... */ return ERROR; /* See if it has `f' or `l' suffix (float or long double). */ --- 947,977 ---- if (parsed_float) { /* It's a float since it contains a point or an exponent. */ ! char c = 0, c2; int num = 0; /* number of tokens scanned by scanf */ char saved_char = p[len]; p[len] = 0; /* null-terminate the token */ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) ! num = sscanf (p, "%g%c%c", (float *) &putithere->typed_val_float.dval,&c,&c2); else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) ! num = sscanf (p, "%lg%c%c", (double *) &putithere->typed_val_float.dval,&c,&c2); else { #ifdef SCANF_HAS_LONG_DOUBLE ! num = sscanf (p, "%Lg%c%c", &putithere->typed_val_float.dval,&c,&c2); #else /* Scan it into a double, then assign it to the long double. This at least wins with values representable in the range of doubles. */ double temp; ! num = sscanf (p, "%lg%c%c", &temp,&c,&c2); putithere->typed_val_float.dval = temp; #endif } p[len] = saved_char; /* restore the input stream */ ! if (num > 2 /* check scanf found ONLY a float ... */ ! || (num == 2 && strchr ("lLfF.", c) == NULL)) return ERROR; /* See if it has `f' or `l' suffix (float or long double). */ *** gdb/jv-exp.y~0 Thu Mar 4 20:56:38 1999 --- gdb/jv-exp.y Wed Jun 16 21:41:04 1999 *************** parse_number (p, len, parsed_float, puti *** 697,734 **** if (parsed_float) { /* It's a float since it contains a point or an exponent. */ ! char c; int num = 0; /* number of tokens scanned by scanf */ char saved_char = p[len]; p[len] = 0; /* null-terminate the token */ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) ! num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c); else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) ! num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c); else { #ifdef SCANF_HAS_LONG_DOUBLE ! num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c); #else /* Scan it into a double, then assign it to the long double. This at least wins with values representable in the range of doubles. */ double temp; ! num = sscanf (p, "%lg%c", &temp, &c); putithere->typed_val_float.dval = temp; #endif } p[len] = saved_char; /* restore the input stream */ ! if (num != 1) /* check scanf found ONLY a float ... */ return ERROR; /* See if it has `f' or `d' suffix (float or double). */ c = tolower (p[len - 1]); ! if (c == 'f' || c == 'F') putithere->typed_val_float.type = builtin_type_float; ! else if (isdigit (c) || c == '.' || c == 'd' || c == 'D') putithere->typed_val_float.type = builtin_type_double; else return ERROR; --- 697,735 ---- if (parsed_float) { /* It's a float since it contains a point or an exponent. */ ! char c = 0, c2; int num = 0; /* number of tokens scanned by scanf */ char saved_char = p[len]; p[len] = 0; /* null-terminate the token */ if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) ! num = sscanf (p, "%g%c%c", (float *) &putithere->typed_val_float.dval, &c, &c2); else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) ! num = sscanf (p, "%lg%c%c", (double *) &putithere->typed_val_float.dval, &c, &c2); else { #ifdef SCANF_HAS_LONG_DOUBLE ! num = sscanf (p, "%Lg%c%c", &putithere->typed_val_float.dval,&c,&c2); #else /* Scan it into a double, then assign it to the long double. This at least wins with values representable in the range of doubles. */ double temp; ! num = sscanf (p, "%lg%c%c", &temp, &c, &c2); putithere->typed_val_float.dval = temp; #endif } p[len] = saved_char; /* restore the input stream */ ! if (num > 2 /* check scanf found ONLY a float ... */ ! || (num == 2 && strchr ("fFdD.", c) == NULL)) return ERROR; /* See if it has `f' or `d' suffix (float or double). */ c = tolower (p[len - 1]); ! if (c == 'f') putithere->typed_val_float.type = builtin_type_float; ! else if (isdigit (c) || c == '.' || c == 'd') putithere->typed_val_float.type = builtin_type_double; else return ERROR;