[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.101,2.102 unicodeobject.c,2.81,2.82

Tim Peters tim_one@users.sourceforge.net
Thu, 12 Apr 2001 11:38:50 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv15600/python/dist/src/Objects

Modified Files:
	stringobject.c unicodeobject.c 
Log Message:
Bug 415514 reported that e.g.
    "%#x" % 0
blew up, at heart because C sprintf supplies a base marker if and only if
the value is not 0.  I then fixed that, by tolerating C's inconsistency
when it does %#x, and taking away that *Python* produced 0x0 when
formatting 0L (the "long" flavor of 0) under %#x itself.  But after talking
with Guido, we agreed it would be better to supply 0x for the short int
case too, despite that it's inconsistent with C, because C is inconsistent
with itself and with Python's hex(0) (plus, while "%#x" % 0 didn't work
before, "%#x" % 0L *did*, and returned "0x0").  Similarly for %#X conversion.


Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.101
retrieving revision 2.102
diff -C2 -r2.101 -r2.102
*** stringobject.c	2001/04/12 00:35:51	2.101
--- stringobject.c	2001/04/12 18:38:48	2.102
***************
*** 2576,2589 ****
  	assert(numdigits > 0);
  
! 	/* Get rid of base marker unless F_ALT.  Even if F_ALT, leading 0x
! 	 * must be stripped if the *value* is 0.
! 	 */
! 	if ((flags & F_ALT) == 0 ||
! 	    ((flags & F_ALT) &&
! 	     (type == 'x' || type == 'X') &&
! 	     numdigits == 1 &&
! 	     !sign &&
! 	     buf[2] == '0'
! 	    )) {
  		/* Need to skip 0x, 0X or 0. */
  		int skipped = 0;
--- 2576,2581 ----
  	assert(numdigits > 0);
  
! 	/* Get rid of base marker unless F_ALT */
! 	if ((flags & F_ALT) == 0) {
  		/* Need to skip 0x, 0X or 0. */
  		int skipped = 0;
***************
*** 2679,2682 ****
--- 2671,2684 ----
  	}
  	sprintf(buf, fmt, x);
+ 	/* When converting 0 under %#x or %#X, C leaves off the base marker,
+ 	 * but we want it (for consistency with other %#x conversions, and
+ 	 * for consistency with Python's hex() function).
+ 	 */
+ 	if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) {
+ 		assert(buf[1] != type);  /* else this C *is* adding 0x/0X */
+ 		memmove(buf+2, buf, strlen(buf) + 1);
+ 		buf[0] = '0';
+ 		buf[1] = (char)type;
+ 	}
  	return strlen(buf);
  }
***************
*** 3024,3042 ****
  			}
  			if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
- 				/* There's a base marker ("0x" or "0X") if and
- 				 * only if the value is non-zero.
- 				 */
  				assert(pbuf[0] == '0');
! 				if (pbuf[1] == c) {
! 					if (fill != ' ') {
! 						*res++ = *pbuf++;
! 						*res++ = *pbuf++;
! 					}
! 					rescnt -= 2;
! 					width -= 2;
! 					if (width < 0)
! 						width = 0;
! 					len -= 2;
! 				}
  			}
  			if (width > len && !(flags & F_LJUST)) {
--- 3026,3040 ----
  			}
  			if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
  				assert(pbuf[0] == '0');
! 				assert(pbuf[1] == c);
! 				if (fill != ' ') {
! 					*res++ = *pbuf++;
! 					*res++ = *pbuf++;
! 				}
! 				rescnt -= 2;
! 				width -= 2;
! 				if (width < 0)
! 					width = 0;
! 				len -= 2;
  			}
  			if (width > len && !(flags & F_LJUST)) {
***************
*** 3050,3055 ****
  					*res++ = sign;
  				if ((flags & F_ALT) &&
! 				    (c == 'x' || c == 'X') &&
! 				    pbuf[1] == c) {
  					*res++ = *pbuf++;
  					*res++ = *pbuf++;
--- 3048,3054 ----
  					*res++ = sign;
  				if ((flags & F_ALT) &&
! 				    (c == 'x' || c == 'X')) {
! 					assert(pbuf[0] == '0');
! 					assert(pbuf[1] == c);
  					*res++ = *pbuf++;
  					*res++ = *pbuf++;

Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.81
retrieving revision 2.82
diff -C2 -r2.81 -r2.82
*** unicodeobject.c	2001/04/12 00:35:51	2.81
--- unicodeobject.c	2001/04/12 18:38:48	2.82
***************
*** 4684,4688 ****
          return -1;
      }
!     sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
      return usprintf(buf, fmt, x);
  }
--- 4684,4695 ----
          return -1;
      }
!     /* When converting 0 under %#x or %#X, C leaves off the base marker,
!      * but we want it (for consistency with other %#x conversions, and
!      * for consistency with Python's hex() function).
!      */
!     if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X'))
!         sprintf(fmt, "0%c%%%s.%dl%c", type, "#", prec, type);
!     else
!         sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
      return usprintf(buf, fmt, x);
  }
***************
*** 5082,5096 ****
  	    if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
  		assert(pbuf[0] == '0');
! 		if (pbuf[1] == c) {
! 			if (fill != ' ') {
! 			    *res++ = *pbuf++;
! 			    *res++ = *pbuf++;
! 			}
! 			rescnt -= 2;
! 			width -= 2;
! 			if (width < 0)
! 			    width = 0;
! 			len -= 2;
! 		}
  	    }
  	    if (width > len && !(flags & F_LJUST)) {
--- 5089,5102 ----
  	    if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
  		assert(pbuf[0] == '0');
! 		assert(pbuf[1] == c);
! 		if (fill != ' ') {
! 		    *res++ = *pbuf++;
! 		    *res++ = *pbuf++;
! 		}
! 		rescnt -= 2;
! 		width -= 2;
! 		if (width < 0)
! 		    width = 0;
! 		len -= 2;
  	    }
  	    if (width > len && !(flags & F_LJUST)) {
***************
*** 5103,5109 ****
  		if (sign)
  		    *res++ = sign;
! 		if ((flags & F_ALT) && (c == 'x' || c == 'X') &&
! 		    pbuf[1] == c) {
  		    assert(pbuf[0] == '0');
  		    *res++ = *pbuf++;
  		    *res++ = *pbuf++;
--- 5109,5115 ----
  		if (sign)
  		    *res++ = sign;
! 		if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
  		    assert(pbuf[0] == '0');
+ 		    assert(pbuf[1] == c);
  		    *res++ = *pbuf++;
  		    *res++ = *pbuf++;