/* String object implementation */#include "Python.h"#include <ctype.h>#ifdef COUNT_ALLOCSintnull_strings,one_strings;#endif#if !defined(HAVE_LIMITS_H) && !defined(UCHAR_MAX)#define UCHAR_MAX 255#endifstaticPyStringObject*characters[UCHAR_MAX+1];#ifndef DONT_SHARE_SHORT_STRINGSstaticPyStringObject*nullstring;#endif/* PyString_FromStringAndSize() and PyString_FromString() try in certain cases to share string objects. When the size of the string is zero, these routines always return a pointer to the same string object; when the size is one, they return a pointer to an already existing object if the contents of the string is known. For PyString_FromString() this is always the case, for PyString_FromStringAndSize() this is the case when the first argument in not NULL. A common practice of allocating a string and then filling it in or changing it must be done carefully. It is only allowed to change the contents of the string if the object was gotten from PyString_FromStringAndSize() with a NULL first argument, because in the future these routines may try to do even more sharing of objects. The string in the `str' parameter does not have to be null-character terminated. (Therefore it is safe to construct a substring by using `PyString_FromStringAndSize(origstring, substrlen)'.) The parameter `size' denotes number of characters to allocate, not counting the null terminating character. If the `str' argument is not NULL, then it points to a of length `size'. For PyString_FromString, this string must be null-terminated. The member `op->ob_size' denotes the number of bytes of data in the string, not counting the null terminating character, and is therefore equal to the `size' parameter.*/PyObject*PyString_FromStringAndSize(constchar*str,intsize){registerPyStringObject*op;#ifndef DONT_SHARE_SHORT_STRINGSif(size==0&&(op=nullstring)!=NULL){#ifdef COUNT_ALLOCSnull_strings++;#endifPy_INCREF(op);return(PyObject*)op;}if(size==1&&str!=NULL&&(op=characters[*str&UCHAR_MAX])!=NULL){#ifdef COUNT_ALLOCSone_strings++;#endifPy_INCREF(op);return(PyObject*)op;}#endif /* DONT_SHARE_SHORT_STRINGS *//* PyObject_NewVar is inlined */op=(PyStringObject*)PyObject_MALLOC(sizeof(PyStringObject)+size*sizeof(char));if(op==NULL)returnPyErr_NoMemory();PyObject_INIT_VAR(op,&PyString_Type,size);#ifdef CACHE_HASHop->ob_shash=-1;#endif#ifdef INTERN_STRINGSop->ob_sinterned=NULL;#endifif(str!=NULL)memcpy(op->ob_sval,str,size);op->ob_sval[size]='\0';#ifndef DONT_SHARE_SHORT_STRINGSif(size==0){PyObject*t=(PyObject*)op;PyString_InternInPlace(&t);op=(PyStringObject*)t;nullstring=op;Py_INCREF(op);}elseif(size==1&&str!=NULL){PyObject*t=(PyObject*)op;PyString_InternInPlace(&t);op=(PyStringObject*)t;characters[*str&UCHAR_MAX]=op;Py_INCREF(op);}#endifreturn(PyObject*)op;}PyObject*PyString_FromString(constchar*str){registersize_tsize;registerPyStringObject*op;assert(str!=NULL);size=strlen(str);if(size>INT_MAX){PyErr_SetString(PyExc_OverflowError,"string is too long for a Python string");returnNULL;}#ifndef DONT_SHARE_SHORT_STRINGSif(size==0&&(op=nullstring)!=NULL){#ifdef COUNT_ALLOCSnull_strings++;#endifPy_INCREF(op);return(PyObject*)op;}if(size==1&&(op=characters[*str&UCHAR_MAX])!=NULL){#ifdef COUNT_ALLOCSone_strings++;#endifPy_INCREF(op);return(PyObject*)op;}#endif /* DONT_SHARE_SHORT_STRINGS *//* PyObject_NewVar is inlined */op=(PyStringObject*)PyObject_MALLOC(sizeof(PyStringObject)+size*sizeof(char));if(op==NULL)returnPyErr_NoMemory();PyObject_INIT_VAR(op,&PyString_Type,size);#ifdef CACHE_HASHop->ob_shash=-1;#endif#ifdef INTERN_STRINGSop->ob_sinterned=NULL;#endifmemcpy(op->ob_sval,str,size+1);#ifndef DONT_SHARE_SHORT_STRINGSif(size==0){PyObject*t=(PyObject*)op;PyString_InternInPlace(&t);op=(PyStringObject*)t;nullstring=op;Py_INCREF(op);}elseif(size==1){PyObject*t=(PyObject*)op;PyString_InternInPlace(&t);op=(PyStringObject*)t;characters[*str&UCHAR_MAX]=op;Py_INCREF(op);}#endifreturn(PyObject*)op;}PyObject*PyString_FromFormatV(constchar*format,va_listvargs){va_listcount;intn=0;constchar*f;char*s;PyObject*string;#ifdef VA_LIST_IS_ARRAYmemcpy(count,vargs,sizeof(va_list));#else#ifdef __va_copy__va_copy(count,vargs);#elsecount=vargs;#endif#endif/* step 1: figure out how large a buffer we need */for(f=format;*f;f++){if(*f=='%'){constchar*p=f;while(*++f&&*f!='%'&&!isalpha(Py_CHARMASK(*f)));/* skip the 'l' in %ld, since it doesn't change the width. although only %d is supported (see "expand" section below), others can be easily added */if(*f=='l'&&*(f+1)=='d')++f;switch(*f){case'c':(void)va_arg(count,int);/* fall through... */case'%':n++;break;case'd':case'i':case'x':(void)va_arg(count,int);/* 20 bytes is enough to hold a 64-bit integer. Decimal takes the most space. This isn't enough for octal. */n+=20;break;case's':s=va_arg(count,char*);n+=strlen(s);break;case'p':(void)va_arg(count,int);/* maximum 64-bit pointer representation: * 0xffffffffffffffff * so 19 characters is enough. * XXX I count 18 -- what's the extra for? */n+=19;break;default:/* if we stumble upon an unknown formatting code, copy the rest of the format string to the output string. (we cannot just skip the code, since there's no way to know what's in the argument list) */n+=strlen(p);gotoexpand;}}elsen++;}expand:/* step 2: fill the buffer *//* Since we've analyzed how much space we need for the worst case, use sprintf directly instead of the slower PyOS_snprintf. */string=PyString_FromStringAndSize(NULL,n);if(!string)returnNULL;s=PyString_AsString(string);for(f=format;*f;f++){if(*f=='%'){constchar*p=f++;inti,longflag=0;/* parse the width.precision part (we're only interested in the precision value, if any) */n=0;while(isdigit(Py_CHARMASK(*f)))n=(n*10)+*f++-'0';if(*f=='.'){f++;n=0;while(isdigit(Py_CHARMASK(*f)))n=(n*10)+*f++-'0';}while(*f&&*f!='%'&&!isalpha(Py_CHARMASK(*f)))f++;/* handle the long flag, but only for %ld. others can be added when necessary. */if(*f=='l'&&*(f+1)=='d'){longflag=1;++f;}switch(*f){case'c':*s++=va_arg(vargs,int);break;case'd':if(longflag)sprintf(s,"%ld",va_arg(vargs,long));elsesprintf(s,"%d",va_arg(vargs,int));s+=strlen(s);break;case'i':sprintf(s,"%i",va_arg(vargs,int));s+=strlen(s);break;case'x':sprintf(s,"%x",va_arg(vargs,int));s+=strlen(s);break;case's':p=va_arg(vargs,char*);i=strlen(p);if(n>0&&i>n)i=n;memcpy(s,p,i);s+=i;break;case'p':sprintf(s,"%p",va_arg(vargs,void*));/* %p is ill-defined: ensure leading 0x. */if(s[1]=='X')s[1]='x';elseif(s[1]!='x'){memmove(s+2,s,strlen(s)+1);s[0]='0';s[1]='x';}s+=strlen(s);break;case'%':*s++='%';break;default:strcpy(s,p);s+=strlen(s);gotoend;}}else*s++=*f;}end:_PyString_Resize(&string,s-PyString_AS_STRING(string));returnstring;}PyObject*PyString_FromFormat(constchar*format,...){PyObject*ret;va_listvargs;#ifdef HAVE_STDARG_PROTOTYPESva_start(vargs,format);#elseva_start(vargs);#endifret=PyString_FromFormatV(format,vargs);va_end(vargs);returnret;}PyObject*PyString_Decode(constchar*s,intsize,constchar*encoding,constchar*errors){PyObject*v,*str;str=PyString_FromStringAndSize(s,size);if(str==NULL)returnNULL;v=PyString_AsDecodedString(str,encoding,errors);Py_DECREF(str);returnv;}PyObject*PyString_AsDecodedObject(PyObject*str,constchar*encoding,constchar*errors){PyObject*v;if(!PyString_Check(str)){PyErr_BadArgument();gotoonError;}if(encoding==NULL){#ifdef Py_USING_UNICODEencoding=PyUnicode_GetDefaultEncoding();#elsePyErr_SetString(PyExc_ValueError,"no encoding specified");gotoonError;#endif}/* Decode via the codec registry */v=PyCodec_Decode(str,encoding,errors);if(v==NULL)gotoonError;returnv;onError:returnNULL;}PyObject*PyString_AsDecodedString(PyObject*str,constchar*encoding,constchar*errors){PyObject*v;v=PyString_AsDecodedObject(str,encoding,errors);if(v==NULL)gotoonError;#ifdef Py_USING_UNICODE/* Convert Unicode to a string using the default encoding */if(PyUnicode_Check(v)){PyObject*temp=v;v=PyUnicode_AsEncodedString(v,NULL,NULL);Py_DECREF(temp);if(v==NULL)gotoonError;}#endifif(!PyString_Check(v)){PyErr_Format(PyExc_TypeError,"decoder did not return a string object (type=%.400s)",v->ob_type->tp_name);Py_DECREF(v);gotoonError;}returnv;onError:returnNULL;}PyObject*PyString_Encode(constchar*s,intsize,constchar*encoding,constchar*errors){PyObject*v,*str;str=PyString_FromStringAndSize(s,size);if(str==NULL)returnNULL;v=PyString_AsEncodedString(str,encoding,errors);Py_DECREF(str);returnv;}PyObject*PyString_AsEncodedObject(PyObject*str,constchar*encoding,constchar*errors){PyObject*v;if(!PyString_Check(str)){PyErr_BadArgument();gotoonError;}if(encoding==NULL){#ifdef Py_USING_UNICODEencoding=PyUnicode_GetDefaultEncoding();#elsePyErr_SetString(PyExc_ValueError,"no encoding specified");gotoonError;#endif}/* Encode via the codec registry */v=PyCodec_Encode(str,encoding,errors);if(v==NULL)gotoonError;returnv;onError:returnNULL;}PyObject*PyString_AsEncodedString(PyObject*str,constchar*encoding,constchar*errors){PyObject*v;v=PyString_AsEncodedObject(str,encoding,errors);if(v==NULL)gotoonError;#ifdef Py_USING_UNICODE/* Convert Unicode to a string using the default encoding */if(PyUnicode_Check(v)){PyObject*temp=v;v=PyUnicode_AsEncodedString(v,NULL,NULL);Py_DECREF(temp);if(v==NULL)gotoonError;}#endifif(!PyString_Check(v)){PyErr_Format(PyExc_TypeError,"encoder did not return a string object (type=%.400s)",v->ob_type->tp_name);Py_DECREF(v);gotoonError;}returnv;onError:returnNULL;}staticvoidstring_dealloc(PyObject*op){op->ob_type->tp_free(op);}staticintstring_getsize(registerPyObject*op){char*s;intlen;if(PyString_AsStringAndSize(op,&s,&len))return-1;returnlen;}static/*const*/char*string_getbuffer(registerPyObject*op){char*s;intlen;if(PyString_AsStringAndSize(op,&s,&len))returnNULL;returns;}intPyString_Size(registerPyObject*op){if(!PyString_Check(op))returnstring_getsize(op);return((PyStringObject*)op)->ob_size;}/*const*/char*PyString_AsString(registerPyObject*op){if(!PyString_Check(op))returnstring_getbuffer(op);return((PyStringObject*)op)->ob_sval;}intPyString_AsStringAndSize(registerPyObject*obj,registerchar**s,registerint*len){if(s==NULL){PyErr_BadInternalCall();return-1;}if(!PyString_Check(obj)){#ifdef Py_USING_UNICODEif(PyUnicode_Check(obj)){obj=_PyUnicode_AsDefaultEncodedString(obj,NULL);if(obj==NULL)return-1;}else#endif{PyErr_Format(PyExc_TypeError,"expected string or Unicode object, ""%.200s found",obj->ob_type->tp_name);return-1;}}*s=PyString_AS_STRING(obj);if(len!=NULL)*len=PyString_GET_SIZE(obj);elseif((int)strlen(*s)!=PyString_GET_SIZE(obj)){PyErr_SetString(PyExc_TypeError,"expected string without null bytes");return-1;}return0;}/* Methods */staticintstring_print(PyStringObject*op,FILE*fp,intflags){inti;charc;intquote;/* XXX Ought to check for interrupts when writing long strings */if(!PyString_CheckExact(op)){intret;/* A str subclass may have its own __str__ method. */op=(PyStringObject*)PyObject_Str((PyObject*)op);if(op==NULL)return-1;ret=string_print(op,fp,flags);Py_DECREF(op);returnret;}if(flags&Py_PRINT_RAW){fwrite(op->ob_sval,1,(int)op->ob_size,fp);return0;}/* figure out which quote to use; single is preferred */quote='\'';if(strchr(op->ob_sval,'\'')&&!strchr(op->ob_sval,'"'))quote='"';fputc(quote,fp);for(i=0;i<op->ob_size;i++){c=op->ob_sval[i];if(c==quote||c=='\\')fprintf(fp,"\\%c",c);elseif(c=='\t')fprintf(fp,"\\t");elseif(c=='\n')fprintf(fp,"\\n");elseif(c=='\r')fprintf(fp,"\\r");elseif(c<' '||c>=0x7f)fprintf(fp,"\\x%02x",c&0xff);elsefputc(c,fp);}fputc(quote,fp);return0;}staticPyObject*string_repr(registerPyStringObject*op){size_tnewsize=2+4*op->ob_size*sizeof(char);PyObject*v;if(newsize>INT_MAX){PyErr_SetString(PyExc_OverflowError,"string is too large to make repr");}v=PyString_FromStringAndSize((char*)NULL,newsize);if(v==NULL){returnNULL;}else{registerinti;registercharc;registerchar*p;intquote;/* figure out which quote to use; single is preferred */quote='\'';if(strchr(op->ob_sval,'\'')&&!strchr(op->ob_sval,'"'))quote='"';p=PyString_AS_STRING(v);*p++=quote;for(i=0;i<op->ob_size;i++){/* There's at least enough room for a hex escape and a closing quote. */assert(newsize-(p-PyString_AS_STRING(v))>=5);c=op->ob_sval[i];if(c==quote||c=='\\')*p++='\\',*p++=c;elseif(c=='\t')*p++='\\',*p++='t';elseif(c=='\n')*p++='\\',*p++='n';elseif(c=='\r')*p++='\\',*p++='r';elseif(c<' '||c>=0x7f){/* For performance, we don't want to call PyOS_snprintf here (extra layers of function call). */sprintf(p,"\\x%02x",c&0xff);p+=4;}else*p++=c;}assert(newsize-(p-PyString_AS_STRING(v))>=1);*p++=quote;*p='\0';_PyString_Resize(&v,(int)(p-PyString_AS_STRING(v)));returnv;}}staticPyObject*string_str(PyObject*s){assert(PyString_Check(s));if(PyString_CheckExact(s)){Py_INCREF(s);returns;}else{/* Subtype -- return genuine string with the same value. */PyStringObject*t=(PyStringObject*)s;returnPyString_FromStringAndSize(t->ob_sval,t->ob_size);}}staticintstring_length(PyStringObject*a){returna->ob_size;}staticPyObject*string_concat(registerPyStringObject*a,registerPyObject*bb){registerunsignedintsize;registerPyStringObject*op;if(!PyString_Check(bb)){#ifdef Py_USING_UNICODEif(PyUnicode_Check(bb))returnPyUnicode_Concat((PyObject*)a,bb);#endifPyErr_Format(PyExc_TypeError,"cannot concatenate 'str' and '%.200s' objects",bb->ob_type->tp_name);returnNULL;}#define b ((PyStringObject *)bb)/* Optimize cases with empty left or right operand */if((a->ob_size==0||b->ob_size==0)&&PyString_CheckExact(a)&&PyString_CheckExact(b)){if(a->ob_size==0){Py_INCREF(bb);returnbb;}Py_INCREF(a);return(PyObject*)a;}size=a->ob_size+b->ob_size;/* PyObject_NewVar is inlined */op=(PyStringObject*)PyObject_MALLOC(sizeof(PyStringObject)+size*sizeof(char));if(op==NULL)returnPyErr_NoMemory();PyObject_INIT_VAR(op,&PyString_Type,size);#ifdef CACHE_HASHop->ob_shash=-1;#endif#ifdef INTERN_STRINGSop->ob_sinterned=NULL;#endifmemcpy(op->ob_sval,a->ob_sval,(int)a->ob_size);memcpy(op->ob_sval+a->ob_size,b->ob_sval,(int)b->ob_size);op->ob_sval[size]='\0';return(PyObject*)op;#undef b}staticPyObject*string_repeat(registerPyStringObject*a,registerintn){registerinti;registerintsize;registerPyStringObject*op;size_tnbytes;if(n<0)n=0;/* watch out for overflows: the size can overflow int, * and the # of bytes needed can overflow size_t */size=a->ob_size*n;if(n&&size/n!=a->ob_size){PyErr_SetString(PyExc_OverflowError,"repeated string is too long");returnNULL;}if(size==a->ob_size&&PyString_CheckExact(a)){Py_INCREF(a);return(PyObject*)a;}nbytes=size*sizeof(char);if(nbytes/sizeof(char)!=(size_t)size||nbytes+sizeof(PyStringObject)<=nbytes){PyErr_SetString(PyExc_OverflowError,"repeated string is too long");returnNULL;}op=(PyStringObject*)PyObject_MALLOC(sizeof(PyStringObject)+nbytes);if(op==NULL)returnPyErr_NoMemory();PyObject_INIT_VAR(op,&PyString_Type,size);#ifdef CACHE_HASHop->ob_shash=-1;#endif#ifdef INTERN_STRINGSop->ob_sinterned=NULL;#endiffor(i=0;i<size;i+=a->ob_size)memcpy(op->ob_sval+i,a->ob_sval,(int)a->ob_size);op->ob_sval[size]='\0';return(PyObject*)op;}/* String slice a[i:j] consists of characters a[i] ... a[j-1] */staticPyObject*string_slice(registerPyStringObject*a,registerinti,registerintj)/* j -- may be negative! */{if(i<0)i=0;if(j<0)j=0;/* Avoid signed/unsigned bug in next line */if(j>a->ob_size)j=a->ob_size;if(i==0&&j==a->ob_size&&PyString_CheckExact(a)){/* It's the same as a */Py_INCREF(a);return(PyObject*)a;}if(j<i)j=i;returnPyString_FromStringAndSize(a->ob_sval+i,(int)(j-i));}staticintstring_contains(PyObject*a,PyObject*el){registerchar*s,*end;registercharc;#ifdef Py_USING_UNICODEif(PyUnicode_Check(el))returnPyUnicode_Contains(a,el);#endifif(!PyString_Check(el)||PyString_Size(el)!=1){PyErr_SetString(PyExc_TypeError,"'in <string>' requires character as left operand");return-1;}c=PyString_AsString(el)[0];s=PyString_AsString(a);end=s+PyString_Size(a);while(s<end){if(c==*s++)return1;}return0;}staticPyObject*string_item(PyStringObject*a,registerinti){PyObject*v;char*pchar;if(i<0||i>=a->ob_size){PyErr_SetString(PyExc_IndexError,"string index out of range");returnNULL;}pchar=a->ob_sval+i;v=(PyObject*)characters[*pchar&UCHAR_MAX];if(v==NULL)v=PyString_FromStringAndSize(pchar,1);else{#ifdef COUNT_ALLOCSone_strings++;#endifPy_INCREF(v);}returnv;}staticPyObject*string_richcompare(PyStringObject*a,PyStringObject*b,intop){intc;intlen_a,len_b;intmin_len;PyObject*result;/* Make sure both arguments are strings. */if(!(PyString_Check(a)&&PyString_Check(b))){result=Py_NotImplemented;gotoout;}if(a==b){switch(op){casePy_EQ:casePy_LE:casePy_GE:result=Py_True;gotoout;casePy_NE:casePy_LT:casePy_GT:result=Py_False;gotoout;}}if(op==Py_EQ){/* Supporting Py_NE here as well does not save much time, since Py_NE is rarely used. */if(a->ob_size==b->ob_size&&(a->ob_sval[0]==b->ob_sval[0]&&memcmp(a->ob_sval,b->ob_sval,a->ob_size)==0)){result=Py_True;}else{result=Py_False;}gotoout;}len_a=a->ob_size;len_b=b->ob_size;min_len=(len_a<len_b)?len_a:len_b;if(min_len>0){c=Py_CHARMASK(*a->ob_sval)-Py_CHARMASK(*b->ob_sval);if(c==0)c=memcmp(a->ob_sval,b->ob_sval,min_len);}elsec=0;if(c==0)c=(len_a<len_b)?-1:(len_a>len_b)?1:0;switch(op){casePy_LT:c=c<0;break;casePy_LE:c=c<=0;break;casePy_EQ:assert(0);break;/* unreachable */casePy_NE:c=c!=0;break;casePy_GT:c=c>0;break;casePy_GE:c=c>=0;break;default:result=Py_NotImplemented;gotoout;}result=c?Py_True:Py_False;out:Py_INCREF(result);returnresult;}int_PyString_Eq(PyObject*o1,PyObject*o2){PyStringObject*a,*b;a=(PyStringObject*)o1;b=(PyStringObject*)o2;returna->ob_size==b->ob_size&&*a->ob_sval==*b->ob_sval&&memcmp(a->ob_sval,b->ob_sval,a->ob_size)==0;}staticlongstring_hash(PyStringObject*a){registerintlen;registerunsignedchar*p;registerlongx;#ifdef CACHE_HASHif(a->ob_shash!=-1)returna->ob_shash;#ifdef INTERN_STRINGSif(a->ob_sinterned!=NULL)return(a->ob_shash=((PyStringObject*)(a->ob_sinterned))->ob_shash);#endif#endiflen=a->ob_size;p=(unsignedchar*)a->ob_sval;x=*p<<7;while(--len>=0)x=(1000003*x)^*p++;x^=a->ob_size;if(x==-1)x=-2;#ifdef CACHE_HASHa->ob_shash=x;#endifreturnx;}staticintstring_buffer_getreadbuf(PyStringObject*self,intindex,constvoid**ptr){if(index!=0){PyErr_SetString(PyExc_SystemError,"accessing non-existent string segment");return-1;}*ptr=(void*)self->ob_sval;returnself->ob_size;}staticintstring_buffer_getwritebuf(PyStringObject*self,intindex,constvoid**ptr){PyErr_SetString(PyExc_TypeError,"Cannot use string as modifiable buffer");return-1;}staticintstring_buffer_getsegcount(PyStringObject*self,int*lenp){if(lenp)*lenp=self->ob_size;return1;}staticintstring_buffer_getcharbuf(PyStringObject*self,intindex,constchar**ptr){if(index!=0){PyErr_SetString(PyExc_SystemError,"accessing non-existent string segment");return-1;}*ptr=self->ob_sval;returnself->ob_size;}staticPySequenceMethodsstring_as_sequence={(inquiry)string_length,/*sq_length*/(binaryfunc)string_concat,/*sq_concat*/(intargfunc)string_repeat,/*sq_repeat*/(intargfunc)string_item,/*sq_item*/(intintargfunc)string_slice,/*sq_slice*/0,/*sq_ass_item*/0,/*sq_ass_slice*/(objobjproc)string_contains/*sq_contains*/};staticPyBufferProcsstring_as_buffer={(getreadbufferproc)string_buffer_getreadbuf,(getwritebufferproc)string_buffer_getwritebuf,(getsegcountproc)string_buffer_getsegcount,(getcharbufferproc)string_buffer_getcharbuf,};#define LEFTSTRIP 0#define RIGHTSTRIP 1#define BOTHSTRIP 2/* Arrays indexed by above */staticconstchar*stripformat[]={"|O:lstrip","|O:rstrip","|O:strip"};#define STRIPNAME(i) (stripformat[i]+3)staticPyObject*split_whitespace(constchar*s,intlen,intmaxsplit){inti,j,err;PyObject*item;PyObject*list=PyList_New(0);if(list==NULL)returnNULL;for(i=j=0;i<len;){while(i<len&&isspace(Py_CHARMASK(s[i])))i++;j=i;while(i<len&&!isspace(Py_CHARMASK(s[i])))i++;if(j<i){if(maxsplit--<=0)break;item=PyString_FromStringAndSize(s+j,(int)(i-j));if(item==NULL)gotofinally;err=PyList_Append(list,item);Py_DECREF(item);if(err<0)gotofinally;while(i<len&&isspace(Py_CHARMASK(s[i])))i++;j=i;}}if(j<len){item=PyString_FromStringAndSize(s+j,(int)(len-j));if(item==NULL)gotofinally;err=PyList_Append(list,item);Py_DECREF(item);if(err<0)gotofinally;}returnlist;finally:Py_DECREF(list);returnNULL;}staticcharsplit__doc__[]="S.split([sep [,maxsplit]]) -> list of strings\n\\n\Return a list of the words in the string S, using sep as the\n\delimiter string. If maxsplit is given, at most maxsplit\n\splits are done. If sep is not specified or is None, any\n\whitespace string is a separator.";staticPyObject*string_split(PyStringObject*self,PyObject*args){intlen=PyString_GET_SIZE(self),n,i,j,err;intmaxsplit=-1;constchar*s=PyString_AS_STRING(self),*sub;PyObject*list,*item,*subobj=Py_None;if(!PyArg_ParseTuple(args,"|Oi:split",&subobj,&maxsplit))returnNULL;if(maxsplit<0)maxsplit=INT_MAX;if(subobj==Py_None)returnsplit_whitespace(s,len,maxsplit);if(PyString_Check(subobj)){sub=PyString_AS_STRING(subobj);n=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj))returnPyUnicode_Split((PyObject*)self,subobj,maxsplit);#endifelseif(PyObject_AsCharBuffer(subobj,&sub,&n))returnNULL;if(n==0){PyErr_SetString(PyExc_ValueError,"empty separator");returnNULL;}list=PyList_New(0);if(list==NULL)returnNULL;i=j=0;while(i+n<=len){if(s[i]==sub[0]&&memcmp(s+i,sub,n)==0){if(maxsplit--<=0)break;item=PyString_FromStringAndSize(s+j,(int)(i-j));if(item==NULL)gotofail;err=PyList_Append(list,item);Py_DECREF(item);if(err<0)gotofail;i=j=i+n;}elsei++;}item=PyString_FromStringAndSize(s+j,(int)(len-j));if(item==NULL)gotofail;err=PyList_Append(list,item);Py_DECREF(item);if(err<0)gotofail;returnlist;fail:Py_DECREF(list);returnNULL;}staticcharjoin__doc__[]="S.join(sequence) -> string\n\\n\Return a string which is the concatenation of the strings in the\n\sequence. The separator between elements is S.";staticPyObject*string_join(PyStringObject*self,PyObject*orig){char*sep=PyString_AS_STRING(self);constintseplen=PyString_GET_SIZE(self);PyObject*res=NULL;char*p;intseqlen=0;size_tsz=0;inti;PyObject*seq,*item;seq=PySequence_Fast(orig,"");if(seq==NULL){if(PyErr_ExceptionMatches(PyExc_TypeError))PyErr_Format(PyExc_TypeError,"sequence expected, %.80s found",orig->ob_type->tp_name);returnNULL;}seqlen=PySequence_Size(seq);if(seqlen==0){Py_DECREF(seq);returnPyString_FromString("");}if(seqlen==1){item=PySequence_Fast_GET_ITEM(seq,0);if(!PyString_Check(item)&&!PyUnicode_Check(item)){PyErr_Format(PyExc_TypeError,"sequence item 0: expected string,"" %.80s found",item->ob_type->tp_name);Py_DECREF(seq);returnNULL;}Py_INCREF(item);Py_DECREF(seq);returnitem;}/* There are at least two things to join. Do a pre-pass to figure out * the total amount of space we'll need (sz), see whether any argument * is absurd, and defer to the Unicode join if appropriate. */for(i=0;i<seqlen;i++){constsize_told_sz=sz;item=PySequence_Fast_GET_ITEM(seq,i);if(!PyString_Check(item)){#ifdef Py_USING_UNICODEif(PyUnicode_Check(item)){/* Defer to Unicode join. * CAUTION: There's no gurantee that the * original sequence can be iterated over * again, so we must pass seq here. */PyObject*result;result=PyUnicode_Join((PyObject*)self,seq);Py_DECREF(seq);returnresult;}#endifPyErr_Format(PyExc_TypeError,"sequence item %i: expected string,"" %.80s found",i,item->ob_type->tp_name);Py_DECREF(seq);returnNULL;}sz+=PyString_GET_SIZE(item);if(i!=0)sz+=seplen;if(sz<old_sz||sz>INT_MAX){PyErr_SetString(PyExc_OverflowError,"join() is too long for a Python string");Py_DECREF(seq);returnNULL;}}/* Allocate result space. */res=PyString_FromStringAndSize((char*)NULL,(int)sz);if(res==NULL){Py_DECREF(seq);returnNULL;}/* Catenate everything. */p=PyString_AS_STRING(res);for(i=0;i<seqlen;++i){size_tn;item=PySequence_Fast_GET_ITEM(seq,i);n=PyString_GET_SIZE(item);memcpy(p,PyString_AS_STRING(item),n);p+=n;if(i<seqlen-1){memcpy(p,sep,seplen);p+=seplen;}}Py_DECREF(seq);returnres;}PyObject*_PyString_Join(PyObject*sep,PyObject*x){assert(sep!=NULL&&PyString_Check(sep));assert(x!=NULL);returnstring_join((PyStringObject*)sep,x);}staticlongstring_find_internal(PyStringObject*self,PyObject*args,intdir){constchar*s=PyString_AS_STRING(self),*sub;intlen=PyString_GET_SIZE(self);intn,i=0,last=INT_MAX;PyObject*subobj;if(!PyArg_ParseTuple(args,"O|O&O&:find/rfind/index/rindex",&subobj,_PyEval_SliceIndex,&i,_PyEval_SliceIndex,&last))return-2;if(PyString_Check(subobj)){sub=PyString_AS_STRING(subobj);n=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj))returnPyUnicode_Find((PyObject*)self,subobj,i,last,dir);#endifelseif(PyObject_AsCharBuffer(subobj,&sub,&n))return-2;if(last>len)last=len;if(last<0)last+=len;if(last<0)last=0;if(i<0)i+=len;if(i<0)i=0;if(dir>0){if(n==0&&i<=last)return(long)i;last-=n;for(;i<=last;++i)if(s[i]==sub[0]&&memcmp(&s[i],sub,n)==0)return(long)i;}else{intj;if(n==0&&i<=last)return(long)last;for(j=last-n;j>=i;--j)if(s[j]==sub[0]&&memcmp(&s[j],sub,n)==0)return(long)j;}return-1;}staticcharfind__doc__[]="S.find(sub [,start [,end]]) -> int\n\\n\Return the lowest index in S where substring sub is found,\n\such that sub is contained within s[start,end]. Optional\n\arguments start and end are interpreted as in slice notation.\n\\n\Return -1 on failure.";staticPyObject*string_find(PyStringObject*self,PyObject*args){longresult=string_find_internal(self,args,+1);if(result==-2)returnNULL;returnPyInt_FromLong(result);}staticcharindex__doc__[]="S.index(sub [,start [,end]]) -> int\n\\n\Like S.find() but raise ValueError when the substring is not found.";staticPyObject*string_index(PyStringObject*self,PyObject*args){longresult=string_find_internal(self,args,+1);if(result==-2)returnNULL;if(result==-1){PyErr_SetString(PyExc_ValueError,"substring not found in string.index");returnNULL;}returnPyInt_FromLong(result);}staticcharrfind__doc__[]="S.rfind(sub [,start [,end]]) -> int\n\\n\Return the highest index in S where substring sub is found,\n\such that sub is contained within s[start,end]. Optional\n\arguments start and end are interpreted as in slice notation.\n\\n\Return -1 on failure.";staticPyObject*string_rfind(PyStringObject*self,PyObject*args){longresult=string_find_internal(self,args,-1);if(result==-2)returnNULL;returnPyInt_FromLong(result);}staticcharrindex__doc__[]="S.rindex(sub [,start [,end]]) -> int\n\\n\Like S.rfind() but raise ValueError when the substring is not found.";staticPyObject*string_rindex(PyStringObject*self,PyObject*args){longresult=string_find_internal(self,args,-1);if(result==-2)returnNULL;if(result==-1){PyErr_SetString(PyExc_ValueError,"substring not found in string.rindex");returnNULL;}returnPyInt_FromLong(result);}staticPyObject*do_xstrip(PyStringObject*self,intstriptype,PyObject*sepobj){char*s=PyString_AS_STRING(self);intlen=PyString_GET_SIZE(self);char*sep=PyString_AS_STRING(sepobj);intseplen=PyString_GET_SIZE(sepobj);inti,j;i=0;if(striptype!=RIGHTSTRIP){while(i<len&&memchr(sep,Py_CHARMASK(s[i]),seplen)){i++;}}j=len;if(striptype!=LEFTSTRIP){do{j--;}while(j>=i&&memchr(sep,Py_CHARMASK(s[j]),seplen));j++;}if(i==0&&j==len&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}elsereturnPyString_FromStringAndSize(s+i,j-i);}staticPyObject*do_strip(PyStringObject*self,intstriptype){char*s=PyString_AS_STRING(self);intlen=PyString_GET_SIZE(self),i,j;i=0;if(striptype!=RIGHTSTRIP){while(i<len&&isspace(Py_CHARMASK(s[i]))){i++;}}j=len;if(striptype!=LEFTSTRIP){do{j--;}while(j>=i&&isspace(Py_CHARMASK(s[j])));j++;}if(i==0&&j==len&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}elsereturnPyString_FromStringAndSize(s+i,j-i);}staticPyObject*do_argstrip(PyStringObject*self,intstriptype,PyObject*args){PyObject*sep=NULL;if(!PyArg_ParseTuple(args,(char*)stripformat[striptype],&sep))returnNULL;if(sep!=NULL&&sep!=Py_None){if(PyString_Check(sep))returndo_xstrip(self,striptype,sep);#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(sep)){PyObject*uniself=PyUnicode_FromObject((PyObject*)self);PyObject*res;if(uniself==NULL)returnNULL;res=_PyUnicode_XStrip((PyUnicodeObject*)uniself,striptype,sep);Py_DECREF(uniself);returnres;}#endifelse{PyErr_Format(PyExc_TypeError,#ifdef Py_USING_UNICODE"%s arg must be None, str or unicode",#else"%s arg must be None or str",#endifSTRIPNAME(striptype));returnNULL;}returndo_xstrip(self,striptype,sep);}returndo_strip(self,striptype);}staticcharstrip__doc__[]="S.strip([chars]) -> string or unicode\n\\n\Return a copy of the string S with leading and trailing\n\whitespace removed.\n\If chars is given and not None, remove characters in chars instead.\n\If chars is unicode, S will be converted to unicode before stripping";staticPyObject*string_strip(PyStringObject*self,PyObject*args){if(PyTuple_GET_SIZE(args)==0)returndo_strip(self,BOTHSTRIP);/* Common case */elsereturndo_argstrip(self,BOTHSTRIP,args);}staticcharlstrip__doc__[]="S.lstrip([chars]) -> string or unicode\n\\n\Return a copy of the string S with leading whitespace removed.\n\If chars is given and not None, remove characters in chars instead.\n\If chars is unicode, S will be converted to unicode before stripping";staticPyObject*string_lstrip(PyStringObject*self,PyObject*args){if(PyTuple_GET_SIZE(args)==0)returndo_strip(self,LEFTSTRIP);/* Common case */elsereturndo_argstrip(self,LEFTSTRIP,args);}staticcharrstrip__doc__[]="S.rstrip([chars]) -> string or unicode\n\\n\Return a copy of the string S with trailing whitespace removed.\n\If chars is given and not None, remove characters in chars instead.\n\If chars is unicode, S will be converted to unicode before stripping";staticPyObject*string_rstrip(PyStringObject*self,PyObject*args){if(PyTuple_GET_SIZE(args)==0)returndo_strip(self,RIGHTSTRIP);/* Common case */elsereturndo_argstrip(self,RIGHTSTRIP,args);}staticcharlower__doc__[]="S.lower() -> string\n\\n\Return a copy of the string S converted to lowercase.";staticPyObject*string_lower(PyStringObject*self){char*s=PyString_AS_STRING(self),*s_new;inti,n=PyString_GET_SIZE(self);PyObject*new;new=PyString_FromStringAndSize(NULL,n);if(new==NULL)returnNULL;s_new=PyString_AsString(new);for(i=0;i<n;i++){intc=Py_CHARMASK(*s++);if(isupper(c)){*s_new=tolower(c);}else*s_new=c;s_new++;}returnnew;}staticcharupper__doc__[]="S.upper() -> string\n\\n\Return a copy of the string S converted to uppercase.";staticPyObject*string_upper(PyStringObject*self){char*s=PyString_AS_STRING(self),*s_new;inti,n=PyString_GET_SIZE(self);PyObject*new;new=PyString_FromStringAndSize(NULL,n);if(new==NULL)returnNULL;s_new=PyString_AsString(new);for(i=0;i<n;i++){intc=Py_CHARMASK(*s++);if(islower(c)){*s_new=toupper(c);}else*s_new=c;s_new++;}returnnew;}staticchartitle__doc__[]="S.title() -> string\n\\n\Return a titlecased version of S, i.e. words start with uppercase\n\characters, all remaining cased characters have lowercase.";staticPyObject*string_title(PyStringObject*self){char*s=PyString_AS_STRING(self),*s_new;inti,n=PyString_GET_SIZE(self);intprevious_is_cased=0;PyObject*new;new=PyString_FromStringAndSize(NULL,n);if(new==NULL)returnNULL;s_new=PyString_AsString(new);for(i=0;i<n;i++){intc=Py_CHARMASK(*s++);if(islower(c)){if(!previous_is_cased)c=toupper(c);previous_is_cased=1;}elseif(isupper(c)){if(previous_is_cased)c=tolower(c);previous_is_cased=1;}elseprevious_is_cased=0;*s_new++=c;}returnnew;}staticcharcapitalize__doc__[]="S.capitalize() -> string\n\\n\Return a copy of the string S with only its first character\n\capitalized.";staticPyObject*string_capitalize(PyStringObject*self){char*s=PyString_AS_STRING(self),*s_new;inti,n=PyString_GET_SIZE(self);PyObject*new;new=PyString_FromStringAndSize(NULL,n);if(new==NULL)returnNULL;s_new=PyString_AsString(new);if(0<n){intc=Py_CHARMASK(*s++);if(islower(c))*s_new=toupper(c);else*s_new=c;s_new++;}for(i=1;i<n;i++){intc=Py_CHARMASK(*s++);if(isupper(c))*s_new=tolower(c);else*s_new=c;s_new++;}returnnew;}staticcharcount__doc__[]="S.count(sub[, start[, end]]) -> int\n\\n\Return the number of occurrences of substring sub in string\n\S[start:end]. Optional arguments start and end are\n\interpreted as in slice notation.";staticPyObject*string_count(PyStringObject*self,PyObject*args){constchar*s=PyString_AS_STRING(self),*sub;intlen=PyString_GET_SIZE(self),n;inti=0,last=INT_MAX;intm,r;PyObject*subobj;if(!PyArg_ParseTuple(args,"O|O&O&:count",&subobj,_PyEval_SliceIndex,&i,_PyEval_SliceIndex,&last))returnNULL;if(PyString_Check(subobj)){sub=PyString_AS_STRING(subobj);n=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj)){intcount;count=PyUnicode_Count((PyObject*)self,subobj,i,last);if(count==-1)returnNULL;elsereturnPyInt_FromLong((long)count);}#endifelseif(PyObject_AsCharBuffer(subobj,&sub,&n))returnNULL;if(last>len)last=len;if(last<0)last+=len;if(last<0)last=0;if(i<0)i+=len;if(i<0)i=0;m=last+1-n;if(n==0)returnPyInt_FromLong((long)(m-i));r=0;while(i<m){if(!memcmp(s+i,sub,n)){r++;i+=n;}else{i++;}}returnPyInt_FromLong((long)r);}staticcharswapcase__doc__[]="S.swapcase() -> string\n\\n\Return a copy of the string S with uppercase characters\n\converted to lowercase and vice versa.";staticPyObject*string_swapcase(PyStringObject*self){char*s=PyString_AS_STRING(self),*s_new;inti,n=PyString_GET_SIZE(self);PyObject*new;new=PyString_FromStringAndSize(NULL,n);if(new==NULL)returnNULL;s_new=PyString_AsString(new);for(i=0;i<n;i++){intc=Py_CHARMASK(*s++);if(islower(c)){*s_new=toupper(c);}elseif(isupper(c)){*s_new=tolower(c);}else*s_new=c;s_new++;}returnnew;}staticchartranslate__doc__[]="S.translate(table [,deletechars]) -> string\n\\n\Return a copy of the string S, where all characters occurring\n\in the optional argument deletechars are removed, and the\n\remaining characters have been mapped through the given\n\translation table, which must be a string of length 256.";staticPyObject*string_translate(PyStringObject*self,PyObject*args){registerchar*input,*output;registerconstchar*table;registerinti,c,changed=0;PyObject*input_obj=(PyObject*)self;constchar*table1,*output_start,*del_table=NULL;intinlen,tablen,dellen=0;PyObject*result;inttrans_table[256];PyObject*tableobj,*delobj=NULL;if(!PyArg_ParseTuple(args,"O|O:translate",&tableobj,&delobj))returnNULL;if(PyString_Check(tableobj)){table1=PyString_AS_STRING(tableobj);tablen=PyString_GET_SIZE(tableobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(tableobj)){/* Unicode .translate() does not support the deletechars parameter; instead a mapping to None will cause characters to be deleted. */if(delobj!=NULL){PyErr_SetString(PyExc_TypeError,"deletions are implemented differently for unicode");returnNULL;}returnPyUnicode_Translate((PyObject*)self,tableobj,NULL);}#endifelseif(PyObject_AsCharBuffer(tableobj,&table1,&tablen))returnNULL;if(delobj!=NULL){if(PyString_Check(delobj)){del_table=PyString_AS_STRING(delobj);dellen=PyString_GET_SIZE(delobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(delobj)){PyErr_SetString(PyExc_TypeError,"deletions are implemented differently for unicode");returnNULL;}#endifelseif(PyObject_AsCharBuffer(delobj,&del_table,&dellen))returnNULL;if(tablen!=256){PyErr_SetString(PyExc_ValueError,"translation table must be 256 characters long");returnNULL;}}else{del_table=NULL;dellen=0;}table=table1;inlen=PyString_Size(input_obj);result=PyString_FromStringAndSize((char*)NULL,inlen);if(result==NULL)returnNULL;output_start=output=PyString_AsString(result);input=PyString_AsString(input_obj);if(dellen==0){/* If no deletions are required, use faster code */for(i=inlen;--i>=0;){c=Py_CHARMASK(*input++);if(Py_CHARMASK((*output++=table[c]))!=c)changed=1;}if(changed||!PyString_CheckExact(input_obj))returnresult;Py_DECREF(result);Py_INCREF(input_obj);returninput_obj;}for(i=0;i<256;i++)trans_table[i]=Py_CHARMASK(table[i]);for(i=0;i<dellen;i++)trans_table[(int)Py_CHARMASK(del_table[i])]=-1;for(i=inlen;--i>=0;){c=Py_CHARMASK(*input++);if(trans_table[c]!=-1)if(Py_CHARMASK(*output++=(char)trans_table[c])==c)continue;changed=1;}if(!changed&&PyString_CheckExact(input_obj)){Py_DECREF(result);Py_INCREF(input_obj);returninput_obj;}/* Fix the size of the resulting string */if(inlen>0)_PyString_Resize(&result,output-output_start);returnresult;}/* What follows is used for implementing replace(). Perry Stoll. *//* mymemfind strstr replacement for arbitrary blocks of memory. Locates the first occurrence in the memory pointed to by MEM of the contents of memory pointed to by PAT. Returns the index into MEM if found, or -1 if not found. If len of PAT is greater than length of MEM, the function returns -1.*/staticintmymemfind(constchar*mem,intlen,constchar*pat,intpat_len){registerintii;/* pattern can not occur in the last pat_len-1 chars */len-=pat_len;for(ii=0;ii<=len;ii++){if(mem[ii]==pat[0]&&memcmp(&mem[ii],pat,pat_len)==0){returnii;}}return-1;}/* mymemcnt Return the number of distinct times PAT is found in MEM. meaning mem=1111 and pat==11 returns 2. mem=11111 and pat==11 also return 2. */staticintmymemcnt(constchar*mem,intlen,constchar*pat,intpat_len){registerintoffset=0;intnfound=0;while(len>=0){offset=mymemfind(mem,len,pat,pat_len);if(offset==-1)break;mem+=offset+pat_len;len-=offset+pat_len;nfound++;}returnnfound;}/* mymemreplace Return a string in which all occurrences of PAT in memory STR are replaced with SUB. If length of PAT is less than length of STR or there are no occurrences of PAT in STR, then the original string is returned. Otherwise, a new string is allocated here and returned. on return, out_len is: the length of output string, or -1 if the input string is returned, or unchanged if an error occurs (no memory). return value is: the new string allocated locally, or NULL if an error occurred.*/staticchar*mymemreplace(constchar*str,intlen,/* input string */constchar*pat,intpat_len,/* pattern string to find */constchar*sub,intsub_len,/* substitution string */intcount,/* number of replacements */int*out_len){char*out_s;char*new_s;intnfound,offset,new_len;if(len==0||pat_len>len)gotoreturn_same;/* find length of output string */nfound=mymemcnt(str,len,pat,pat_len);if(count<0)count=INT_MAX;elseif(nfound>count)nfound=count;if(nfound==0)gotoreturn_same;new_len=len+nfound*(sub_len-pat_len);if(new_len==0){/* Have to allocate something for the caller to free(). */out_s=(char*)PyMem_MALLOC(1);if(out_s==NULL)returnNULL;out_s[0]='\0';}else{assert(new_len>0);new_s=(char*)PyMem_MALLOC(new_len);if(new_s==NULL)returnNULL;out_s=new_s;for(;count>0&&len>0;--count){/* find index of next instance of pattern */offset=mymemfind(str,len,pat,pat_len);if(offset==-1)break;/* copy non matching part of input string */memcpy(new_s,str,offset);str+=offset+pat_len;len-=offset+pat_len;/* copy substitute into the output string */new_s+=offset;memcpy(new_s,sub,sub_len);new_s+=sub_len;}/* copy any remaining values into output string */if(len>0)memcpy(new_s,str,len);}*out_len=new_len;returnout_s;return_same:*out_len=-1;return(char*)str;/* cast away const */}staticcharreplace__doc__[]="S.replace (old, new[, maxsplit]) -> string\n\\n\Return a copy of string S with all occurrences of substring\n\old replaced by new. If the optional argument maxsplit is\n\given, only the first maxsplit occurrences are replaced.";staticPyObject*string_replace(PyStringObject*self,PyObject*args){constchar*str=PyString_AS_STRING(self),*sub,*repl;char*new_s;constintlen=PyString_GET_SIZE(self);intsub_len,repl_len,out_len;intcount=-1;PyObject*new;PyObject*subobj,*replobj;if(!PyArg_ParseTuple(args,"OO|i:replace",&subobj,&replobj,&count))returnNULL;if(PyString_Check(subobj)){sub=PyString_AS_STRING(subobj);sub_len=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj))returnPyUnicode_Replace((PyObject*)self,subobj,replobj,count);#endifelseif(PyObject_AsCharBuffer(subobj,&sub,&sub_len))returnNULL;if(PyString_Check(replobj)){repl=PyString_AS_STRING(replobj);repl_len=PyString_GET_SIZE(replobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(replobj))returnPyUnicode_Replace((PyObject*)self,subobj,replobj,count);#endifelseif(PyObject_AsCharBuffer(replobj,&repl,&repl_len))returnNULL;if(sub_len<=0){PyErr_SetString(PyExc_ValueError,"empty pattern string");returnNULL;}new_s=mymemreplace(str,len,sub,sub_len,repl,repl_len,count,&out_len);if(new_s==NULL){PyErr_NoMemory();returnNULL;}if(out_len==-1){if(PyString_CheckExact(self)){/* we're returning another reference to self */new=(PyObject*)self;Py_INCREF(new);}else{new=PyString_FromStringAndSize(str,len);if(new==NULL)returnNULL;}}else{new=PyString_FromStringAndSize(new_s,out_len);PyMem_FREE(new_s);}returnnew;}staticcharstartswith__doc__[]="S.startswith(prefix[, start[, end]]) -> int\n\\n\Return 1 if S starts with the specified prefix, otherwise return 0. With\n\optional start, test S beginning at that position. With optional end, stop\n\comparing S at that position.";staticPyObject*string_startswith(PyStringObject*self,PyObject*args){constchar*str=PyString_AS_STRING(self);intlen=PyString_GET_SIZE(self);constchar*prefix;intplen;intstart=0;intend=INT_MAX;PyObject*subobj;if(!PyArg_ParseTuple(args,"O|O&O&:startswith",&subobj,_PyEval_SliceIndex,&start,_PyEval_SliceIndex,&end))returnNULL;if(PyString_Check(subobj)){prefix=PyString_AS_STRING(subobj);plen=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj)){intrc;rc=PyUnicode_Tailmatch((PyObject*)self,subobj,start,end,-1);if(rc==-1)returnNULL;elsereturnPyInt_FromLong((long)rc);}#endifelseif(PyObject_AsCharBuffer(subobj,&prefix,&plen))returnNULL;/* adopt Java semantics for index out of range. it is legal for * offset to be == plen, but this only returns true if prefix is * the empty string. */if(start<0||start+plen>len)returnPyInt_FromLong(0);if(!memcmp(str+start,prefix,plen)){/* did the match end after the specified end? */if(end<0)returnPyInt_FromLong(1);elseif(end-start<plen)returnPyInt_FromLong(0);elsereturnPyInt_FromLong(1);}elsereturnPyInt_FromLong(0);}staticcharendswith__doc__[]="S.endswith(suffix[, start[, end]]) -> int\n\\n\Return 1 if S ends with the specified suffix, otherwise return 0. With\n\optional start, test S beginning at that position. With optional end, stop\n\comparing S at that position.";staticPyObject*string_endswith(PyStringObject*self,PyObject*args){constchar*str=PyString_AS_STRING(self);intlen=PyString_GET_SIZE(self);constchar*suffix;intslen;intstart=0;intend=INT_MAX;intlower,upper;PyObject*subobj;if(!PyArg_ParseTuple(args,"O|O&O&:endswith",&subobj,_PyEval_SliceIndex,&start,_PyEval_SliceIndex,&end))returnNULL;if(PyString_Check(subobj)){suffix=PyString_AS_STRING(subobj);slen=PyString_GET_SIZE(subobj);}#ifdef Py_USING_UNICODEelseif(PyUnicode_Check(subobj)){intrc;rc=PyUnicode_Tailmatch((PyObject*)self,subobj,start,end,+1);if(rc==-1)returnNULL;elsereturnPyInt_FromLong((long)rc);}#endifelseif(PyObject_AsCharBuffer(subobj,&suffix,&slen))returnNULL;if(start<0||start>len||slen>len)returnPyInt_FromLong(0);upper=(end>=0&&end<=len)?end:len;lower=(upper-slen)>start?(upper-slen):start;if(upper-lower>=slen&&!memcmp(str+lower,suffix,slen))returnPyInt_FromLong(1);elsereturnPyInt_FromLong(0);}staticcharencode__doc__[]="S.encode([encoding[,errors]]) -> object\n\\n\Encodes S using the codec registered for encoding. encoding defaults\n\to the default encoding. errors may be given to set a different error\n\handling scheme. Default is 'strict' meaning that encoding errors raise\n\a ValueError. Other possible values are 'ignore' and 'replace'.";staticPyObject*string_encode(PyStringObject*self,PyObject*args){char*encoding=NULL;char*errors=NULL;if(!PyArg_ParseTuple(args,"|ss:encode",&encoding,&errors))returnNULL;returnPyString_AsEncodedObject((PyObject*)self,encoding,errors);}staticchardecode__doc__[]="S.decode([encoding[,errors]]) -> object\n\\n\Decodes S using the codec registered for encoding. encoding defaults\n\to the default encoding. errors may be given to set a different error\n\handling scheme. Default is 'strict' meaning that encoding errors raise\n\a ValueError. Other possible values are 'ignore' and 'replace'.";staticPyObject*string_decode(PyStringObject*self,PyObject*args){char*encoding=NULL;char*errors=NULL;if(!PyArg_ParseTuple(args,"|ss:decode",&encoding,&errors))returnNULL;returnPyString_AsDecodedObject((PyObject*)self,encoding,errors);}staticcharexpandtabs__doc__[]="S.expandtabs([tabsize]) -> string\n\\n\Return a copy of S where all tab characters are expanded using spaces.\n\If tabsize is not given, a tab size of 8 characters is assumed.";staticPyObject*string_expandtabs(PyStringObject*self,PyObject*args){constchar*e,*p;char*q;inti,j;PyObject*u;inttabsize=8;if(!PyArg_ParseTuple(args,"|i:expandtabs",&tabsize))returnNULL;/* First pass: determine size of output string */i=j=0;e=PyString_AS_STRING(self)+PyString_GET_SIZE(self);for(p=PyString_AS_STRING(self);p<e;p++)if(*p=='\t'){if(tabsize>0)j+=tabsize-(j%tabsize);}else{j++;if(*p=='\n'||*p=='\r'){i+=j;j=0;}}/* Second pass: create output string and fill it */u=PyString_FromStringAndSize(NULL,i+j);if(!u)returnNULL;j=0;q=PyString_AS_STRING(u);for(p=PyString_AS_STRING(self);p<e;p++)if(*p=='\t'){if(tabsize>0){i=tabsize-(j%tabsize);j+=i;while(i--)*q++=' ';}}else{j++;*q++=*p;if(*p=='\n'||*p=='\r')j=0;}returnu;}staticPyObject*pad(PyStringObject*self,intleft,intright,charfill){PyObject*u;if(left<0)left=0;if(right<0)right=0;if(left==0&&right==0&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}u=PyString_FromStringAndSize(NULL,left+PyString_GET_SIZE(self)+right);if(u){if(left)memset(PyString_AS_STRING(u),fill,left);memcpy(PyString_AS_STRING(u)+left,PyString_AS_STRING(self),PyString_GET_SIZE(self));if(right)memset(PyString_AS_STRING(u)+left+PyString_GET_SIZE(self),fill,right);}returnu;}staticcharljust__doc__[]="S.ljust(width) -> string\n""\n""Return S left justified in a string of length width. Padding is\n""done using spaces.";staticPyObject*string_ljust(PyStringObject*self,PyObject*args){intwidth;if(!PyArg_ParseTuple(args,"i:ljust",&width))returnNULL;if(PyString_GET_SIZE(self)>=width&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}returnpad(self,0,width-PyString_GET_SIZE(self),' ');}staticcharrjust__doc__[]="S.rjust(width) -> string\n""\n""Return S right justified in a string of length width. Padding is\n""done using spaces.";staticPyObject*string_rjust(PyStringObject*self,PyObject*args){intwidth;if(!PyArg_ParseTuple(args,"i:rjust",&width))returnNULL;if(PyString_GET_SIZE(self)>=width&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}returnpad(self,width-PyString_GET_SIZE(self),0,' ');}staticcharcenter__doc__[]="S.center(width) -> string\n""\n""Return S centered in a string of length width. Padding is done\n""using spaces.";staticPyObject*string_center(PyStringObject*self,PyObject*args){intmarg,left;intwidth;if(!PyArg_ParseTuple(args,"i:center",&width))returnNULL;if(PyString_GET_SIZE(self)>=width&&PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}marg=width-PyString_GET_SIZE(self);left=marg/2+(marg&width&1);returnpad(self,left,marg-left,' ');}staticcharzfill__doc__[]="S.zfill(width) -> string\n""\n""Pad a numeric string S with zeros on the left, to fill a field\n""of the specified width. The string S is never truncated.";staticPyObject*string_zfill(PyStringObject*self,PyObject*args){intfill;PyObject*s;char*p;intwidth;if(!PyArg_ParseTuple(args,"i:zfill",&width))returnNULL;if(PyString_GET_SIZE(self)>=width){if(PyString_CheckExact(self)){Py_INCREF(self);return(PyObject*)self;}elsereturnPyString_FromStringAndSize(PyString_AS_STRING(self),PyString_GET_SIZE(self));}fill=width-PyString_GET_SIZE(self);s=pad(self,fill,0,'0');if(s==NULL)returnNULL;p=PyString_AS_STRING(s);if(p[fill]=='+'||p[fill]=='-'){/* move sign to beginning of string */p[0]=p[fill];p[fill]='0';}return(PyObject*)s;}staticcharisspace__doc__[]="S.isspace() -> int\n""\n""Return 1 if there are only whitespace characters in S,\n""0 otherwise.";staticPyObject*string_isspace(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1&&isspace(*p))returnPyInt_FromLong(1);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);for(;p<e;p++){if(!isspace(*p))returnPyInt_FromLong(0);}returnPyInt_FromLong(1);}staticcharisalpha__doc__[]="S.isalpha() -> int\n\\n\Return 1 if all characters in S are alphabetic\n\and there is at least one character in S, 0 otherwise.";staticPyObject*string_isalpha(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1&&isalpha(*p))returnPyInt_FromLong(1);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);for(;p<e;p++){if(!isalpha(*p))returnPyInt_FromLong(0);}returnPyInt_FromLong(1);}staticcharisalnum__doc__[]="S.isalnum() -> int\n\\n\Return 1 if all characters in S are alphanumeric\n\and there is at least one character in S, 0 otherwise.";staticPyObject*string_isalnum(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1&&isalnum(*p))returnPyInt_FromLong(1);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);for(;p<e;p++){if(!isalnum(*p))returnPyInt_FromLong(0);}returnPyInt_FromLong(1);}staticcharisdigit__doc__[]="S.isdigit() -> int\n\\n\Return 1 if there are only digit characters in S,\n\0 otherwise.";staticPyObject*string_isdigit(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1&&isdigit(*p))returnPyInt_FromLong(1);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);for(;p<e;p++){if(!isdigit(*p))returnPyInt_FromLong(0);}returnPyInt_FromLong(1);}staticcharislower__doc__[]="S.islower() -> int\n\\n\Return 1 if all cased characters in S are lowercase and there is\n\at least one cased character in S, 0 otherwise.";staticPyObject*string_islower(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;intcased;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1)returnPyInt_FromLong(islower(*p)!=0);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);cased=0;for(;p<e;p++){if(isupper(*p))returnPyInt_FromLong(0);elseif(!cased&&islower(*p))cased=1;}returnPyInt_FromLong(cased);}staticcharisupper__doc__[]="S.isupper() -> int\n\\n\Return 1 if all cased characters in S are uppercase and there is\n\at least one cased character in S, 0 otherwise.";staticPyObject*string_isupper(PyStringObject*self){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;intcased;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1)returnPyInt_FromLong(isupper(*p)!=0);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);cased=0;for(;p<e;p++){if(islower(*p))returnPyInt_FromLong(0);elseif(!cased&&isupper(*p))cased=1;}returnPyInt_FromLong(cased);}staticcharistitle__doc__[]="S.istitle() -> int\n\\n\Return 1 if S is a titlecased string, i.e. uppercase characters\n\may only follow uncased characters and lowercase characters only cased\n\ones. Return 0 otherwise.";staticPyObject*string_istitle(PyStringObject*self,PyObject*uncased){registerconstunsignedchar*p=(unsignedchar*)PyString_AS_STRING(self);registerconstunsignedchar*e;intcased,previous_is_cased;/* Shortcut for single character strings */if(PyString_GET_SIZE(self)==1)returnPyInt_FromLong(isupper(*p)!=0);/* Special case for empty strings */if(PyString_GET_SIZE(self)==0)returnPyInt_FromLong(0);e=p+PyString_GET_SIZE(self);cased=0;previous_is_cased=0;for(;p<e;p++){registerconstunsignedcharch=*p;if(isupper(ch)){if(previous_is_cased)returnPyInt_FromLong(0);previous_is_cased=1;cased=1;}elseif(islower(ch)){if(!previous_is_cased)returnPyInt_FromLong(0);previous_is_cased=1;cased=1;}elseprevious_is_cased=0;}returnPyInt_FromLong(cased);}staticcharsplitlines__doc__[]="S.splitlines([keepends]) -> list of strings\n\\n\Return a list of the lines in S, breaking at line boundaries.\n\Line breaks are not included in the resulting list unless keepends\n\is given and true.";#define SPLIT_APPEND(data, left, right) \ str = PyString_FromStringAndSize(data + left, right - left); \ if (!str) \ goto onError; \ if (PyList_Append(list, str)) { \ Py_DECREF(str); \ goto onError; \ } \ else \ Py_DECREF(str);staticPyObject*string_splitlines(PyStringObject*self,PyObject*args){registerinti;registerintj;intlen;intkeepends=0;PyObject*list;PyObject*str;char*data;if(!PyArg_ParseTuple(args,"|i:splitlines",&keepends))returnNULL;data=PyString_AS_STRING(self);len=PyString_GET_SIZE(self);list=PyList_New(0);if(!list)gotoonError;for(i=j=0;i<len;){inteol;/* Find a line and append it */while(i<len&&data[i]!='\n'&&data[i]!='\r')i++;/* Skip the line break reading CRLF as one line break */eol=i;if(i<len){if(data[i]=='\r'&&i+1<len&&data[i+1]=='\n')i+=2;elsei++;if(keepends)eol=i;}SPLIT_APPEND(data,j,eol);j=i;}if(j<len){SPLIT_APPEND(data,j,len);}returnlist;onError:Py_DECREF(list);returnNULL;}#undef SPLIT_APPENDstaticPyMethodDefstring_methods[]={/* Counterparts of the obsolete stropmodule functions; except string.maketrans(). */{"join",(PyCFunction)string_join,METH_O,join__doc__},{"split",(PyCFunction)string_split,METH_VARARGS,split__doc__},{"lower",(PyCFunction)string_lower,METH_NOARGS,lower__doc__},{"upper",(PyCFunction)string_upper,METH_NOARGS,upper__doc__},{"islower",(PyCFunction)string_islower,METH_NOARGS,islower__doc__},{"isupper",(PyCFunction)string_isupper,METH_NOARGS,isupper__doc__},{"isspace",(PyCFunction)string_isspace,METH_NOARGS,isspace__doc__},{"isdigit",(PyCFunction)string_isdigit,METH_NOARGS,isdigit__doc__},{"istitle",(PyCFunction)string_istitle,METH_NOARGS,istitle__doc__},{"isalpha",(PyCFunction)string_isalpha,METH_NOARGS,isalpha__doc__},{"isalnum",(PyCFunction)string_isalnum,METH_NOARGS,isalnum__doc__},{"capitalize",(PyCFunction)string_capitalize,METH_NOARGS,capitalize__doc__},{"count",(PyCFunction)string_count,METH_VARARGS,count__doc__},{"endswith",(PyCFunction)string_endswith,METH_VARARGS,endswith__doc__},{"find",(PyCFunction)string_find,METH_VARARGS,find__doc__},{"index",(PyCFunction)string_index,METH_VARARGS,index__doc__},{"lstrip",(PyCFunction)string_lstrip,METH_VARARGS,lstrip__doc__},{"replace",(PyCFunction)string_replace,METH_VARARGS,replace__doc__},{"rfind",(PyCFunction)string_rfind,METH_VARARGS,rfind__doc__},{"rindex",(PyCFunction)string_rindex,METH_VARARGS,rindex__doc__},{"rstrip",(PyCFunction)string_rstrip,METH_VARARGS,rstrip__doc__},{"startswith",(PyCFunction)string_startswith,METH_VARARGS,startswith__doc__},{"strip",(PyCFunction)string_strip,METH_VARARGS,strip__doc__},{"swapcase",(PyCFunction)string_swapcase,METH_NOARGS,swapcase__doc__},{"translate",(PyCFunction)string_translate,METH_VARARGS,translate__doc__},{"title",(PyCFunction)string_title,METH_NOARGS,title__doc__},{"ljust",(PyCFunction)string_ljust,METH_VARARGS,ljust__doc__},{"rjust",(PyCFunction)string_rjust,METH_VARARGS,rjust__doc__},{"center",(PyCFunction)string_center,METH_VARARGS,center__doc__},{"zfill",(PyCFunction)string_zfill,METH_VARARGS,zfill__doc__},{"encode",(PyCFunction)string_encode,METH_VARARGS,encode__doc__},{"decode",(PyCFunction)string_decode,METH_VARARGS,decode__doc__},{"expandtabs",(PyCFunction)string_expandtabs,METH_VARARGS,expandtabs__doc__},{"splitlines",(PyCFunction)string_splitlines,METH_VARARGS,splitlines__doc__},{NULL,NULL}/* sentinel */};staticforwardPyObject*str_subtype_new(PyTypeObject*type,PyObject*args,PyObject*kwds);staticPyObject*string_new(PyTypeObject*type,PyObject*args,PyObject*kwds){PyObject*x=NULL;staticchar*kwlist[]={"object",0};if(type!=&PyString_Type)returnstr_subtype_new(type,args,kwds);if(!PyArg_ParseTupleAndKeywords(args,kwds,"|O:str",kwlist,&x))returnNULL;if(x==NULL)returnPyString_FromString("");returnPyObject_Str(x);}staticPyObject*str_subtype_new(PyTypeObject*type,PyObject*args,PyObject*kwds){PyObject*tmp,*pnew;intn;assert(PyType_IsSubtype(type,&PyString_Type));tmp=string_new(&PyString_Type,args,kwds);if(tmp==NULL)returnNULL;assert(PyString_CheckExact(tmp));n=PyString_GET_SIZE(tmp);pnew=type->tp_alloc(type,n);if(pnew!=NULL){memcpy(PyString_AS_STRING(pnew),PyString_AS_STRING(tmp),n+1);#ifdef CACHE_HASH((PyStringObject*)pnew)->ob_shash=((PyStringObject*)tmp)->ob_shash;#endif#ifdef INTERN_STRINGS((PyStringObject*)pnew)->ob_sinterned=((PyStringObject*)tmp)->ob_sinterned;#endif}Py_DECREF(tmp);returnpnew;}staticcharstring_doc[]="str(object) -> string\n\\n\Return a nice string representation of the object.\n\If the argument is a string, the return value is the same object.";PyTypeObjectPyString_Type={PyObject_HEAD_INIT(&PyType_Type)0,"str",sizeof(PyStringObject),sizeof(char),(destructor)string_dealloc,/* tp_dealloc */(printfunc)string_print,/* tp_print */0,/* tp_getattr */0,/* tp_setattr */0,/* tp_compare */(reprfunc)string_repr,/* tp_repr */0,/* tp_as_number */&string_as_sequence,/* tp_as_sequence */0,/* tp_as_mapping */(hashfunc)string_hash,/* tp_hash */0,/* tp_call */(reprfunc)string_str,/* tp_str */PyObject_GenericGetAttr,/* tp_getattro */0,/* tp_setattro */&string_as_buffer,/* tp_as_buffer */Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,/* tp_flags */string_doc,/* tp_doc */0,/* tp_traverse */0,/* tp_clear */(richcmpfunc)string_richcompare,/* tp_richcompare */0,/* tp_weaklistoffset */0,/* tp_iter */0,/* tp_iternext */string_methods,/* tp_methods */0,/* tp_members */0,/* tp_getset */0,/* tp_base */0,/* tp_dict */0,/* tp_descr_get */0,/* tp_descr_set */0,/* tp_dictoffset */0,/* tp_init */0,/* tp_alloc */string_new,/* tp_new */_PyObject_Del,/* tp_free */};voidPyString_Concat(registerPyObject**pv,registerPyObject*w){registerPyObject*v;if(*pv==NULL)return;if(w==NULL||!PyString_Check(*pv)){Py_DECREF(*pv);*pv=NULL;return;}v=string_concat((PyStringObject*)*pv,w);Py_DECREF(*pv);*pv=v;}voidPyString_ConcatAndDel(registerPyObject**pv,registerPyObject*w){PyString_Concat(pv,w);Py_XDECREF(w);}/* The following function breaks the notion that strings are immutable: it changes the size of a string. We get away with this only if there is only one module referencing the object. You can also think of it as creating a new string object and destroying the old one, only more efficiently. In any case, don't use this if the string may already be known to some other part of the code... Note that if there's not enough memory to resize the string, the original string object at *pv is deallocated, *pv is set to NULL, an "out of memory" exception is set, and -1 is returned. Else (on success) 0 is returned, and the value in *pv may or may not be the same as on input. As always, an extra byte is allocated for a trailing \0 byte (newsize does *not* include that), and a trailing \0 byte is stored.*/int_PyString_Resize(PyObject**pv,intnewsize){registerPyObject*v;registerPyStringObject*sv;v=*pv;if(!PyString_Check(v)||v->ob_refcnt!=1||newsize<0){*pv=0;Py_DECREF(v);PyErr_BadInternalCall();return-1;}/* XXX UNREF/NEWREF interface should be more symmetrical */#ifdef Py_REF_DEBUG--_Py_RefTotal;#endif_Py_ForgetReference(v);*pv=(PyObject*)PyObject_REALLOC((char*)v,sizeof(PyStringObject)+newsize*sizeof(char));if(*pv==NULL){PyObject_DEL(v);PyErr_NoMemory();return-1;}_Py_NewReference(*pv);sv=(PyStringObject*)*pv;sv->ob_size=newsize;sv->ob_sval[newsize]='\0';return0;}/* Helpers for formatstring */staticPyObject*getnextarg(PyObject*args,intarglen,int*p_argidx){intargidx=*p_argidx;if(argidx<arglen){(*p_argidx)++;if(arglen<0)returnargs;elsereturnPyTuple_GetItem(args,argidx);}PyErr_SetString(PyExc_TypeError,"not enough arguments for format string");returnNULL;}/* Format codes * F_LJUST '-' * F_SIGN '+' * F_BLANK ' ' * F_ALT '#' * F_ZERO '0' */#define F_LJUST (1<<0)#define F_SIGN (1<<1)#define F_BLANK (1<<2)#define F_ALT (1<<3)#define F_ZERO (1<<4)staticintformatfloat(char*buf,size_tbuflen,intflags,intprec,inttype,PyObject*v){/* fmt = '%#.' + `prec` + `type` worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/charfmt[20];doublex;if(!PyArg_Parse(v,"d;float argument required",&x))return-1;if(prec<0)prec=6;if(type=='f'&&fabs(x)/1e25>=1e25)type='g';/* Worst case length calc to ensure no buffer overrun: 'g' formats: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec 'f' formats: buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) len = 1 + 50 + 1 + prec = 52 + prec If prec=0 the effective precision is 1 (the leading digit is always given), therefore increase the length by one. */if((type=='g'&&buflen<=(size_t)10+(size_t)prec)||(type=='f'&&buflen<=(size_t)53+(size_t)prec)){PyErr_SetString(PyExc_OverflowError,"formatted float is too long (precision too large?)");return-1;}PyOS_snprintf(fmt,sizeof(fmt),"%%%s.%d%c",(flags&F_ALT)?"#":"",prec,type);PyOS_snprintf(buf,buflen,fmt,x);returnstrlen(buf);}/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and * the F_ALT flag, for Python's long (unbounded) ints. It's not used for * Python's regular ints. * Return value: a new PyString*, or NULL if error. * . *pbuf is set to point into it, * *plen set to the # of chars following that. * Caller must decref it when done using pbuf. * The string starting at *pbuf is of the form * "-"? ("0x" | "0X")? digit+ * "0x"/"0X" are present only for x and X conversions, with F_ALT * set in flags. The case of hex digits will be correct, * There will be at least prec digits, zero-filled on the left if * necessary to get that many. * val object to be converted * flags bitmask of format flags; only F_ALT is looked at * prec minimum number of digits; 0-fill on left if needed * type a character in [duoxX]; u acts the same as d * * CAUTION: o, x and X conversions on regular ints can never * produce a '-' sign, but can for Python's unbounded ints. */PyObject*_PyString_FormatLong(PyObject*val,intflags,intprec,inttype,char**pbuf,int*plen){PyObject*result=NULL;char*buf;inti;intsign;/* 1 if '-', else 0 */intlen;/* number of characters */intnumdigits;/* len == numnondigits + numdigits */intnumnondigits=0;switch(type){case'd':case'u':result=val->ob_type->tp_str(val);break;case'o':result=val->ob_type->tp_as_number->nb_oct(val);break;case'x':case'X':numnondigits=2;result=val->ob_type->tp_as_number->nb_hex(val);break;default:assert(!"'type' not in [duoxX]");}if(!result)returnNULL;/* To modify the string in-place, there can only be one reference. */if(result->ob_refcnt!=1){PyErr_BadInternalCall();returnNULL;}buf=PyString_AsString(result);len=PyString_Size(result);if(buf[len-1]=='L'){--len;buf[len]='\0';}sign=buf[0]=='-';numnondigits+=sign;numdigits=len-numnondigits;assert(numdigits>0);/* Get rid of base marker unless F_ALT */if((flags&F_ALT)==0){/* Need to skip 0x, 0X or 0. */intskipped=0;switch(type){case'o':assert(buf[sign]=='0');/* If 0 is only digit, leave it alone. */if(numdigits>1){skipped=1;--numdigits;}break;case'x':case'X':assert(buf[sign]=='0');assert(buf[sign+1]=='x');skipped=2;numnondigits-=2;break;}if(skipped){buf+=skipped;len-=skipped;if(sign)buf[0]='-';}assert(len==numnondigits+numdigits);assert(numdigits>0);}/* Fill with leading zeroes to meet minimum width. */if(prec>numdigits){PyObject*r1=PyString_FromStringAndSize(NULL,numnondigits+prec);char*b1;if(!r1){Py_DECREF(result);returnNULL;}b1=PyString_AS_STRING(r1);for(i=0;i<numnondigits;++i)*b1++=*buf++;for(i=0;i<prec-numdigits;i++)*b1++='0';for(i=0;i<numdigits;i++)*b1++=*buf++;*b1='\0';Py_DECREF(result);result=r1;buf=PyString_AS_STRING(result);len=numnondigits+prec;}/* Fix up case for hex conversions. */switch(type){case'x':/* Need to convert all upper case letters to lower case. */for(i=0;i<len;i++)if(buf[i]>='A'&&buf[i]<='F')buf[i]+='a'-'A';break;case'X':/* Need to convert 0x to 0X (and -0x to -0X). */if(buf[sign+1]=='x')buf[sign+1]='X';break;}*pbuf=buf;*plen=len;returnresult;}staticintformatint(char*buf,size_tbuflen,intflags,intprec,inttype,PyObject*v){/* fmt = '%#.' + `prec` + 'l' + `type` worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine) + 1 + 1 = 24 */charfmt[64];/* plenty big enough! */longx;if(!PyArg_Parse(v,"l;int argument required",&x))return-1;if(prec<0)prec=1;PyOS_snprintf(fmt,sizeof(fmt),"%%%s.%dl%c",(flags&F_ALT)?"#":"",prec,type);/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec, len(x in octal)) worst case buf = '0x' + [0-9]*prec, where prec >= 11 */if(buflen<=13||buflen<=(size_t)2+(size_t)prec){PyErr_SetString(PyExc_OverflowError,"formatted integer is too long (precision too large?)");return-1;}PyOS_snprintf(buf,buflen,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). * BUG 28-Apr-2001 tim: At least two platform Cs (Metrowerks & * Compaq Tru64) violate the std by converting 0 w/ leading 0x anyway. * So add it only if the platform didn't already. */if(x==0&&(flags&F_ALT)&&(type=='x'||type=='X')&&buf[1]!=(char)type)/* this last always true under std C */{memmove(buf+2,buf,strlen(buf)+1);buf[0]='0';buf[1]=(char)type;}returnstrlen(buf);}staticintformatchar(char*buf,size_tbuflen,PyObject*v){/* presume that the buffer is at least 2 characters long */if(PyString_Check(v)){if(!PyArg_Parse(v,"c;%c requires int or char",&buf[0]))return-1;}else{if(!PyArg_Parse(v,"b;%c requires int or char",&buf[0]))return-1;}buf[1]='\0';return1;}/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) FORMATBUFLEN is the length of the buffer in which the floats, ints, & chars are formatted. XXX This is a magic number. Each formatting routine does bounds checking to ensure no overflow, but a better solution may be to malloc a buffer of appropriate size for each format. For now, the current solution is sufficient.*/#define FORMATBUFLEN (size_t)120PyObject*PyString_Format(PyObject*format,PyObject*args){char*fmt,*res;intfmtcnt,rescnt,reslen,arglen,argidx;intargs_owned=0;PyObject*result,*orig_args;#ifdef Py_USING_UNICODEPyObject*v,*w;#endifPyObject*dict=NULL;if(format==NULL||!PyString_Check(format)||args==NULL){PyErr_BadInternalCall();returnNULL;}orig_args=args;fmt=PyString_AS_STRING(format);fmtcnt=PyString_GET_SIZE(format);reslen=rescnt=fmtcnt+100;result=PyString_FromStringAndSize((char*)NULL,reslen);if(result==NULL)returnNULL;res=PyString_AsString(result);if(PyTuple_Check(args)){arglen=PyTuple_GET_SIZE(args);argidx=0;}else{arglen=-1;argidx=-2;}if(args->ob_type->tp_as_mapping)dict=args;while(--fmtcnt>=0){if(*fmt!='%'){if(--rescnt<0){rescnt=fmtcnt+100;reslen+=rescnt;if(_PyString_Resize(&result,reslen)<0)returnNULL;res=PyString_AS_STRING(result)+reslen-rescnt;--rescnt;}*res++=*fmt++;}else{/* Got a format specifier */intflags=0;intwidth=-1;intprec=-1;intc='\0';intfill;PyObject*v=NULL;PyObject*temp=NULL;char*pbuf;intsign;intlen;charformatbuf[FORMATBUFLEN];/* For format{float,int,char}() */#ifdef Py_USING_UNICODEchar*fmt_start=fmt;intargidx_start=argidx;#endiffmt++;if(*fmt=='('){char*keystart;intkeylen;PyObject*key;intpcount=1;if(dict==NULL){PyErr_SetString(PyExc_TypeError,"format requires a mapping");gotoerror;}++fmt;--fmtcnt;keystart=fmt;/* Skip over balanced parentheses */while(pcount>0&&--fmtcnt>=0){if(*fmt==')')--pcount;elseif(*fmt=='(')++pcount;fmt++;}keylen=fmt-keystart-1;if(fmtcnt<0||pcount>0){PyErr_SetString(PyExc_ValueError,"incomplete format key");gotoerror;}key=PyString_FromStringAndSize(keystart,keylen);if(key==NULL)gotoerror;if(args_owned){Py_DECREF(args);args_owned=0;}args=PyObject_GetItem(dict,key);Py_DECREF(key);if(args==NULL){gotoerror;}args_owned=1;arglen=-1;argidx=-2;}while(--fmtcnt>=0){switch(c=*fmt++){case'-':flags|=F_LJUST;continue;case'+':flags|=F_SIGN;continue;case' ':flags|=F_BLANK;continue;case'#':flags|=F_ALT;continue;case'0':flags|=F_ZERO;continue;}break;}if(c=='*'){v=getnextarg(args,arglen,&argidx);if(v==NULL)gotoerror;if(!PyInt_Check(v)){PyErr_SetString(PyExc_TypeError,"* wants int");gotoerror;}width=PyInt_AsLong(v);if(width<0){flags|=F_LJUST;width=-width;}if(--fmtcnt>=0)c=*fmt++;}elseif(c>=0&&isdigit(c)){width=c-'0';while(--fmtcnt>=0){c=Py_CHARMASK(*fmt++);if(!isdigit(c))break;if((width*10)/10!=width){PyErr_SetString(PyExc_ValueError,"width too big");gotoerror;}width=width*10+(c-'0');}}if(c=='.'){prec=0;if(--fmtcnt>=0)c=*fmt++;if(c=='*'){v=getnextarg(args,arglen,&argidx);if(v==NULL)gotoerror;if(!PyInt_Check(v)){PyErr_SetString(PyExc_TypeError,"* wants int");gotoerror;}prec=PyInt_AsLong(v);if(prec<0)prec=0;if(--fmtcnt>=0)c=*fmt++;}elseif(c>=0&&isdigit(c)){prec=c-'0';while(--fmtcnt>=0){c=Py_CHARMASK(*fmt++);if(!isdigit(c))break;if((prec*10)/10!=prec){PyErr_SetString(PyExc_ValueError,"prec too big");gotoerror;}prec=prec*10+(c-'0');}}}/* prec */if(fmtcnt>=0){if(c=='h'||c=='l'||c=='L'){if(--fmtcnt>=0)c=*fmt++;}}if(fmtcnt<0){PyErr_SetString(PyExc_ValueError,"incomplete format");gotoerror;}if(c!='%'){v=getnextarg(args,arglen,&argidx);if(v==NULL)gotoerror;}sign=0;fill=' ';switch(c){case'%':pbuf="%";len=1;break;case's':#ifdef Py_USING_UNICODEif(PyUnicode_Check(v)){fmt=fmt_start;argidx=argidx_start;gotounicode;}#endif/* Fall through */case'r':if(c=='s')temp=PyObject_Str(v);elsetemp=PyObject_Repr(v);if(temp==NULL)gotoerror;if(!PyString_Check(temp)){PyErr_SetString(PyExc_TypeError,"%s argument has non-string str()");Py_DECREF(temp);gotoerror;}pbuf=PyString_AS_STRING(temp);len=PyString_GET_SIZE(temp);if(prec>=0&&len>prec)len=prec;break;case'i':case'd':case'u':case'o':case'x':case'X':if(c=='i')c='d';if(PyLong_Check(v)){temp=_PyString_FormatLong(v,flags,prec,c,&pbuf,&len);if(!temp)gotoerror;/* unbounded ints can always produce a sign character! */sign=1;}else{pbuf=formatbuf;len=formatint(pbuf,sizeof(formatbuf),flags,prec,c,v);if(len<0)gotoerror;/* only d conversion is signed */sign=c=='d';}if(flags&F_ZERO)fill='0';break;case'e':case'E':case'f':case'g':case'G':pbuf=formatbuf;len=formatfloat(pbuf,sizeof(formatbuf),flags,prec,c,v);if(len<0)gotoerror;sign=1;if(flags&F_ZERO)fill='0';break;case'c':pbuf=formatbuf;len=formatchar(pbuf,sizeof(formatbuf),v);if(len<0)gotoerror;break;default:PyErr_Format(PyExc_ValueError,"unsupported format character '%c' (0x%x) ""at index %i",c,c,(int)(fmt-1-PyString_AsString(format)));gotoerror;}if(sign){if(*pbuf=='-'||*pbuf=='+'){sign=*pbuf++;len--;}elseif(flags&F_SIGN)sign='+';elseif(flags&F_BLANK)sign=' ';elsesign=0;}if(width<len)width=len;if(rescnt-(sign!=0)<width){reslen-=rescnt;rescnt=width+fmtcnt+100;reslen+=rescnt;if(reslen<0){Py_DECREF(result);returnPyErr_NoMemory();}if(_PyString_Resize(&result,reslen)<0)returnNULL;res=PyString_AS_STRING(result)+reslen-rescnt;}if(sign){if(fill!=' ')*res++=sign;rescnt--;if(width>len)width--;}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)){do{--rescnt;*res++=fill;}while(--width>len);}if(fill==' '){if(sign)*res++=sign;if((flags&F_ALT)&&(c=='x'||c=='X')){assert(pbuf[0]=='0');assert(pbuf[1]==c);*res++=*pbuf++;*res++=*pbuf++;}}memcpy(res,pbuf,len);res+=len;rescnt-=len;while(--width>=len){--rescnt;*res++=' ';}if(dict&&(argidx<arglen)&&c!='%'){PyErr_SetString(PyExc_TypeError,"not all arguments converted");gotoerror;}Py_XDECREF(temp);}/* '%' */}/* until end */if(argidx<arglen&&!dict){PyErr_SetString(PyExc_TypeError,"not all arguments converted");gotoerror;}if(args_owned){Py_DECREF(args);}_PyString_Resize(&result,reslen-rescnt);returnresult;#ifdef Py_USING_UNICODEunicode:if(args_owned){Py_DECREF(args);args_owned=0;}/* Fiddle args right (remove the first argidx arguments) */if(PyTuple_Check(orig_args)&&argidx>0){PyObject*v;intn=PyTuple_GET_SIZE(orig_args)-argidx;v=PyTuple_New(n);if(v==NULL)gotoerror;while(--n>=0){PyObject*w=PyTuple_GET_ITEM(orig_args,n+argidx);Py_INCREF(w);PyTuple_SET_ITEM(v,n,w);}args=v;}else{Py_INCREF(orig_args);args=orig_args;}args_owned=1;/* Take what we have of the result and let the Unicode formatting function format the rest of the input. */rescnt=res-PyString_AS_STRING(result);if(_PyString_Resize(&result,rescnt))gotoerror;fmtcnt=PyString_GET_SIZE(format)- \
(fmt-PyString_AS_STRING(format));format=PyUnicode_Decode(fmt,fmtcnt,NULL,NULL);if(format==NULL)gotoerror;v=PyUnicode_Format(format,args);Py_DECREF(format);if(v==NULL)gotoerror;/* Paste what we have (result) to what the Unicode formatting function returned (v) and return the result (or error) */w=PyUnicode_Concat(result,v);Py_DECREF(result);Py_DECREF(v);Py_DECREF(args);returnw;#endif /* Py_USING_UNICODE */error:Py_DECREF(result);if(args_owned){Py_DECREF(args);}returnNULL;}#ifdef INTERN_STRINGS/* This dictionary will leak at PyString_Fini() time. That's acceptable * because PyString_Fini() specifically frees interned strings that are * only referenced by this dictionary. The CVS log entry for revision 2.45 * says: * * Change the Fini function to only remove otherwise unreferenced * strings from the interned table. There are references in * hard-to-find static variables all over the interpreter, and it's not * worth trying to get rid of all those; but "uninterning" isn't fair * either and may cause subtle failures later -- so we have to keep them * in the interned table. */staticPyObject*interned;voidPyString_InternInPlace(PyObject**p){registerPyStringObject*s=(PyStringObject*)(*p);PyObject*t;if(s==NULL||!PyString_Check(s))Py_FatalError("PyString_InternInPlace: strings only please!");if((t=s->ob_sinterned)!=NULL){if(t==(PyObject*)s)return;Py_INCREF(t);*p=t;Py_DECREF(s);return;}if(interned==NULL){interned=PyDict_New();if(interned==NULL)return;}if((t=PyDict_GetItem(interned,(PyObject*)s))!=NULL){Py_INCREF(t);*p=s->ob_sinterned=t;Py_DECREF(s);return;}/* Ensure that only true string objects appear in the intern dict, and as the value of ob_sinterned. */if(PyString_CheckExact(s)){t=(PyObject*)s;if(PyDict_SetItem(interned,t,t)==0){s->ob_sinterned=t;return;}}else{t=PyString_FromStringAndSize(PyString_AS_STRING(s),PyString_GET_SIZE(s));if(t!=NULL){if(PyDict_SetItem(interned,t,t)==0){*p=s->ob_sinterned=t;Py_DECREF(s);return;}Py_DECREF(t);}}PyErr_Clear();}PyObject*PyString_InternFromString(constchar*cp){PyObject*s=PyString_FromString(cp);if(s==NULL)returnNULL;PyString_InternInPlace(&s);returns;}#endifvoidPyString_Fini(void){inti;for(i=0;i<UCHAR_MAX+1;i++){Py_XDECREF(characters[i]);characters[i]=NULL;}#ifndef DONT_SHARE_SHORT_STRINGSPy_XDECREF(nullstring);nullstring=NULL;#endif#ifdef INTERN_STRINGSif(interned){intpos,changed;PyObject*key,*value;do{changed=0;pos=0;while(PyDict_Next(interned,&pos,&key,&value)){if(key->ob_refcnt==2&&key==value){PyDict_DelItem(interned,key);changed=1;}}}while(changed);}#endif}#ifdef INTERN_STRINGSvoid_Py_ReleaseInternedStrings(void){if(interned){fprintf(stderr,"releasing interned strings\n");PyDict_Clear(interned);Py_DECREF(interned);interned=NULL;}}#endif /* INTERN_STRINGS */