[Python-checkins] python/dist/src/Python ast.c,1.1.2.14,1.1.2.15

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Tue, 25 Mar 2003 11:09:21 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv5930/Python

Modified Files:
      Tag: ast-branch
	ast.c 
Log Message:
Copied a small mountain of code for parsing string literals from
compile.c, and fiddled it just enough to compile in this new context.
Nothing calls it yet.


Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.14
retrieving revision 1.1.2.15
diff -C2 -d -r1.1.2.14 -r1.1.2.15
*** ast.c	24 Mar 2003 21:36:49 -0000	1.1.2.14
--- ast.c	25 Mar 2003 19:09:16 -0000	1.1.2.15
***************
*** 26,30 ****
  static expr_ty ast_for_call(const node *, expr_ty);
  
! static PyObject *parsenumber(char *);
  
  extern grammar _PyParser_Grammar; /* From graminit.c */
--- 26,32 ----
  static expr_ty ast_for_call(const node *, expr_ty);
  
! static PyObject *parsenumber(const char *);
! static PyObject *parsestr(const char *s);
! static PyObject *parsestrplus(node *n);
  
  extern grammar _PyParser_Grammar; /* From graminit.c */
***************
*** 1445,1451 ****
  
  static PyObject *
! parsenumber(char *s)
  {
! 	char *end;
  	long x;
  	double dx;
--- 1447,1453 ----
  
  static PyObject *
! parsenumber(const char *s)
  {
! 	const char *end;
  	long x;
  	double dx;
***************
*** 1461,1472 ****
  #endif
  	if (*end == 'l' || *end == 'L')
! 		return PyLong_FromString(s, (char **)0, 0);
  	if (s[0] == '0')
! 		x = (long) PyOS_strtoul((char *)s, &end, 0);
  	else
! 		x = PyOS_strtol(s, &end, 0);
  	if (*end == '\0') {
  		if (errno != 0)
! 			return PyLong_FromString(s, (char **)0, 0);
  		return PyInt_FromLong(x);
  	}
--- 1463,1474 ----
  #endif
  	if (*end == 'l' || *end == 'L')
! 		return PyLong_FromString((char *)s, (char **)0, 0);
  	if (s[0] == '0')
! 		x = (long) PyOS_strtoul((char *)s, (char **)&end, 0);
  	else
! 		x = PyOS_strtol((char *)s, (char **)&end, 0);
  	if (*end == '\0') {
  		if (errno != 0)
! 			return PyLong_FromString((char *)s, (char **)0, 0);
  		return PyInt_FromLong(x);
  	}
***************
*** 1488,1490 ****
--- 1490,1675 ----
  		return PyFloat_FromDouble(dx);
  	}
+ }
+ 
+ static PyObject *
+ parsestr(const char *s)
+ {
+ 	PyObject *v;
+ 	size_t len;
+ 	char *buf;
+ 	char *p;
+ 	const char *end;
+ 	int c;
+ 	int first = *s;
+ 	int quote = first;
+ 	int rawmode = 0;
+ 	int unicode = 0;
+ 
+ 	if (isalpha(quote) || quote == '_') {
+ 		if (quote == 'u' || quote == 'U') {
+ 			quote = *++s;
+ 			unicode = 1;
+ 		}
+ 		if (quote == 'r' || quote == 'R') {
+ 			quote = *++s;
+ 			rawmode = 1;
+ 		}
+ 	}
+ 	if (quote != '\'' && quote != '\"') {
+ 		PyErr_BadInternalCall();
+ 		return NULL;
+ 	}
+ 	s++;
+ 	len = strlen(s);
+ 	if (len > INT_MAX) {
+ 		PyErr_SetString(PyExc_OverflowError, 
+ 			  "string to parse is too long");
+ 		return NULL;
+ 	}
+ 	if (s[--len] != quote) {
+ 		PyErr_BadInternalCall();
+ 		return NULL;
+ 	}
+ 	if (len >= 4 && s[0] == quote && s[1] == quote) {
+ 		s += 2;
+ 		len -= 2;
+ 		if (s[--len] != quote || s[--len] != quote) {
+ 			PyErr_BadInternalCall();
+ 			return NULL;
+ 		}
+ 	}
+ #ifdef Py_USING_UNICODE
+ 	if (unicode || Py_UnicodeFlag) {
+ 		if (rawmode)
+ 			v = PyUnicode_DecodeRawUnicodeEscape(
+ 				 s, len, NULL);
+ 		else
+ 			v = PyUnicode_DecodeUnicodeEscape(
+ 				s, len, NULL);
+ 		return v;
+ 			
+ 	}
+ #endif
+ 	if (rawmode || strchr(s, '\\') == NULL)
+ 		return PyString_FromStringAndSize(s, len);
+ 	v = PyString_FromStringAndSize((char *)NULL, len);
+ 	if (v == NULL)
+ 		return NULL;
+ 	p = buf = PyString_AsString(v);
+ 	end = s + len;
+ 	while (s < end) {
+ 		if (*s != '\\') {
+ 			*p++ = *s++;
+ 			continue;
+ 		}
+ 		s++;
+ 		switch (*s++) {
+ 		/* XXX This assumes ASCII! */
+ 		case '\n': break;
+ 		case '\\': *p++ = '\\'; break;
+ 		case '\'': *p++ = '\''; break;
+ 		case '\"': *p++ = '\"'; break;
+ 		case 'b': *p++ = '\b'; break;
+ 		case 'f': *p++ = '\014'; break; /* FF */
+ 		case 't': *p++ = '\t'; break;
+ 		case 'n': *p++ = '\n'; break;
+ 		case 'r': *p++ = '\r'; break;
+ 		case 'v': *p++ = '\013'; break; /* VT */
+ 		case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+ 		case '0': case '1': case '2': case '3':
+ 		case '4': case '5': case '6': case '7':
+ 			c = s[-1] - '0';
+ 			if ('0' <= *s && *s <= '7') {
+ 				c = (c<<3) + *s++ - '0';
+ 				if ('0' <= *s && *s <= '7')
+ 					c = (c<<3) + *s++ - '0';
+ 			}
+ 			*p++ = c;
+ 			break;
+ 		case 'x':
+ 			if (isxdigit(Py_CHARMASK(s[0])) 
+ 			    && isxdigit(Py_CHARMASK(s[1]))) {
+ 				unsigned int x = 0;
+ 				c = Py_CHARMASK(*s);
+ 				s++;
+ 				if (isdigit(c))
+ 					x = c - '0';
+ 				else if (islower(c))
+ 					x = 10 + c - 'a';
+ 				else
+ 					x = 10 + c - 'A';
+ 				x = x << 4;
+ 				c = Py_CHARMASK(*s);
+ 				s++;
+ 				if (isdigit(c))
+ 					x += c - '0';
+ 				else if (islower(c))
+ 					x += 10 + c - 'a';
+ 				else
+ 					x += 10 + c - 'A';
+ 				*p++ = x;
+ 				break;
+ 			}
+ 			Py_DECREF(v);
+ 			PyErr_SetString(PyExc_ValueError, 
+ 				  "invalid \\x escape");
+ 			return NULL;
+ #ifndef Py_USING_UNICODE
+ 		case 'u':
+ 		case 'U':
+ 		case 'N':
+ 			if (unicode) {
+ 				Py_DECREF(v);
+ 				com_error(com, PyExc_ValueError,
+ 					  "Unicode escapes not legal "
+ 					  "when Unicode disabled");
+ 				return NULL;
+ 			}
+ #endif
+ 		default:
+ 			*p++ = '\\';
+ 			*p++ = s[-1];
+ 			break;
+ 		}
+ 	}
+ 	_PyString_Resize(&v, (int)(p - buf));
+ 	return v;
+ }
+ 
+ static PyObject *
+ parsestrplus(node *n)
+ {
+ 	PyObject *v;
+ 	int i;
+ 	REQ(CHILD(n, 0), STRING);
+ 	if ((v = parsestr(STR(CHILD(n, 0)))) != NULL) {
+ 		/* String literal concatenation */
+ 		for (i = 1; i < NCH(n); i++) {
+ 		    PyObject *s;
+ 		    s = parsestr(STR(CHILD(n, i)));
+ 		    if (s == NULL)
+ 			goto onError;
+ 		    if (PyString_Check(v) && PyString_Check(s)) {
+ 			PyString_ConcatAndDel(&v, s);
+ 			if (v == NULL)
+ 			    goto onError;
+ 		    }
+ #ifdef Py_USING_UNICODE
+ 		    else {
+ 			PyObject *temp;
+ 			temp = PyUnicode_Concat(v, s);
+ 			Py_DECREF(s);
+ 			if (temp == NULL)
+ 			    goto onError;
+ 			Py_DECREF(v);
+ 			v = temp;
+ 		    }
+ #endif
+ 		}
+ 	}
+ 	return v;
+ 
+  onError:
+ 	Py_XDECREF(v);
+ 	return NULL;
  }