static PyObject* PyLocale_strcoll(PyObject* self, PyObject* args) { #if !defined(HAVE_WCSCOLL) || !defined(Py_USING_UNICODE) char *s1,*s2; if (!PyArg_ParseTuple(args, "ss:strcoll", &s1, &s2)) return NULL; return PyInt_FromLong(strcoll(s1, s2)); #else PyObject *os1, *os2, *result = NULL; wchar_t *ws1 = NULL, *ws2 = NULL; int rel1 = 0, rel2 = 0, len1, len2; if (!PyArg_UnpackTuple(args, "strcoll", 2, 2, &os1, &os2)) return NULL; /* If both arguments are byte strings, use strcoll. */ if (PyString_Check(os1) && PyString_Check(os2)) return PyInt_FromLong(strcoll(PyString_AS_STRING(os1), PyString_AS_STRING(os2))); /* If neither argument is unicode, it's an error. */ if (!PyUnicode_Check(os1) && !PyUnicode_Check(os2)) { PyErr_SetString(PyExc_ValueError, "strcoll arguments must be strings"); } /* Convert the non-unicode argument to unicode. */ if (!PyUnicode_Check(os1)) { os1 = PyUnicode_FromObject(os1); if (!os1) return NULL; rel1 = 1; } if (!PyUnicode_Check(os2)) { os2 = PyUnicode_FromObject(os2); if (!os2) { if (rel1) { Py_DECREF(os1); } return NULL; } rel2 = 1; } /* Convert the unicode strings to wchar[]. */ len1 = PyUnicode_GET_SIZE(os1) + 1; ws1 = PyMem_MALLOC(len1 * sizeof(wchar_t)); if (!ws1) { PyErr_NoMemory(); goto done; } if (PyUnicode_AsWideChar((PyUnicodeObject*)os1, ws1, len1) == -1) goto done; ws1[len1 - 1] = 0; len2 = PyUnicode_GET_SIZE(os2) + 1; ws2 = PyMem_MALLOC(len2 * sizeof(wchar_t)); if (!ws2) { PyErr_NoMemory(); goto done; } if (PyUnicode_AsWideChar((PyUnicodeObject*)os2, ws2, len2) == -1) goto done; ws2[len2 - 1] = 0; /* Collate the strings. */ result = PyInt_FromLong(wcscoll(ws1, ws2)); done: /* Deallocate everything. */ if (ws1) PyMem_FREE(ws1); if (ws2) PyMem_FREE(ws2); if (rel1) { Py_DECREF(os1); } if (rel2) { Py_DECREF(os2); } return result; #endif }
static int prepare_s(PyStructObject *self) { const formatdef *f; const formatdef *e; formatcode *codes; const char *s; const char *fmt; char c; Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); f = whichtable((char **)&fmt); s = fmt; size = 0; len = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { /* overflow-safe version of if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ if (num >= PY_SSIZE_T_MAX / 10 && ( num > PY_SSIZE_T_MAX / 10 || (c - '0') > PY_SSIZE_T_MAX % 10)) goto overflow; num = num*10 + (c - '0'); } if (c == '\0') { PyErr_SetString(StructError, "repeat count given without format specifier"); return -1; } } else num = 1; e = getentry(c, f); if (e == NULL) return -1; switch (c) { case 's': /* fall through */ case 'p': len++; break; case 'x': break; default: len += num; break; } itemsize = e->size; size = align(size, c, e); if (size == -1) goto overflow; /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ if (num > (PY_SSIZE_T_MAX - size) / itemsize) goto overflow; size += num * itemsize; } /* check for overflow */ if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { PyErr_NoMemory(); return -1; } self->s_size = size; self->s_len = len; codes = (formatcode *) PyMem_MALLOC((len + 1) * sizeof(formatcode)); if (codes == NULL) { PyErr_NoMemory(); return -1; } /* Free any s_codes value left over from a previous initialization. */ if (self->s_codes != NULL) PyMem_FREE(self->s_codes); self->s_codes = codes; s = fmt; size = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') num = num*10 + (c - '0'); if (c == '\0') break; } else num = 1; e = getentry(c, f); size = align(size, c, e); if (c == 's' || c == 'p') { codes->offset = size; codes->size = num; codes->fmtdef = e; codes++; size += num; } else if (c == 'x') { size += num; } else { while (--num >= 0) { codes->offset = size; codes->size = e->size; codes->fmtdef = e; codes++; size += e->size; } } } codes->fmtdef = NULL; codes->offset = size; codes->size = 0; return 0; overflow: PyErr_SetString(StructError, "total struct size too long"); return -1; }
int exceptionlist__initmodule(PyObject* module, struct exceptionlist* exclist) { const struct exceptionlist* exc; char* longname = NULL; PyObject* name; Py_ssize_t size; Py_ssize_t maxsize; if ((name = PyObject_GetAttrString(module, "__name__")) == NULL) return -1; if (!PyString_Check(name)) { PyErr_SetString(PyExc_TypeError, "__name__ required an str()"); goto failed; } size = PyString_GET_SIZE(name); for (maxsize = 0, exc = exclist; exc->exc_name != NULL; exc++) { register int i = strlen(exc->exc_name); if (i > maxsize) maxsize = i; } if ((longname = PyMem_MALLOC(size + sizeof(".") + maxsize + sizeof("\0"))) == NULL) { PyErr_NoMemory(); goto failed; } memcpy(longname, PyString_AS_STRING(name), size); Py_DECREF(name); longname[size++] = '.'; for (exc = exclist; exc->exc_name != NULL; exc++) { PyObject* dict; PyObject* s; if ((dict = PyDict_New()) == NULL) goto failed; if ((s = PyString_FromString(exc->exc_doc)) == NULL) { Py_DECREF(dict); goto failed; } if (PyDict_SetItemString(dict, "__doc__", s) < 0) { Py_DECREF(dict); Py_DECREF(s); goto failed; } Py_DECREF(s); strcpy(&longname[size], exc->exc_name); if (*exc->exc_this == NULL && (*exc->exc_this = PyErr_NewException(longname, *exc->exc_base, dict)) == NULL) { Py_DECREF(dict); goto failed; } Py_DECREF(dict); } PyMem_FREE(longname); for (exc = exclist; exc->exc_name != NULL; exc++) { Py_INCREF(*exc->exc_this); if (PyModule_AddObject(module, exc->exc_name, *exc->exc_this) < 0) return -1; } return 0; failed: if (longname != NULL) PyMem_FREE(longname); Py_DECREF(name); return -1; }
/* TODO, multi-dimensional arrays */ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) { int len = RNA_property_array_length(ptr, prop); int type; int i; if (len == 0) /* possible with dynamic arrays */ return 0; if (RNA_property_array_dimension(ptr, prop, NULL) > 1) { PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet"); return -1; } type = RNA_property_type(prop); switch (type) { case PROP_FLOAT: { float value_f = PyFloat_AsDouble(value); if (value_f == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } else { float tmp[32]; float *tmp_arr; if (len * sizeof(float) > sizeof(tmp)) { tmp_arr = PyMem_MALLOC(len * sizeof(float)); } else { tmp_arr = tmp; } RNA_property_float_get_array(ptr, prop, tmp_arr); for (i = 0; i < len; i++) { if (tmp_arr[i] == value_f) { break; } } if (tmp_arr != tmp) PyMem_FREE(tmp_arr); return i < len ? 1 : 0; } break; } case PROP_BOOLEAN: case PROP_INT: { int value_i = PyLong_AsSsize_t(value); if (value_i == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } else { int tmp[32]; int *tmp_arr; if (len * sizeof(int) > sizeof(tmp)) { tmp_arr = PyMem_MALLOC(len * sizeof(int)); } else { tmp_arr = tmp; } if (type == PROP_BOOLEAN) RNA_property_boolean_get_array(ptr, prop, tmp_arr); else RNA_property_int_get_array(ptr, prop, tmp_arr); for (i = 0; i < len; i++) { if (tmp_arr[i] == value_i) { break; } } if (tmp_arr != tmp) PyMem_FREE(tmp_arr); return i < len ? 1 : 0; } break; } } /* should never reach this */ PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int"); return -1; }
static PyObject * marshal_Load_internal(PyObject *py_stream, PyObject *py_callback, int skipcrc) { // Return value: New Reference char *stream; Py_ssize_t size; char *s; char *end; int type = -1; // current object type int shared = -1; // indicates whether current object is shared int i; char *error = "NO ERROR SPECIFIED"; char errortext[256]; Py_ssize_t length = 0; // generic length value. int shared_mapsize; int shared_count; // shared object index counter int *shared_map; // points to shared object mapping at end of stream PyObject **shared_obj = NULL; // holds the shared objects PyObject *obj = NULL; // currently decoded object PyObject *result = NULL; // final result int ct_ix = 0; struct Container ct_stack[MAX_DEPTH]; struct Container *container = &ct_stack[0]; if(PyString_AsStringAndSize(py_stream, &stream, &size) == -1) return NULL; s = stream; container->obj = NULL; container->type = 0; container->free = -1; container->index = 0; if(size < 6 || *s++ != PROTOCOL_ID) { int offset = 0; result = unpickle(py_stream, &offset); if(!result) goto cleanup; return result; } // how many shared objects in this stream? shared_mapsize = *(int32_t *)s; s += 4; // Security Check: assert there is enough data for that many items. if((5 + shared_mapsize*4) > size) { PyErr_Format(UnmarshalError, "Not enough room in stream for map. Wanted %d, but have only %d bytes remaining...", (shared_mapsize*4), ((int)size-5)); goto cleanup; } // ok, we got the map data right here... shared_map = (int32_t *)&stream[size - shared_mapsize * 4]; // Security Check #2: assert all map entries are between 1 and shared_mapsize for(i=0; i<shared_mapsize; i++) { if( (shared_map[i] > shared_mapsize) || (shared_map[i] < 1) ) { PyErr_SetString(UnmarshalError, "Bogus map data in marshal stream"); goto cleanup; } } // the start of which is incidentally also the end of the object data. end = (char *)shared_map; // create object table shared_obj = PyMem_MALLOC(shared_mapsize * sizeof(PyObject *)); if(!shared_obj) goto cleanup; // zero out object table for(shared_count = 0; shared_count < shared_mapsize; shared_count++) shared_obj[shared_count] = NULL; shared_count = 0; // start decoding. while(s < end) { // This outer loop is responsible for reading and decoding the next // object from the stream. The object is then handed to the inner loop, // which adds it to the current container, or returns it to the caller. // get type of next object to decode and check shared flag type = *s++; shared = type & SHARED_FLAG; type &= ~SHARED_FLAG; // if token uses a normal length value, read it now. if(needlength[type]) { READ_LENGTH; } else length = 0; #if MARSHAL_DEBUG // if(shared) { char text[220]; DEBUG_INDENT; sprintf(text, "pos:%4d type:%s(0x%02x) shared:%d len:%4d map:[", s-stream, tokenname[type], type, shared?1:0, length); printf(text); for(i=0; i<shared_mapsize; i++) printf("%d(%d),", shared_obj[i], shared_obj[i] ? ((PyObject *)(shared_obj[i]))->ob_refcnt : 0); printf("]\r\n"); } #endif // MARSHAL_DEBUG switch(type) { // // break statement: // attempts to add the newly decoded object (in the obj variable) to // the currently building container object. // // continue statement: // indicates the decoded object or type marker was handled/consumed // by the case and should _not_ be added to the currently building // container object or used in any other way; immediately decode a // new object // //--------------------------------------------------------------------- // SCALAR TYPES //--------------------------------------------------------------------- case TYPE_INT8: CHECK_SIZE(1); obj = PyInt_FromLong(*(int8_t *)s); s++; break; case TYPE_INT16: CHECK_SIZE(2); obj = PyInt_FromLong(*(int16_t *)s); s += 2; break; case TYPE_INT32: CHECK_SIZE(4); obj = PyInt_FromLong(*(int32_t *)s); s += 4; break; case TYPE_INT64: CHECK_SIZE(8); obj = PyLong_FromLongLong(*(int64_t *)s); s += 8; break; case TYPE_LONG: CHECK_SIZE(length); if(!length) obj = PyLong_FromLong(0); else { obj = _PyLong_FromByteArray((unsigned char *)s, length, 1, 1); Py_INCREF(obj); } CHECK_SHARED(obj); s += length; break; case TYPE_FLOAT: CHECK_SIZE(8); obj = PyFloat_FromDouble(*(double *)s); s += 8; break; case TYPE_CHECKSUM: CHECK_SIZE(4); if(!skipcrc && (*(uint32_t *)s != (uint32_t)adler32(1, s, (unsigned long)(end-s)))) { error = "checksum error"; goto fail; } s += 4; // because this type does not yield an object, go grab another // object right away! continue; //--------------------------------------------------------------------- // STRING TYPES //--------------------------------------------------------------------- case TYPE_STRINGR: if (length < 1 || length >= PyList_GET_SIZE(string_table)) { if(PyList_GET_SIZE(string_table)) PyErr_Format(UnmarshalError, "Invalid string table index %d", (int)length); else PyErr_SetString(PyExc_RuntimeError, "_stringtable not initialized"); goto cleanup; } obj = PyList_GET_ITEM(string_table, length); Py_INCREF(obj); break; case TYPE_STRING: // appears to be deprecated since machoVersion 213 CHECK_SIZE(1); length = *(unsigned char *)s++; CHECK_SIZE(length); obj = PyString_FromStringAndSize(s, length); s += length; break; case TYPE_STRING1: CHECK_SIZE(1); obj = PyString_FromStringAndSize(s, 1); s++; break; case TYPE_STREAM: // fallthrough, can be treated as string. case TYPE_STRINGL: // fallthrough, deprecated since machoVersion 213 case TYPE_BUFFER: // Type identifier re-used by CCP. treat as string. CHECK_SIZE(length); obj = PyString_FromStringAndSize(s, length); s += length; CHECK_SHARED(obj); break; case TYPE_UNICODE1: CHECK_SIZE(2); #ifdef Py_UNICODE_WIDE obj = _PyUnicodeUCS4_FromUCS2((void *)s, 1); #else obj = PyUnicode_FromWideChar((wchar_t *)s, 1); #endif s += 2; break; case TYPE_UNICODE: CHECK_SIZE(length*2); #ifdef Py_UNICODE_WIDE obj = _PyUnicodeUCS4_FromUCS2((void *)s, (int)length); #else obj = PyUnicode_FromWideChar((wchar_t *)s, length); #endif s += length*2; break; case TYPE_UTF8: CHECK_SIZE(length); obj = PyUnicode_DecodeUTF8(s, length, NULL); s += length; break; //--------------------------------------------------------------------- // SEQUENCE/MAPPING TYPES //--------------------------------------------------------------------- case TYPE_TUPLE1: NEW_SEQUENCE(TYPE_TUPLE, 1); continue; case TYPE_TUPLE2: NEW_SEQUENCE(TYPE_TUPLE, 2); continue; case TYPE_TUPLE: NEW_SEQUENCE(TYPE_TUPLE, (int)length); continue; case TYPE_LIST0: obj = PyList_New(0); CHECK_SHARED(obj); break; case TYPE_LIST1: NEW_SEQUENCE(TYPE_LIST, 1); continue; case TYPE_LIST: NEW_SEQUENCE(TYPE_LIST, (int)length); continue; case TYPE_DICT: if(length) { CHECK_SIZE(length*2); PUSH_CONTAINER(TYPE_DICT, (int)length*2); container->obj = PyDict_New(); container->obj2 = NULL; container->index = 0; CHECK_SHARED(container->obj); continue; } else { obj = PyDict_New(); CHECK_SHARED(obj); break; } //--------------------------------------------------------------------- // OBJECT TYPES //--------------------------------------------------------------------- case TYPE_REF: // length value is index in sharedobj array! if((length < 1 || length > shared_mapsize)) { error = "Shared reference index out of range"; goto fail; } if(!(obj = shared_obj[length-1])) { error = "Shared reference points to invalid object"; goto fail; } Py_INCREF(obj); //printf("Getting object %d from %d (refs:%d)\r\n", (int)obj, length-1, obj->ob_refcnt); break; case TYPE_GLOBAL: { PyObject *name; CHECK_SIZE(length); name = PyString_FromStringAndSize(s, length); if(!name) goto cleanup; s += length; if(!(obj = find_global(name))) { // exception should be set by find_global goto cleanup; } Py_DECREF(name); CHECK_SHARED(obj); break; } case TYPE_DBROW: case TYPE_INSTANCE: case TYPE_NEWOBJ: case TYPE_REDUCE: PUSH_CONTAINER(type, -1); container->obj = NULL; RESERVE_SLOT(container->index); continue; case TYPE_MARK: // this is a marker, not a real object. list/dict iterators check // for this type, but it can't be instantiated. break; default: if((obj = constants[type])) { Py_INCREF(obj); } else { error = "Unsupported type"; goto fail; } } // object decoding and construction done! if(!obj && type != TYPE_MARK) { // if obj is somehow NULL, whatever caused it is expected to have // set an exception at this point. goto cleanup; } #if MARSHAL_DEBUG /* if(obj && obj->ob_refcnt < 0) { char b[200]; sprintf(b, "type: %d, refcount: %d", type, obj->ob_refcnt); DEBUG(b); } */ if(obj) { DEBUG_INDENT; printf("`-- "); PyObject_Print(obj, stdout, 0); printf("\r\n"); fflush(stdout); } else { DEBUG_INDENT; printf("*** MARK\r\n"); } #endif // MARSHAL_DEBUG while(1) { // This inner loop does one of two things: // // - return the finished object to the caller if we're at the root // container. // // - add the object to the current container in a container- // specific manner. note that ownership of the reference is to be // given to the container object. #if MARSHAL_DEBUG { //char text[220]; DEBUG_INDENT; printf("container ix:%d (%08lx) type:%s[0x%02x] free:%d index:%d\r\n", ct_ix, container->obj, tokenname[container->type], container->type, container->free, container->index); } #endif // MARSHAL_DEBUG /* if(!container->obj) { error = "Root container popped off stack"; goto fail; } */ switch(container->type) { case TYPE_TUPLE: // tuples steal references. PyTuple_SET_ITEM(container->obj, container->index++, obj); break; case TYPE_LIST: // lists steal references. PyList_SET_ITEM(container->obj, container->index++, obj); break; case TYPE_DBROW: if(container->obj) { // we have an initialized DBRow. current object is a // non-scalar object for the row. append it. if(!dbrow_append_internal((PyDBRowObject *)container->obj, obj)) { // append call will have set an exception here. goto cleanup; } } else { // we now have a DBRowDescriptor, and the header data // should follow. Pull it and create the DBRow. READ_LENGTH; CHECK_SIZE(length); container->obj = PyDBRow_New((PyDBRowDescriptorObject *)obj, s, (int)length); container->free = 1+((PyDBRowDescriptorObject *)obj)->rd_num_objects; if(!container->obj) goto cleanup; Py_DECREF(obj); s += length; // add as shared object, if neccessary... UPDATE_SLOT(container->index, container->obj); } break; case TYPE_INSTANCE: { PyObject *cls; if(container->free == -1) { // create class instance if(!(cls = find_global(obj))) goto cleanup; container->obj = PyInstance_NewRaw(cls, 0); Py_DECREF(cls); if(!container->obj) goto cleanup; UPDATE_SLOT(container->index, container->obj); Py_DECREF(obj); break; } if(container->free == -2) { container->free = 1; // set state. if(!set_state(container->obj, obj)) goto cleanup; Py_DECREF(obj); break; } error = "invalid container state"; goto fail; } case TYPE_NEWOBJ: { PyObject *cls, *args, *__new__, *state; // instantiate the object... if(!(args = PyTuple_GetItem(obj, 0))) goto cleanup; if(!(cls = PyTuple_GetItem(args, 0))) goto cleanup; __new__ = PyObject_GetAttr(cls, py__new__); if(!__new__) goto cleanup; container->obj = PyObject_CallObject(__new__, args); Py_DECREF(__new__); if(!container->obj) goto cleanup; // add as shared object, if neccessary... UPDATE_SLOT(container->index, container->obj); // is there state data? if(PyTuple_GET_SIZE(obj) > 1) { state = PyTuple_GET_ITEM(obj, 1); if(!set_state(container->obj, state)) goto cleanup; } Py_DECREF(obj); // switch to list iterator LIST_ITERATOR; break; } case TYPE_REDUCE: { PyObject *callable, *args, *state; if(!(args = PyTuple_GetItem(obj, 1))) goto cleanup; if(!(callable = PyTuple_GET_ITEM(obj, 0))) goto cleanup; if(!(container->obj = PyObject_CallObject(callable, args))) goto cleanup; UPDATE_SLOT(container->index, container->obj); if(PyTuple_GET_SIZE(obj) > 2) { state = PyTuple_GET_ITEM(obj, 2); if(!set_state(container->obj, state)) goto cleanup; } Py_DECREF(obj); // switch to list iterator LIST_ITERATOR; break; } case TYPE_LIST_ITERATOR: if(type == TYPE_MARK) { // clear mark so nested iterator containers do not get terminated prematurely. type = -1; // decref the append method Py_XDECREF(container->obj2); container->obj2 = NULL; container->type = TYPE_DICT_ITERATOR; break; } if(!container->obj2) { // grab the append method from the container and keep // it around for speed. if(!(container->obj2 = PyObject_GetAttr(container->obj, pyappend))) goto cleanup; } if(!PyObject_CallFunctionObjArgs(container->obj2, obj, NULL)) goto cleanup; #if MARSHAL_DEBUG DEBUG_INDENT; printf("Appended %08lx to %08lx\r\n", obj, container->obj); #endif // MARSHAL_DEBUG Py_DECREF(obj); break; case TYPE_DICT_ITERATOR: if(type == TYPE_MARK) { // clear mark so nested iterator containers do not get terminated prematurely. type = -1; // we're done with dict iter. container is finished. container->free = 1; break; } POPULATE_DICT(container->obj2, obj); break; case TYPE_DICT: POPULATE_DICT(obj, container->obj2); break; case 0: // we're at the root. return the object to caller. result = obj; // avoid decreffing this object. obj = NULL; goto cleanup; } container->free--; if(container->free) // still room in this container. // break out of container handling to get next object for it. break; // this container is done, it is the next object to put into the // container under it! obj = container->obj; // switch context to said older container POP_CONTAINER; } // we've processed the object. clear it for next one. obj = NULL; } // if we get here, we're out of data, but it's a "clean" eof; we ran out // of data while expecting a new object... error = "Not enough objects in stream"; fail: PyErr_Format(UnmarshalError, "%s - type:0x%02x ctype:0x%02x len:%d share:%d pos:%d size:%d", error, type, container->type, (int)length, shared, (int)(s-stream), (int)(size)); cleanup: // on any error the current object we were working on will be unassociated // with anything, decref it. if decode was succesful or an object failed to // be created, it will be NULL anyway. Py_XDECREF(obj); // same story for containers... while(container->type) { Py_XDECREF(container->obj); // possibly unassociated object for dict entry? if(container->type == TYPE_DICT || container->type == TYPE_DICT_ITERATOR) { Py_XDECREF(container->obj2); } POP_CONTAINER; } if(shared_obj) { /* shared object list held a safety ref to all objects, decref em */ int i; for(i=0; i<shared_mapsize; i++) Py_XDECREF(shared_obj[i]); /* and free the list */ PyMem_FREE(shared_obj); } return result; }
static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { const char *s, *start; char *end; double x=0.0, y=0.0, z; int got_bracket=0; #ifdef Py_USING_UNICODE char *s_buffer = NULL; #endif Py_ssize_t len; if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(v)) { s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1); if (s_buffer == NULL) return PyErr_NoMemory(); if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), s_buffer, NULL)) goto error; s = s_buffer; len = strlen(s); } #endif else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, "complex() arg is not a string"); return NULL; } /* position on first nonblank */ start = s; while (Py_ISSPACE(*s)) s++; if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; while (Py_ISSPACE(*s)) s++; } /* a valid complex string usually takes one of the three forms: <float> - real part only <float>j - imaginary part only <float><signed-float>j - real and imaginary parts where <float> represents any numeric string that's accepted by the float constructor (including 'nan', 'inf', 'infinity', etc.), and <signed-float> is any string of the form <float> whose first character is '+' or '-'. For backwards compatibility, the extra forms <float><sign>j <sign>j j are also accepted, though support for these forms may be removed from a future version of Python. */ /* first look for forms starting with <float> */ z = PyOS_string_to_double(s, &end, NULL); if (z == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) { /* all 4 forms starting with <float> land here */ s = end; if (*s == '+' || *s == '-') { /* <float><signed-float>j | <float><sign>j */ x = z; y = PyOS_string_to_double(s, &end, NULL); if (y == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) /* <float><signed-float>j */ s = end; else { /* <float><sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } else if (*s == 'j' || *s == 'J') { /* <float>j */ s++; y = z; } else /* <float> */ x = z; } else { /* not starting with <float>; must be <sign>j or j */ if (*s == '+' || *s == '-') { /* <sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } else /* j */ y = 1.0; if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } /* trailing whitespace and closing bracket */ while (Py_ISSPACE(*s)) s++; if (got_bracket) { /* if there was an opening parenthesis, then the corresponding closing parenthesis should be right here */ if (*s != ')') goto parse_error; s++; while (Py_ISSPACE(*s)) s++; } /* we should now be at the end of the string */ if (s-start != len) goto parse_error; #ifdef Py_USING_UNICODE if (s_buffer) PyMem_FREE(s_buffer); #endif return complex_subtype_from_doubles(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: #ifdef Py_USING_UNICODE if (s_buffer) PyMem_FREE(s_buffer); #endif return NULL; }
static int tok_nextc(register struct tok_state *tok) { for (;;) { if (tok->cur != tok->inp) { return Py_CHARMASK(*tok->cur++); /* Fast path */ } if (tok->done != E_OK) return EOF; if (tok->fp == NULL) { char *end = strchr(tok->inp, '\n'); if (end != NULL) end++; else { end = strchr(tok->inp, '\0'); if (end == tok->inp) { tok->done = E_EOF; return EOF; } } if (tok->start == NULL) tok->buf = tok->cur; tok->line_start = tok->cur; tok->lineno++; tok->inp = end; return Py_CHARMASK(*tok->cur++); } if (tok->prompt != NULL) { char *newtok = PyOS_Readline(stdin, stdout, tok->prompt); if (tok->nextprompt != NULL) tok->prompt = tok->nextprompt; if (newtok == NULL) tok->done = E_INTR; else if (*newtok == '\0') { PyMem_FREE(newtok); tok->done = E_EOF; } #if !defined(PGEN) && defined(Py_USING_UNICODE) else if (tok_stdin_decode(tok, &newtok) != 0) PyMem_FREE(newtok); #endif else if (tok->start != NULL) { size_t start = tok->start - tok->buf; size_t oldlen = tok->cur - tok->buf; size_t newlen = oldlen + strlen(newtok); char *buf = tok->buf; buf = (char *)PyMem_REALLOC(buf, newlen+1); tok->lineno++; if (buf == NULL) { PyMem_FREE(tok->buf); tok->buf = NULL; PyMem_FREE(newtok); tok->done = E_NOMEM; return EOF; } tok->buf = buf; tok->cur = tok->buf + oldlen; tok->line_start = tok->cur; strcpy(tok->buf + oldlen, newtok); PyMem_FREE(newtok); tok->inp = tok->buf + newlen; tok->end = tok->inp + 1; tok->start = tok->buf + start; } else { tok->lineno++; if (tok->buf != NULL) PyMem_FREE(tok->buf); tok->buf = newtok; tok->line_start = tok->buf; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); tok->end = tok->inp + 1; } } else { int done = 0; Py_ssize_t cur = 0; char *pt; if (tok->start == NULL) { if (tok->buf == NULL) { tok->buf = (char *) PyMem_MALLOC(BUFSIZ); if (tok->buf == NULL) { tok->done = E_NOMEM; return EOF; } tok->end = tok->buf + BUFSIZ; } if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), tok) == NULL) { tok->done = E_EOF; done = 1; } else { tok->done = E_OK; tok->inp = strchr(tok->buf, '\0'); done = tok->inp[-1] == '\n'; } } else { cur = tok->cur - tok->buf; if (decoding_feof(tok)) { tok->done = E_EOF; done = 1; } else tok->done = E_OK; } tok->lineno++; /* Read until '\n' or EOF */ while (!done) { Py_ssize_t curstart = tok->start == NULL ? -1 : tok->start - tok->buf; Py_ssize_t curvalid = tok->inp - tok->buf; Py_ssize_t newsize = curvalid + BUFSIZ; char *newbuf = tok->buf; newbuf = (char *)PyMem_REALLOC(newbuf, newsize); if (newbuf == NULL) { tok->done = E_NOMEM; tok->cur = tok->inp; return EOF; } tok->buf = newbuf; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; tok->start = curstart < 0 ? NULL : tok->buf + curstart; if (decoding_fgets(tok->inp, (int)(tok->end - tok->inp), tok) == NULL) { /* Break out early on decoding errors, as tok->buf will be NULL */ if (tok->decoding_erred) return EOF; /* Last line does not end in \n, fake one */ strcpy(tok->inp, "\n"); } tok->inp = strchr(tok->inp, '\0'); done = tok->inp[-1] == '\n'; } if (tok->buf != NULL) { tok->cur = tok->buf + cur; tok->line_start = tok->cur; /* replace "\r\n" with "\n" */ /* For Mac leave the \r, giving a syntax error */ pt = tok->inp - 2; if (pt >= tok->buf && *pt == '\r') { *pt++ = '\n'; *pt = '\0'; tok->inp = pt; } } } if (tok->done != E_OK) { if (tok->prompt != NULL) PySys_WriteStderr("\n"); tok->cur = tok->inp; return EOF; } } /*NOTREACHED*/ }
static void calcfirstset(grammar *g, dfa *d) { int i, j; state *s; arc *a; int nsyms; int *sym; int nbits; static bitset dummy; bitset result; int type; dfa *d1; label *l0; #ifndef NDEBUG printf("Calculate FIRST set for '%.*s'\n", (int)d->d_name_length, d->d_name); #endif if (dummy == NULL) dummy = newbitset(1); if (d->d_first == dummy) { fprintf(stderr, "Left-recursion for '%.*s'\n", (int)d->d_name_length, d->d_name); return; } if (d->d_first != NULL) { fprintf(stderr, "Re-calculating FIRST set for '%.*s' ???\n", (int)d->d_name_length, d->d_name); } d->d_first = dummy; l0 = g->g_ll.ll_label; nbits = g->g_ll.ll_nlabels; result = newbitset(nbits); sym = (int *)PyMem_MALLOC(sizeof(int)); if (sym == NULL) Py_FatalError("no mem for new sym in calcfirstset"); nsyms = 1; sym[0] = findlabel(&g->g_ll, d->d_type, UC(NULL), 0); s = &d->d_state[d->d_initial]; for (i = 0; i < s->s_narcs; i++) { a = &s->s_arc[i]; for (j = 0; j < nsyms; j++) { if (sym[j] == a->a_lbl) break; } if (j >= nsyms) { /* New label */ sym = (int *)PyMem_REALLOC(sym, sizeof(int) * (nsyms + 1)); if (sym == NULL) Py_FatalError( "no mem to resize sym in calcfirstset"); sym[nsyms++] = a->a_lbl; type = l0[a->a_lbl].lb_type; if (ISNONTERMINAL(type)) { d1 = PyGrammar_FindDFA(g, type); if (d1->d_first == dummy) { fprintf(stderr, "Left-recursion below '%.*s'\n", (int)d->d_name_length, d->d_name); } else { if (d1->d_first == NULL) calcfirstset(g, d1); mergebitset(result, d1->d_first, nbits); } } else if (ISTERMINAL(type)) { addbit(result, a->a_lbl); } } } d->d_first = result; PyMem_FREE(sym); }
PyCodeObject * PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab) { PyCodeObject *co; unsigned char *cell2arg = NULL; Py_ssize_t i, n_cellvars; /* Check argument types */ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || code == NULL || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || freevars == NULL || !PyTuple_Check(freevars) || cellvars == NULL || !PyTuple_Check(cellvars) || name == NULL || !PyUnicode_Check(name) || filename == NULL || !PyUnicode_Check(filename) || lnotab == NULL || !PyBytes_Check(lnotab) || !PyObject_CheckReadBuffer(code)) { PyErr_BadInternalCall(); return NULL; } /* Ensure that the filename is a ready Unicode string */ if (PyUnicode_READY(filename) < 0) return NULL; n_cellvars = PyTuple_GET_SIZE(cellvars); intern_strings(names); intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); /* Intern selected string constants */ for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { PyObject *v = PyTuple_GetItem(consts, i); if (!all_name_chars(v)) continue; PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); } /* Create mapping between cells and arguments if needed. */ if (n_cellvars) { Py_ssize_t total_args = argcount + kwonlyargcount + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars; int used_cell2arg = 0; cell2arg = PyMem_MALLOC(alloc_size); if (cell2arg == NULL) return NULL; memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size); /* Find cells which are also arguments. */ for (i = 0; i < n_cellvars; i++) { Py_ssize_t j; PyObject *cell = PyTuple_GET_ITEM(cellvars, i); for (j = 0; j < total_args; j++) { PyObject *arg = PyTuple_GET_ITEM(varnames, j); if (!PyUnicode_Compare(cell, arg)) { cell2arg[i] = j; used_cell2arg = 1; break; } } } if (!used_cell2arg) { PyMem_FREE(cell2arg); cell2arg = NULL; } } co = PyObject_NEW(PyCodeObject, &PyCode_Type); if (co == NULL) { if (cell2arg) PyMem_FREE(cell2arg); return NULL; } co->co_argcount = argcount; co->co_kwonlyargcount = kwonlyargcount; co->co_nlocals = nlocals; co->co_stacksize = stacksize; co->co_flags = flags; Py_INCREF(code); co->co_code = code; Py_INCREF(consts); co->co_consts = consts; Py_INCREF(names); co->co_names = names; Py_INCREF(varnames); co->co_varnames = varnames; Py_INCREF(freevars); co->co_freevars = freevars; Py_INCREF(cellvars); co->co_cellvars = cellvars; co->co_cell2arg = cell2arg; Py_INCREF(filename); co->co_filename = filename; Py_INCREF(name); co->co_name = name; co->co_firstlineno = firstlineno; Py_INCREF(lnotab); co->co_lnotab = lnotab; co->co_zombieframe = NULL; co->co_weakreflist = NULL; return co; }
PyObject * PyModule_Create2(struct PyModuleDef* module, int module_api_version) { PyObject *d, *v, *n; PyMethodDef *ml; const char* name; PyModuleObject *m; PyInterpreterState *interp = PyThreadState_Get()->interp; if (interp->modules == NULL) Py_FatalError("Python import machinery not initialized"); if (PyType_Ready(&moduledef_type) < 0) return NULL; if (module->m_base.m_index == 0) { max_module_number++; Py_REFCNT(module) = 1; Py_TYPE(module) = &moduledef_type; module->m_base.m_index = max_module_number; } name = module->m_name; if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { int err; err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "Python C API version mismatch for module %.100s: " "This Python has API version %d, module %.100s has version %d.", name, PYTHON_API_VERSION, name, module_api_version); if (err) return NULL; } /* Make sure name is fully qualified. This is a bit of a hack: when the shared library is loaded, the module name is "package.module", but the module calls PyModule_Create*() with just "module" for the name. The shared library loader squirrels away the true name of the module in _Py_PackageContext, and PyModule_Create*() will substitute this (if the name actually matches). */ if (_Py_PackageContext != NULL) { char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(module->m_name, p+1) == 0) { name = _Py_PackageContext; _Py_PackageContext = NULL; } } if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; if (module->m_size > 0) { m->md_state = PyMem_MALLOC(module->m_size); if (!m->md_state) { PyErr_NoMemory(); Py_DECREF(m); return NULL; } memset(m->md_state, 0, module->m_size); } d = PyModule_GetDict((PyObject*)m); if (module->m_methods != NULL) { n = PyUnicode_FromString(name); if (n == NULL) { Py_DECREF(m); return NULL; } for (ml = module->m_methods; ml->ml_name != NULL; ml++) { if ((ml->ml_flags & METH_CLASS) || (ml->ml_flags & METH_STATIC)) { PyErr_SetString(PyExc_ValueError, "module functions cannot set" " METH_CLASS or METH_STATIC"); Py_DECREF(n); Py_DECREF(m); return NULL; } v = PyCFunction_NewEx(ml, (PyObject*)m, n); if (v == NULL) { Py_DECREF(n); Py_DECREF(m); return NULL; } if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { Py_DECREF(v); Py_DECREF(n); Py_DECREF(m); return NULL; } Py_DECREF(v); } Py_DECREF(n); } if (module->m_doc != NULL) { v = PyUnicode_FromString(module->m_doc); if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { Py_XDECREF(v); Py_DECREF(m); return NULL; } Py_DECREF(v); } m->md_def = module; return (PyObject*)m; }
void * PyMem_Malloc(size_t nbytes) { return PyMem_MALLOC(nbytes); }
/* Would be nice if python had this built in */ void PyC_RunQuicky(const char *filepath, int n, ...) { FILE *fp= fopen(filepath, "r"); if(fp) { PyGILState_STATE gilstate= PyGILState_Ensure(); va_list vargs; int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2)); int i; PyObject *py_dict = PyC_DefaultNameSpace(filepath); PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */ PyObject *py_result, *ret; PyObject *struct_mod= PyImport_ImportModule("struct"); PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */ PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */ PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */ Py_DECREF(struct_mod); va_start(vargs, n); for (i=0; i * 2<n; i++) { char *format = va_arg(vargs, char *); void *ptr = va_arg(vargs, void *); ret= PyObject_CallFunction(calcsize, (char *)"s", format); if(ret) { sizes[i]= PyLong_AsSsize_t(ret); Py_DECREF(ret); ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]); } if(ret == NULL) { printf("PyC_InlineRun error, line:%d\n", __LINE__); PyErr_Print(); PyErr_Clear(); PyList_SET_ITEM(values, i, Py_None); /* hold user */ Py_INCREF(Py_None); sizes[i]= 0; } else { if(PyTuple_GET_SIZE(ret) == 1) { /* convenience, convert single tuples into single values */ PyObject *tmp= PyTuple_GET_ITEM(ret, 0); Py_INCREF(tmp); Py_DECREF(ret); ret = tmp; } PyList_SET_ITEM(values, i, ret); /* hold user */ } } va_end(vargs); /* set the value so we can access it */ PyDict_SetItemString(py_dict, "values", values); py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict); fclose(fp); if(py_result) { /* we could skip this but then only slice assignment would work * better not be so strict */ values= PyDict_GetItemString(py_dict, "values"); if(values && PyList_Check(values)) { /* dont use the result */ Py_DECREF(py_result); py_result= NULL; /* now get the values back */ va_start(vargs, n); for (i=0; i*2 <n; i++) { char *format = va_arg(vargs, char *); void *ptr = va_arg(vargs, void *); PyObject *item; PyObject *item_new; /* prepend the string formatting and remake the tuple */ item= PyList_GET_ITEM(values, i); if(PyTuple_CheckExact(item)) { int ofs= PyTuple_GET_SIZE(item); item_new= PyTuple_New(ofs + 1); while(ofs--) { PyObject *member= PyTuple_GET_ITEM(item, ofs); PyTuple_SET_ITEM(item_new, ofs + 1, member); Py_INCREF(member); } PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format)); } else { item_new= Py_BuildValue("sO", format, item); } ret = PyObject_Call(pack, item_new, NULL); if(ret) { /* copy the bytes back into memory */ memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]); Py_DECREF(ret); } else { printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__); PyC_ObSpit("failed converting:", item_new); PyErr_Print(); PyErr_Clear(); } Py_DECREF(item_new); } va_end(vargs); } else { printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__); } }
PyCodeObject * PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab) { PyCodeObject *co; unsigned char *cell2arg = NULL; Py_ssize_t i, n_cellvars; // We originally had a Py_GUARD here, and all was well. It was never hit // by normal parallel contexts. Then, after misusing datrie, it was // suddenly being hit -- turns out Cython calls PyCode_New() when an // exception occurs in order to do stuff. I've since perused the body and // nothing immediately stands out as being unsafe for calling in a // parallel context (i.e. no random mallocs or static storage), so, let's // remove the guard and see what happens. //Py_GUARD(); /* Check argument types */ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || code == NULL || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || freevars == NULL || !PyTuple_Check(freevars) || cellvars == NULL || !PyTuple_Check(cellvars) || name == NULL || !PyUnicode_Check(name) || filename == NULL || !PyUnicode_Check(filename) || lnotab == NULL || !PyBytes_Check(lnotab) || !PyObject_CheckReadBuffer(code)) { PyErr_BadInternalCall(); return NULL; } /* Ensure that the filename is a ready Unicode string */ if (PyUnicode_READY(filename) < 0) return NULL; n_cellvars = PyTuple_GET_SIZE(cellvars); intern_strings(names); intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); /* Intern selected string constants */ for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { PyObject *v = PyTuple_GetItem(consts, i); if (!all_name_chars(v)) continue; PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); } /* Create mapping between cells and arguments if needed. */ if (n_cellvars) { Py_ssize_t total_args = argcount + kwonlyargcount + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars; int used_cell2arg = 0; cell2arg = PyMem_MALLOC(alloc_size); if (cell2arg == NULL) return NULL; memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size); /* Find cells which are also arguments. */ for (i = 0; i < n_cellvars; i++) { Py_ssize_t j; PyObject *cell = PyTuple_GET_ITEM(cellvars, i); for (j = 0; j < total_args; j++) { PyObject *arg = PyTuple_GET_ITEM(varnames, j); if (!PyUnicode_Compare(cell, arg)) { cell2arg[i] = j; used_cell2arg = 1; break; } } } if (!used_cell2arg) { PyMem_FREE(cell2arg); cell2arg = NULL; } } co = PyObject_NEW(PyCodeObject, &PyCode_Type); if (co == NULL) { if (cell2arg) PyMem_FREE(cell2arg); return NULL; } co->co_argcount = argcount; co->co_kwonlyargcount = kwonlyargcount; co->co_nlocals = nlocals; co->co_stacksize = stacksize; co->co_flags = flags; Py_INCREF(code); co->co_code = code; Py_INCREF(consts); co->co_consts = consts; Py_INCREF(names); co->co_names = names; Py_INCREF(varnames); co->co_varnames = varnames; Py_INCREF(freevars); co->co_freevars = freevars; Py_INCREF(cellvars); co->co_cellvars = cellvars; co->co_cell2arg = cell2arg; Py_INCREF(filename); co->co_filename = filename; Py_INCREF(name); co->co_name = name; co->co_firstlineno = firstlineno; Py_INCREF(lnotab); co->co_lnotab = lnotab; co->co_zombieframe = NULL; co->co_weakreflist = NULL; return co; }
/* 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. */ static char * mymemreplace(const char *str, Py_ssize_t len, /* input string */ const char *pat, Py_ssize_t pat_len, /* pattern string to find */ const char *sub, Py_ssize_t sub_len, /* substitution string */ Py_ssize_t count, /* number of replacements */ Py_ssize_t *out_len) { char *out_s; char *new_s; Py_ssize_t nfound, offset, new_len; if (len == 0 || pat_len > len) goto return_same; /* find length of output string */ nfound = mymemcnt(str, len, pat, pat_len); if (count < 0) count = PY_SSIZE_T_MAX; else if (nfound > count) nfound = count; if (nfound == 0) goto return_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) return NULL; out_s[0] = '\0'; } else { assert(new_len > 0); new_s = (char *)PyMem_MALLOC(new_len); if (new_s == NULL) return NULL; 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; return out_s; return_same: *out_len = -1; return (char *)str; /* cast away const */ }
int PyModule_ExecDef(PyObject *module, PyModuleDef *def) { PyModuleDef_Slot *cur_slot; const char *name; int ret; name = PyModule_GetName(module); if (name == NULL) { return -1; } if (def->m_size >= 0) { PyModuleObject *md = (PyModuleObject*)module; if (md->md_state == NULL) { /* Always set a state pointer; this serves as a marker to skip * multiple initialization (importlib.reload() is no-op) */ md->md_state = PyMem_MALLOC(def->m_size); if (!md->md_state) { PyErr_NoMemory(); return -1; } memset(md->md_state, 0, def->m_size); } } if (def->m_slots == NULL) { return 0; } for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { switch (cur_slot->slot) { case Py_mod_create: /* handled in PyModule_FromDefAndSpec2 */ break; case Py_mod_exec: ret = ((int (*)(PyObject *))cur_slot->value)(module); if (ret != 0) { if (!PyErr_Occurred()) { PyErr_Format( PyExc_SystemError, "execution of module %s failed without setting an exception", name); } return -1; } if (PyErr_Occurred()) { PyErr_Format( PyExc_SystemError, "execution of module %s raised unreported exception", name); return -1; } break; default: PyErr_Format( PyExc_SystemError, "module %s initialized with unknown slot %i", name, cur_slot->slot); return -1; } } return 0; }
PyObject * PyModule_Create2(struct PyModuleDef* module, int module_api_version) { const char* name; PyModuleObject *m; PyInterpreterState *interp = PyThreadState_Get()->interp; if (interp->modules == NULL) Py_FatalError("Python import machinery not initialized"); if (!PyModuleDef_Init(module)) return NULL; name = module->m_name; if (!check_api_version(name, module_api_version)) { return NULL; } if (module->m_slots) { PyErr_Format( PyExc_SystemError, "module %s: PyModule_Create is incompatible with m_slots", name); return NULL; } /* Make sure name is fully qualified. This is a bit of a hack: when the shared library is loaded, the module name is "package.module", but the module calls PyModule_Create*() with just "module" for the name. The shared library loader squirrels away the true name of the module in _Py_PackageContext, and PyModule_Create*() will substitute this (if the name actually matches). */ if (_Py_PackageContext != NULL) { const char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(module->m_name, p+1) == 0) { name = _Py_PackageContext; _Py_PackageContext = NULL; } } if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; if (module->m_size > 0) { m->md_state = PyMem_MALLOC(module->m_size); if (!m->md_state) { PyErr_NoMemory(); Py_DECREF(m); return NULL; } memset(m->md_state, 0, module->m_size); } if (module->m_methods != NULL) { if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) { Py_DECREF(m); return NULL; } } if (module->m_doc != NULL) { if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) { Py_DECREF(m); return NULL; } } m->md_def = module; return (PyObject*)m; }
/** * PyOS_ascii_strtod: * @nptr: the string to convert to a numeric value. * @endptr: if non-%NULL, it returns the character after * the last character used in the conversion. * * Converts a string to a #gdouble value. * This function behaves like the standard strtod() function * does in the C locale. It does this without actually * changing the current locale, since that would not be * thread-safe. * * This function is typically used when reading configuration * files or other non-user input that should be locale independent. * To handle input from the user you should normally use the * locale-sensitive system strtod() function. * * If the correct value would cause overflow, plus or minus %HUGE_VAL * is returned (according to the sign of the value), and %ERANGE is * stored in %errno. If the correct value would cause underflow, * zero is returned and %ERANGE is stored in %errno. * If memory allocation fails, %ENOMEM is stored in %errno. * * This function resets %errno before calling strtod() so that * you can reliably detect overflow and underflow. * * Return value: the #gdouble value. **/ double PyOS_ascii_strtod(const char *nptr, char **endptr) { char *fail_pos; double val = -1.0; #ifndef ANDROID struct lconv *locale_data; #endif const char *decimal_point; size_t decimal_point_len; const char *p, *decimal_point_pos; const char *end = NULL; /* Silence gcc */ const char *digits_pos = NULL; int negate = 0; assert(nptr != NULL); fail_pos = NULL; #ifdef ANDROID decimal_point = "."; #else locale_data = localeconv(); decimal_point = locale_data->decimal_point; #endif decimal_point_len = strlen(decimal_point); assert(decimal_point_len != 0); decimal_point_pos = NULL; /* We process any leading whitespace and the optional sign manually, then pass the remainder to the system strtod. This ensures that the result of an underflow has the correct sign. (bug #1725) */ p = nptr; /* Skip leading space */ while (ISSPACE(*p)) p++; /* Process leading sign, if present */ if (*p == '-') { negate = 1; p++; } else if (*p == '+') { p++; } /* What's left should begin with a digit, a decimal point, or one of the letters i, I, n, N. It should not begin with 0x or 0X */ if ((!ISDIGIT(*p) && *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N') || (*p == '0' && (p[1] == 'x' || p[1] == 'X'))) { if (endptr) *endptr = (char*)nptr; errno = EINVAL; return val; } digits_pos = p; if (decimal_point[0] != '.' || decimal_point[1] != 0) { while (ISDIGIT(*p)) p++; if (*p == '.') { decimal_point_pos = p++; while (ISDIGIT(*p)) p++; if (*p == 'e' || *p == 'E') p++; if (*p == '+' || *p == '-') p++; while (ISDIGIT(*p)) p++; end = p; } else if (strncmp(p, decimal_point, decimal_point_len) == 0) { /* Python bug #1417699 */ if (endptr) *endptr = (char*)nptr; errno = EINVAL; return val; } /* For the other cases, we need not convert the decimal point */ } /* Set errno to zero, so that we can distinguish zero results and underflows */ errno = 0; if (decimal_point_pos) { char *copy, *c; /* We need to convert the '.' to the locale specific decimal point */ copy = (char *)PyMem_MALLOC(end - digits_pos + 1 + decimal_point_len); if (copy == NULL) { if (endptr) *endptr = (char *)nptr; errno = ENOMEM; return val; } c = copy; memcpy(c, digits_pos, decimal_point_pos - digits_pos); c += decimal_point_pos - digits_pos; memcpy(c, decimal_point, decimal_point_len); c += decimal_point_len; memcpy(c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); c += end - (decimal_point_pos + 1); *c = 0; val = strtod(copy, &fail_pos); if (fail_pos) { if (fail_pos > decimal_point_pos) fail_pos = (char *)digits_pos + (fail_pos - copy) - (decimal_point_len - 1); else fail_pos = (char *)digits_pos + (fail_pos - copy); } PyMem_FREE(copy); } else { val = strtod(digits_pos, &fail_pos); } if (fail_pos == digits_pos) fail_pos = (char *)nptr; if (negate && fail_pos != nptr) val = -val; if (endptr) *endptr = fail_pos; return val; }