LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Python - structmember.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 23 177 13.0 %
Date: 2012-12-17 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /* Map C struct members to Python object attributes */
       3             : 
       4             : #include "Python.h"
       5             : 
       6             : #include "structmember.h"
       7             : 
       8             : PyObject *
       9        1197 : PyMember_GetOne(const char *addr, PyMemberDef *l)
      10             : {
      11             :     PyObject *v;
      12             : 
      13        1197 :     addr += l->offset;
      14        1197 :     switch (l->type) {
      15             :     case T_BOOL:
      16           0 :         v = PyBool_FromLong(*(char*)addr);
      17           0 :         break;
      18             :     case T_BYTE:
      19           0 :         v = PyLong_FromLong(*(char*)addr);
      20           0 :         break;
      21             :     case T_UBYTE:
      22           0 :         v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
      23           0 :         break;
      24             :     case T_SHORT:
      25           0 :         v = PyLong_FromLong(*(short*)addr);
      26           0 :         break;
      27             :     case T_USHORT:
      28           0 :         v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
      29           0 :         break;
      30             :     case T_INT:
      31           0 :         v = PyLong_FromLong(*(int*)addr);
      32           0 :         break;
      33             :     case T_UINT:
      34           0 :         v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
      35           0 :         break;
      36             :     case T_LONG:
      37           0 :         v = PyLong_FromLong(*(long*)addr);
      38           0 :         break;
      39             :     case T_ULONG:
      40           0 :         v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
      41           0 :         break;
      42             :     case T_PYSSIZET:
      43           0 :         v = PyLong_FromSsize_t(*(Py_ssize_t*)addr);
      44           0 :         break;
      45             :     case T_FLOAT:
      46           0 :         v = PyFloat_FromDouble((double)*(float*)addr);
      47           0 :         break;
      48             :     case T_DOUBLE:
      49           0 :         v = PyFloat_FromDouble(*(double*)addr);
      50           0 :         break;
      51             :     case T_STRING:
      52           0 :         if (*(char**)addr == NULL) {
      53           0 :             Py_INCREF(Py_None);
      54           0 :             v = Py_None;
      55             :         }
      56             :         else
      57           0 :             v = PyUnicode_FromString(*(char**)addr);
      58           0 :         break;
      59             :     case T_STRING_INPLACE:
      60           0 :         v = PyUnicode_FromString((char*)addr);
      61           0 :         break;
      62             :     case T_CHAR:
      63           0 :         v = PyUnicode_FromStringAndSize((char*)addr, 1);
      64           0 :         break;
      65             :     case T_OBJECT:
      66         895 :         v = *(PyObject **)addr;
      67         895 :         if (v == NULL)
      68           0 :             v = Py_None;
      69         895 :         Py_INCREF(v);
      70         895 :         break;
      71             :     case T_OBJECT_EX:
      72         302 :         v = *(PyObject **)addr;
      73         302 :         if (v == NULL)
      74           0 :             PyErr_SetString(PyExc_AttributeError, l->name);
      75         302 :         Py_XINCREF(v);
      76         302 :         break;
      77             : #ifdef HAVE_LONG_LONG
      78             :     case T_LONGLONG:
      79           0 :         v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
      80           0 :         break;
      81             :     case T_ULONGLONG:
      82           0 :         v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
      83           0 :         break;
      84             : #endif /* HAVE_LONG_LONG */
      85             :     case T_NONE:
      86           0 :         v = Py_None;
      87           0 :         Py_INCREF(v);
      88           0 :         break;
      89             :     default:
      90           0 :         PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
      91           0 :         v = NULL;
      92             :     }
      93        1197 :     return v;
      94             : }
      95             : 
      96             : #define WARN(msg)                                               \
      97             :     do {                                                        \
      98             :     if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0)         \
      99             :         return -1;                                              \
     100             :     } while (0)
     101             : 
     102             : int
     103         203 : PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
     104             : {
     105             :     PyObject *oldv;
     106             : 
     107         203 :     addr += l->offset;
     108             : 
     109         203 :     if ((l->flags & READONLY))
     110             :     {
     111           0 :         PyErr_SetString(PyExc_AttributeError, "readonly attribute");
     112           0 :         return -1;
     113             :     }
     114         203 :     if (v == NULL) {
     115           0 :         if (l->type == T_OBJECT_EX) {
     116             :             /* Check if the attribute is set. */
     117           0 :             if (*(PyObject **)addr == NULL) {
     118           0 :                 PyErr_SetString(PyExc_AttributeError, l->name);
     119           0 :                 return -1;
     120             :             }
     121             :         }
     122           0 :         else if (l->type != T_OBJECT) {
     123           0 :             PyErr_SetString(PyExc_TypeError,
     124             :                             "can't delete numeric/char attribute");
     125           0 :             return -1;
     126             :         }
     127             :     }
     128         203 :     switch (l->type) {
     129             :     case T_BOOL:{
     130           0 :         if (!PyBool_Check(v)) {
     131           0 :             PyErr_SetString(PyExc_TypeError,
     132             :                             "attribute value type must be bool");
     133           0 :             return -1;
     134             :         }
     135           0 :         if (v == Py_True)
     136           0 :             *(char*)addr = (char) 1;
     137             :         else
     138           0 :             *(char*)addr = (char) 0;
     139           0 :         break;
     140             :         }
     141             :     case T_BYTE:{
     142           0 :         long long_val = PyLong_AsLong(v);
     143           0 :         if ((long_val == -1) && PyErr_Occurred())
     144           0 :             return -1;
     145           0 :         *(char*)addr = (char)long_val;
     146             :         /* XXX: For compatibility, only warn about truncations
     147             :            for now. */
     148           0 :         if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
     149           0 :             WARN("Truncation of value to char");
     150           0 :         break;
     151             :         }
     152             :     case T_UBYTE:{
     153           0 :         long long_val = PyLong_AsLong(v);
     154           0 :         if ((long_val == -1) && PyErr_Occurred())
     155           0 :             return -1;
     156           0 :         *(unsigned char*)addr = (unsigned char)long_val;
     157           0 :         if ((long_val > UCHAR_MAX) || (long_val < 0))
     158           0 :             WARN("Truncation of value to unsigned char");
     159           0 :         break;
     160             :         }
     161             :     case T_SHORT:{
     162           0 :         long long_val = PyLong_AsLong(v);
     163           0 :         if ((long_val == -1) && PyErr_Occurred())
     164           0 :             return -1;
     165           0 :         *(short*)addr = (short)long_val;
     166           0 :         if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
     167           0 :             WARN("Truncation of value to short");
     168           0 :         break;
     169             :         }
     170             :     case T_USHORT:{
     171           0 :         long long_val = PyLong_AsLong(v);
     172           0 :         if ((long_val == -1) && PyErr_Occurred())
     173           0 :             return -1;
     174           0 :         *(unsigned short*)addr = (unsigned short)long_val;
     175           0 :         if ((long_val > USHRT_MAX) || (long_val < 0))
     176           0 :             WARN("Truncation of value to unsigned short");
     177           0 :         break;
     178             :         }
     179             :     case T_INT:{
     180           0 :         long long_val = PyLong_AsLong(v);
     181           0 :         if ((long_val == -1) && PyErr_Occurred())
     182           0 :             return -1;
     183           0 :         *(int *)addr = (int)long_val;
     184             :         if ((long_val > INT_MAX) || (long_val < INT_MIN))
     185             :             WARN("Truncation of value to int");
     186           0 :         break;
     187             :         }
     188             :     case T_UINT:{
     189           0 :         unsigned long ulong_val = PyLong_AsUnsignedLong(v);
     190           0 :         if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
     191             :             /* XXX: For compatibility, accept negative int values
     192             :                as well. */
     193           0 :             PyErr_Clear();
     194           0 :             ulong_val = PyLong_AsLong(v);
     195           0 :             if ((ulong_val == (unsigned long)-1) &&
     196           0 :                 PyErr_Occurred())
     197           0 :                 return -1;
     198           0 :             *(unsigned int *)addr = (unsigned int)ulong_val;
     199           0 :             WARN("Writing negative value into unsigned field");
     200             :         } else
     201           0 :             *(unsigned int *)addr = (unsigned int)ulong_val;
     202             :         if (ulong_val > UINT_MAX)
     203             :             WARN("Truncation of value to unsigned int");
     204           0 :         break;
     205             :         }
     206             :     case T_LONG:{
     207           0 :         *(long*)addr = PyLong_AsLong(v);
     208           0 :         if ((*(long*)addr == -1) && PyErr_Occurred())
     209           0 :             return -1;
     210           0 :         break;
     211             :         }
     212             :     case T_ULONG:{
     213           0 :         *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
     214           0 :         if ((*(unsigned long*)addr == (unsigned long)-1)
     215           0 :             && PyErr_Occurred()) {
     216             :             /* XXX: For compatibility, accept negative int values
     217             :                as well. */
     218           0 :             PyErr_Clear();
     219           0 :             *(unsigned long*)addr = PyLong_AsLong(v);
     220           0 :             if ((*(unsigned long*)addr == (unsigned long)-1)
     221           0 :                 && PyErr_Occurred())
     222           0 :                 return -1;
     223           0 :             WARN("Writing negative value into unsigned field");
     224             :         }
     225           0 :         break;
     226             :         }
     227             :     case T_PYSSIZET:{
     228           0 :         *(Py_ssize_t*)addr = PyLong_AsSsize_t(v);
     229           0 :         if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
     230           0 :             && PyErr_Occurred())
     231           0 :                         return -1;
     232           0 :         break;
     233             :         }
     234             :     case T_FLOAT:{
     235           0 :         double double_val = PyFloat_AsDouble(v);
     236           0 :         if ((double_val == -1) && PyErr_Occurred())
     237           0 :             return -1;
     238           0 :         *(float*)addr = (float)double_val;
     239           0 :         break;
     240             :         }
     241             :     case T_DOUBLE:
     242           0 :         *(double*)addr = PyFloat_AsDouble(v);
     243           0 :         if ((*(double*)addr == -1) && PyErr_Occurred())
     244           0 :             return -1;
     245           0 :         break;
     246             :     case T_OBJECT:
     247             :     case T_OBJECT_EX:
     248         203 :         Py_XINCREF(v);
     249         203 :         oldv = *(PyObject **)addr;
     250         203 :         *(PyObject **)addr = v;
     251         203 :         Py_XDECREF(oldv);
     252         203 :         break;
     253             :     case T_CHAR: {
     254             :         char *string;
     255             :         Py_ssize_t len;
     256             : 
     257           0 :         if (!PyUnicode_Check(v)) {
     258           0 :             PyErr_BadArgument();
     259           0 :             return -1;
     260             :         }
     261           0 :         string = _PyUnicode_AsStringAndSize(v, &len);
     262           0 :         if (len != 1) {
     263           0 :             PyErr_BadArgument();
     264           0 :             return -1;
     265             :         }
     266           0 :         *(char*)addr = string[0];
     267             :         break;
     268             :         }
     269             :     case T_STRING:
     270             :     case T_STRING_INPLACE:
     271           0 :         PyErr_SetString(PyExc_TypeError, "readonly attribute");
     272           0 :         return -1;
     273             : #ifdef HAVE_LONG_LONG
     274             :     case T_LONGLONG:{
     275             :         PY_LONG_LONG value;
     276           0 :         *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
     277           0 :         if ((value == -1) && PyErr_Occurred())
     278           0 :             return -1;
     279           0 :         break;
     280             :         }
     281             :     case T_ULONGLONG:{
     282             :         unsigned PY_LONG_LONG value;
     283             :         /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
     284             :             doesn't ??? */
     285           0 :         if (PyLong_Check(v))
     286           0 :             *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
     287             :         else
     288           0 :             *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsLong(v);
     289           0 :         if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
     290           0 :             return -1;
     291           0 :         break;
     292             :         }
     293             : #endif /* HAVE_LONG_LONG */
     294             :     default:
     295           0 :         PyErr_Format(PyExc_SystemError,
     296             :                      "bad memberdescr type for %s", l->name);
     297           0 :         return -1;
     298             :     }
     299         203 :     return 0;
     300             : }

Generated by: LCOV version 1.10