Changeset 388 for python/vendor/current/Python/structmember.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Python/structmember.c
r2 r388 9 9 listmembers(struct memberlist *mlist) 10 10 { 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 11 int i, n; 12 PyObject *v; 13 for (n = 0; mlist[n].name != NULL; n++) 14 ; 15 v = PyList_New(n); 16 if (v != NULL) { 17 for (i = 0; i < n; i++) 18 PyList_SetItem(v, i, 19 PyString_FromString(mlist[i].name)); 20 if (PyErr_Occurred()) { 21 Py_DECREF(v); 22 v = NULL; 23 } 24 else { 25 PyList_Sort(v); 26 } 27 } 28 return v; 29 29 } 30 30 … … 32 32 PyMember_Get(const char *addr, struct memberlist *mlist, const char *name) 33 33 { 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 34 struct memberlist *l; 35 36 if (strcmp(name, "__members__") == 0) 37 return listmembers(mlist); 38 for (l = mlist; l->name != NULL; l++) { 39 if (strcmp(l->name, name) == 0) { 40 PyMemberDef copy; 41 copy.name = l->name; 42 copy.type = l->type; 43 copy.offset = l->offset; 44 copy.flags = l->flags; 45 copy.doc = NULL; 46 return PyMember_GetOne(addr, ©); 47 } 48 } 49 PyErr_SetString(PyExc_AttributeError, name); 50 return NULL; 51 51 } 52 52 … … 54 54 PyMember_GetOne(const char *addr, PyMemberDef *l) 55 55 { 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 56 PyObject *v; 57 if ((l->flags & READ_RESTRICTED) && 58 PyEval_GetRestricted()) { 59 PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); 60 return NULL; 61 } 62 addr += l->offset; 63 switch (l->type) { 64 case T_BOOL: 65 v = PyBool_FromLong(*(char*)addr); 66 break; 67 case T_BYTE: 68 v = PyInt_FromLong(*(char*)addr); 69 break; 70 case T_UBYTE: 71 v = PyLong_FromUnsignedLong(*(unsigned char*)addr); 72 break; 73 case T_SHORT: 74 v = PyInt_FromLong(*(short*)addr); 75 break; 76 case T_USHORT: 77 v = PyLong_FromUnsignedLong(*(unsigned short*)addr); 78 break; 79 case T_INT: 80 v = PyInt_FromLong(*(int*)addr); 81 break; 82 case T_UINT: 83 v = PyLong_FromUnsignedLong(*(unsigned int*)addr); 84 break; 85 case T_LONG: 86 v = PyInt_FromLong(*(long*)addr); 87 break; 88 case T_ULONG: 89 v = PyLong_FromUnsignedLong(*(unsigned long*)addr); 90 break; 91 case T_PYSSIZET: 92 v = PyInt_FromSsize_t(*(Py_ssize_t*)addr); 93 break; 94 case T_FLOAT: 95 v = PyFloat_FromDouble((double)*(float*)addr); 96 break; 97 case T_DOUBLE: 98 v = PyFloat_FromDouble(*(double*)addr); 99 break; 100 case T_STRING: 101 if (*(char**)addr == NULL) { 102 Py_INCREF(Py_None); 103 v = Py_None; 104 } 105 else 106 v = PyString_FromString(*(char**)addr); 107 break; 108 case T_STRING_INPLACE: 109 v = PyString_FromString((char*)addr); 110 break; 111 case T_CHAR: 112 v = PyString_FromStringAndSize((char*)addr, 1); 113 break; 114 case T_OBJECT: 115 v = *(PyObject **)addr; 116 if (v == NULL) 117 v = Py_None; 118 Py_INCREF(v); 119 break; 120 case T_OBJECT_EX: 121 v = *(PyObject **)addr; 122 if (v == NULL) 123 PyErr_SetString(PyExc_AttributeError, l->name); 124 Py_XINCREF(v); 125 break; 126 126 #ifdef HAVE_LONG_LONG 127 128 129 130 131 132 127 case T_LONGLONG: 128 v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr); 129 break; 130 case T_ULONGLONG: 131 v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr); 132 break; 133 133 #endif /* HAVE_LONG_LONG */ 134 135 136 137 138 134 default: 135 PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); 136 v = NULL; 137 } 138 return v; 139 139 } 140 140 … … 142 142 PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v) 143 143 { 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 } 161 162 #define WARN(msg) 163 do { 164 if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0)\165 return -1;\144 struct memberlist *l; 145 146 for (l = mlist; l->name != NULL; l++) { 147 if (strcmp(l->name, name) == 0) { 148 PyMemberDef copy; 149 copy.name = l->name; 150 copy.type = l->type; 151 copy.offset = l->offset; 152 copy.flags = l->flags; 153 copy.doc = NULL; 154 return PyMember_SetOne(addr, ©, v); 155 } 156 } 157 158 PyErr_SetString(PyExc_AttributeError, name); 159 return -1; 160 } 161 162 #define WARN(msg) \ 163 do { \ 164 if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0) \ 165 return -1; \ 166 166 } while (0) 167 167 … … 169 169 PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) 170 170 { 171 PyObject *oldv; 172 173 addr += l->offset; 174 175 if ((l->flags & READONLY) || l->type == T_STRING) 176 { 177 PyErr_SetString(PyExc_TypeError, "readonly attribute"); 178 return -1; 179 } 180 if ((l->flags & PY_WRITE_RESTRICTED) && PyEval_GetRestricted()) { 181 PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); 182 return -1; 183 } 184 if (v == NULL) { 185 if (l->type == T_OBJECT_EX) { 186 /* Check if the attribute is set. */ 187 if (*(PyObject **)addr == NULL) { 188 PyErr_SetString(PyExc_AttributeError, l->name); 189 return -1; 190 } 191 } 192 else if (l->type != T_OBJECT) { 193 PyErr_SetString(PyExc_TypeError, 194 "can't delete numeric/char attribute"); 195 return -1; 196 } 197 } 198 switch (l->type) { 199 case T_BOOL:{ 200 if (!PyBool_Check(v)) { 201 PyErr_SetString(PyExc_TypeError, 202 "attribute value type must be bool"); 203 return -1; 204 } 205 if (v == Py_True) 206 *(char*)addr = (char) 1; 207 else 208 *(char*)addr = (char) 0; 209 break; 210 } 211 case T_BYTE:{ 212 long long_val = PyInt_AsLong(v); 213 if ((long_val == -1) && PyErr_Occurred()) 214 return -1; 215 *(char*)addr = (char)long_val; 216 /* XXX: For compatibility, only warn about truncations 217 for now. */ 218 if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) 219 WARN("Truncation of value to char"); 220 break; 221 } 222 case T_UBYTE:{ 223 long long_val = PyInt_AsLong(v); 224 if ((long_val == -1) && PyErr_Occurred()) 225 return -1; 226 *(unsigned char*)addr = (unsigned char)long_val; 227 if ((long_val > UCHAR_MAX) || (long_val < 0)) 228 WARN("Truncation of value to unsigned char"); 229 break; 230 } 231 case T_SHORT:{ 232 long long_val = PyInt_AsLong(v); 233 if ((long_val == -1) && PyErr_Occurred()) 234 return -1; 235 *(short*)addr = (short)long_val; 236 if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) 237 WARN("Truncation of value to short"); 238 break; 239 } 240 case T_USHORT:{ 241 long long_val = PyInt_AsLong(v); 242 if ((long_val == -1) && PyErr_Occurred()) 243 return -1; 244 *(unsigned short*)addr = (unsigned short)long_val; 245 if ((long_val > USHRT_MAX) || (long_val < 0)) 246 WARN("Truncation of value to unsigned short"); 247 break; 248 } 249 case T_INT:{ 250 long long_val = PyInt_AsLong(v); 251 if ((long_val == -1) && PyErr_Occurred()) 252 return -1; 253 *(int *)addr = (int)long_val; 254 if ((long_val > INT_MAX) || (long_val < INT_MIN)) 255 WARN("Truncation of value to int"); 256 break; 257 } 258 case T_UINT:{ 259 unsigned long ulong_val = PyLong_AsUnsignedLong(v); 260 if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) { 261 /* XXX: For compatibility, accept negative int values 262 as well. */ 263 PyErr_Clear(); 264 ulong_val = PyLong_AsLong(v); 265 if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) 266 return -1; 267 *(unsigned int *)addr = (unsigned int)ulong_val; 268 WARN("Writing negative value into unsigned field"); 269 } else 270 *(unsigned int *)addr = (unsigned int)ulong_val; 271 if (ulong_val > UINT_MAX) 272 WARN("Truncation of value to unsigned int"); 273 break; 274 } 275 case T_LONG:{ 276 *(long*)addr = PyLong_AsLong(v); 277 if ((*(long*)addr == -1) && PyErr_Occurred()) 278 return -1; 279 break; 280 } 281 case T_ULONG:{ 282 *(unsigned long*)addr = PyLong_AsUnsignedLong(v); 283 if ((*(unsigned long*)addr == (unsigned long)-1) 284 && PyErr_Occurred()) { 285 /* XXX: For compatibility, accept negative int values 286 as well. */ 287 PyErr_Clear(); 288 *(unsigned long*)addr = PyLong_AsLong(v); 289 if ((*(unsigned long*)addr == (unsigned int)-1) 290 && PyErr_Occurred()) 291 return -1; 292 WARN("Writing negative value into unsigned field"); 293 } 294 break; 295 } 296 case T_PYSSIZET:{ 297 *(Py_ssize_t*)addr = PyInt_AsSsize_t(v); 298 if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) 299 && PyErr_Occurred()) 300 return -1; 301 break; 302 } 303 case T_FLOAT:{ 304 double double_val = PyFloat_AsDouble(v); 305 if ((double_val == -1) && PyErr_Occurred()) 306 return -1; 307 *(float*)addr = (float)double_val; 308 break; 309 } 310 case T_DOUBLE: 311 *(double*)addr = PyFloat_AsDouble(v); 312 if ((*(double*)addr == -1) && PyErr_Occurred()) 313 return -1; 314 break; 315 case T_OBJECT: 316 case T_OBJECT_EX: 317 Py_XINCREF(v); 318 oldv = *(PyObject **)addr; 319 *(PyObject **)addr = v; 320 Py_XDECREF(oldv); 321 break; 322 case T_CHAR: 323 if (PyString_Check(v) && PyString_Size(v) == 1) { 324 *(char*)addr = PyString_AsString(v)[0]; 325 } 326 else { 327 PyErr_BadArgument(); 328 return -1; 329 } 330 break; 171 PyObject *oldv; 172 173 addr += l->offset; 174 175 if ((l->flags & READONLY)) 176 { 177 PyErr_SetString(PyExc_TypeError, "readonly attribute"); 178 return -1; 179 } 180 if ((l->flags & PY_WRITE_RESTRICTED) && PyEval_GetRestricted()) { 181 PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); 182 return -1; 183 } 184 if (v == NULL) { 185 if (l->type == T_OBJECT_EX) { 186 /* Check if the attribute is set. */ 187 if (*(PyObject **)addr == NULL) { 188 PyErr_SetString(PyExc_AttributeError, l->name); 189 return -1; 190 } 191 } 192 else if (l->type != T_OBJECT) { 193 PyErr_SetString(PyExc_TypeError, 194 "can't delete numeric/char attribute"); 195 return -1; 196 } 197 } 198 switch (l->type) { 199 case T_BOOL:{ 200 if (!PyBool_Check(v)) { 201 PyErr_SetString(PyExc_TypeError, 202 "attribute value type must be bool"); 203 return -1; 204 } 205 if (v == Py_True) 206 *(char*)addr = (char) 1; 207 else 208 *(char*)addr = (char) 0; 209 break; 210 } 211 case T_BYTE:{ 212 long long_val = PyInt_AsLong(v); 213 if ((long_val == -1) && PyErr_Occurred()) 214 return -1; 215 *(char*)addr = (char)long_val; 216 /* XXX: For compatibility, only warn about truncations 217 for now. */ 218 if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) 219 WARN("Truncation of value to char"); 220 break; 221 } 222 case T_UBYTE:{ 223 long long_val = PyInt_AsLong(v); 224 if ((long_val == -1) && PyErr_Occurred()) 225 return -1; 226 *(unsigned char*)addr = (unsigned char)long_val; 227 if ((long_val > UCHAR_MAX) || (long_val < 0)) 228 WARN("Truncation of value to unsigned char"); 229 break; 230 } 231 case T_SHORT:{ 232 long long_val = PyInt_AsLong(v); 233 if ((long_val == -1) && PyErr_Occurred()) 234 return -1; 235 *(short*)addr = (short)long_val; 236 if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) 237 WARN("Truncation of value to short"); 238 break; 239 } 240 case T_USHORT:{ 241 long long_val = PyInt_AsLong(v); 242 if ((long_val == -1) && PyErr_Occurred()) 243 return -1; 244 *(unsigned short*)addr = (unsigned short)long_val; 245 if ((long_val > USHRT_MAX) || (long_val < 0)) 246 WARN("Truncation of value to unsigned short"); 247 break; 248 } 249 case T_INT:{ 250 long long_val = PyInt_AsLong(v); 251 if ((long_val == -1) && PyErr_Occurred()) 252 return -1; 253 *(int *)addr = (int)long_val; 254 if ((long_val > INT_MAX) || (long_val < INT_MIN)) 255 WARN("Truncation of value to int"); 256 break; 257 } 258 case T_UINT:{ 259 unsigned long ulong_val = PyLong_AsUnsignedLong(v); 260 if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { 261 /* XXX: For compatibility, accept negative int values 262 as well. */ 263 PyErr_Clear(); 264 ulong_val = PyLong_AsLong(v); 265 if ((ulong_val == (unsigned long)-1) && 266 PyErr_Occurred()) 267 return -1; 268 *(unsigned int *)addr = (unsigned int)ulong_val; 269 WARN("Writing negative value into unsigned field"); 270 } else 271 *(unsigned int *)addr = (unsigned int)ulong_val; 272 if (ulong_val > UINT_MAX) 273 WARN("Truncation of value to unsigned int"); 274 break; 275 } 276 case T_LONG:{ 277 *(long*)addr = PyLong_AsLong(v); 278 if ((*(long*)addr == -1) && PyErr_Occurred()) 279 return -1; 280 break; 281 } 282 case T_ULONG:{ 283 *(unsigned long*)addr = PyLong_AsUnsignedLong(v); 284 if ((*(unsigned long*)addr == (unsigned long)-1) 285 && PyErr_Occurred()) { 286 /* XXX: For compatibility, accept negative int values 287 as well. */ 288 PyErr_Clear(); 289 *(unsigned long*)addr = PyLong_AsLong(v); 290 if ((*(unsigned long*)addr == (unsigned long)-1) 291 && PyErr_Occurred()) 292 return -1; 293 WARN("Writing negative value into unsigned field"); 294 } 295 break; 296 } 297 case T_PYSSIZET:{ 298 *(Py_ssize_t*)addr = PyInt_AsSsize_t(v); 299 if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) 300 && PyErr_Occurred()) 301 return -1; 302 break; 303 } 304 case T_FLOAT:{ 305 double double_val = PyFloat_AsDouble(v); 306 if ((double_val == -1) && PyErr_Occurred()) 307 return -1; 308 *(float*)addr = (float)double_val; 309 break; 310 } 311 case T_DOUBLE: 312 *(double*)addr = PyFloat_AsDouble(v); 313 if ((*(double*)addr == -1) && PyErr_Occurred()) 314 return -1; 315 break; 316 case T_OBJECT: 317 case T_OBJECT_EX: 318 Py_XINCREF(v); 319 oldv = *(PyObject **)addr; 320 *(PyObject **)addr = v; 321 Py_XDECREF(oldv); 322 break; 323 case T_CHAR: 324 if (PyString_Check(v) && PyString_Size(v) == 1) { 325 *(char*)addr = PyString_AsString(v)[0]; 326 } 327 else { 328 PyErr_BadArgument(); 329 return -1; 330 } 331 break; 332 case T_STRING: 333 case T_STRING_INPLACE: 334 PyErr_SetString(PyExc_TypeError, "readonly attribute"); 335 return -1; 331 336 #ifdef HAVE_LONG_LONG 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 337 case T_LONGLONG:{ 338 PY_LONG_LONG value; 339 *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v); 340 if ((value == -1) && PyErr_Occurred()) 341 return -1; 342 break; 343 } 344 case T_ULONGLONG:{ 345 unsigned PY_LONG_LONG value; 346 /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong 347 doesn't ??? */ 348 if (PyLong_Check(v)) 349 *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v); 350 else 351 *(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v); 352 if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred()) 353 return -1; 354 break; 355 } 351 356 #endif /* HAVE_LONG_LONG */ 352 353 354 355 356 357 358 } 357 default: 358 PyErr_Format(PyExc_SystemError, 359 "bad memberdescr type for %s", l->name); 360 return -1; 361 } 362 return 0; 363 }
Note:
See TracChangeset
for help on using the changeset viewer.