LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - fileobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 6 199 3.0 %
Date: 2012-12-17 Functions: 1 17 5.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* File object implementation (what's left of it -- see io.py) */
       2             : 
       3             : #define PY_SSIZE_T_CLEAN
       4             : #include "Python.h"
       5             : 
       6             : #ifdef HAVE_GETC_UNLOCKED
       7             : #define GETC(f) getc_unlocked(f)
       8             : #define FLOCKFILE(f) flockfile(f)
       9             : #define FUNLOCKFILE(f) funlockfile(f)
      10             : #else
      11             : #define GETC(f) getc(f)
      12             : #define FLOCKFILE(f)
      13             : #define FUNLOCKFILE(f)
      14             : #endif
      15             : 
      16             : /* Newline flags */
      17             : #define NEWLINE_UNKNOWN 0       /* No newline seen, yet */
      18             : #define NEWLINE_CR 1            /* \r newline seen */
      19             : #define NEWLINE_LF 2            /* \n newline seen */
      20             : #define NEWLINE_CRLF 4          /* \r\n newline seen */
      21             : 
      22             : #ifdef __cplusplus
      23             : extern "C" {
      24             : #endif
      25             : 
      26             : /* External C interface */
      27             : 
      28             : PyObject *
      29           0 : PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding,
      30             :               char *errors, char *newline, int closefd)
      31             : {
      32             :     PyObject *io, *stream;
      33             :     _Py_IDENTIFIER(open);
      34             : 
      35           0 :     io = PyImport_ImportModule("io");
      36           0 :     if (io == NULL)
      37           0 :         return NULL;
      38           0 :     stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
      39             :                                  buffering, encoding, errors,
      40             :                                  newline, closefd);
      41           0 :     Py_DECREF(io);
      42           0 :     if (stream == NULL)
      43           0 :         return NULL;
      44             :     /* ignore name attribute because the name attribute of _BufferedIOMixin
      45             :        and TextIOWrapper is read only */
      46           0 :     return stream;
      47             : }
      48             : 
      49             : PyObject *
      50           0 : PyFile_GetLine(PyObject *f, int n)
      51             : {
      52             :     PyObject *result;
      53             : 
      54           0 :     if (f == NULL) {
      55           0 :         PyErr_BadInternalCall();
      56           0 :         return NULL;
      57             :     }
      58             : 
      59             :     {
      60             :         PyObject *reader;
      61             :         PyObject *args;
      62             :         _Py_IDENTIFIER(readline);
      63             : 
      64           0 :         reader = _PyObject_GetAttrId(f, &PyId_readline);
      65           0 :         if (reader == NULL)
      66           0 :             return NULL;
      67           0 :         if (n <= 0)
      68           0 :             args = PyTuple_New(0);
      69             :         else
      70           0 :             args = Py_BuildValue("(i)", n);
      71           0 :         if (args == NULL) {
      72           0 :             Py_DECREF(reader);
      73           0 :             return NULL;
      74             :         }
      75           0 :         result = PyEval_CallObject(reader, args);
      76           0 :         Py_DECREF(reader);
      77           0 :         Py_DECREF(args);
      78           0 :         if (result != NULL && !PyBytes_Check(result) &&
      79           0 :             !PyUnicode_Check(result)) {
      80           0 :             Py_DECREF(result);
      81           0 :             result = NULL;
      82           0 :             PyErr_SetString(PyExc_TypeError,
      83             :                        "object.readline() returned non-string");
      84             :         }
      85             :     }
      86             : 
      87           0 :     if (n < 0 && result != NULL && PyBytes_Check(result)) {
      88           0 :         char *s = PyBytes_AS_STRING(result);
      89           0 :         Py_ssize_t len = PyBytes_GET_SIZE(result);
      90           0 :         if (len == 0) {
      91           0 :             Py_DECREF(result);
      92           0 :             result = NULL;
      93           0 :             PyErr_SetString(PyExc_EOFError,
      94             :                             "EOF when reading a line");
      95             :         }
      96           0 :         else if (s[len-1] == '\n') {
      97           0 :             if (result->ob_refcnt == 1)
      98           0 :                 _PyBytes_Resize(&result, len-1);
      99             :             else {
     100             :                 PyObject *v;
     101           0 :                 v = PyBytes_FromStringAndSize(s, len-1);
     102           0 :                 Py_DECREF(result);
     103           0 :                 result = v;
     104             :             }
     105             :         }
     106             :     }
     107           0 :     if (n < 0 && result != NULL && PyUnicode_Check(result)) {
     108           0 :         Py_ssize_t len = PyUnicode_GET_LENGTH(result);
     109           0 :         if (len == 0) {
     110           0 :             Py_DECREF(result);
     111           0 :             result = NULL;
     112           0 :             PyErr_SetString(PyExc_EOFError,
     113             :                             "EOF when reading a line");
     114             :         }
     115           0 :         else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
     116             :             PyObject *v;
     117           0 :             v = PyUnicode_Substring(result, 0, len-1);
     118           0 :             Py_DECREF(result);
     119           0 :             result = v;
     120             :         }
     121             :     }
     122           0 :     return result;
     123             : }
     124             : 
     125             : /* Interfaces to write objects/strings to file-like objects */
     126             : 
     127             : int
     128           0 : PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
     129             : {
     130             :     PyObject *writer, *value, *args, *result;
     131             :     _Py_IDENTIFIER(write);
     132             : 
     133           0 :     if (f == NULL) {
     134           0 :         PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
     135           0 :         return -1;
     136             :     }
     137           0 :     writer = _PyObject_GetAttrId(f, &PyId_write);
     138           0 :     if (writer == NULL)
     139           0 :         return -1;
     140           0 :     if (flags & Py_PRINT_RAW) {
     141           0 :         value = PyObject_Str(v);
     142             :     }
     143             :     else
     144           0 :         value = PyObject_Repr(v);
     145           0 :     if (value == NULL) {
     146           0 :         Py_DECREF(writer);
     147           0 :         return -1;
     148             :     }
     149           0 :     args = PyTuple_Pack(1, value);
     150           0 :     if (args == NULL) {
     151           0 :         Py_DECREF(value);
     152           0 :         Py_DECREF(writer);
     153           0 :         return -1;
     154             :     }
     155           0 :     result = PyEval_CallObject(writer, args);
     156           0 :     Py_DECREF(args);
     157           0 :     Py_DECREF(value);
     158           0 :     Py_DECREF(writer);
     159           0 :     if (result == NULL)
     160           0 :         return -1;
     161           0 :     Py_DECREF(result);
     162           0 :     return 0;
     163             : }
     164             : 
     165             : int
     166           0 : PyFile_WriteString(const char *s, PyObject *f)
     167             : {
     168           0 :     if (f == NULL) {
     169             :         /* Should be caused by a pre-existing error */
     170           0 :         if (!PyErr_Occurred())
     171           0 :             PyErr_SetString(PyExc_SystemError,
     172             :                             "null file for PyFile_WriteString");
     173           0 :         return -1;
     174             :     }
     175           0 :     else if (!PyErr_Occurred()) {
     176           0 :         PyObject *v = PyUnicode_FromString(s);
     177             :         int err;
     178           0 :         if (v == NULL)
     179           0 :             return -1;
     180           0 :         err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
     181           0 :         Py_DECREF(v);
     182           0 :         return err;
     183             :     }
     184             :     else
     185           0 :         return -1;
     186             : }
     187             : 
     188             : /* Try to get a file-descriptor from a Python object.  If the object
     189             :    is an integer or long integer, its value is returned.  If not, the
     190             :    object's fileno() method is called if it exists; the method must return
     191             :    an integer or long integer, which is returned as the file descriptor value.
     192             :    -1 is returned on failure.
     193             : */
     194             : 
     195             : int
     196           0 : PyObject_AsFileDescriptor(PyObject *o)
     197             : {
     198             :     int fd;
     199             :     PyObject *meth;
     200             :     _Py_IDENTIFIER(fileno);
     201             : 
     202           0 :     if (PyLong_Check(o)) {
     203           0 :         fd = PyLong_AsLong(o);
     204             :     }
     205           0 :     else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
     206             :     {
     207           0 :         PyObject *fno = PyEval_CallObject(meth, NULL);
     208           0 :         Py_DECREF(meth);
     209           0 :         if (fno == NULL)
     210           0 :             return -1;
     211             : 
     212           0 :         if (PyLong_Check(fno)) {
     213           0 :             fd = PyLong_AsLong(fno);
     214           0 :             Py_DECREF(fno);
     215             :         }
     216             :         else {
     217           0 :             PyErr_SetString(PyExc_TypeError,
     218             :                             "fileno() returned a non-integer");
     219           0 :             Py_DECREF(fno);
     220           0 :             return -1;
     221             :         }
     222             :     }
     223             :     else {
     224           0 :         PyErr_SetString(PyExc_TypeError,
     225             :                         "argument must be an int, or have a fileno() method.");
     226           0 :         return -1;
     227             :     }
     228             : 
     229           0 :     if (fd == -1 && PyErr_Occurred())
     230           0 :         return -1;
     231           0 :     if (fd < 0) {
     232           0 :         PyErr_Format(PyExc_ValueError,
     233             :                      "file descriptor cannot be a negative integer (%i)",
     234             :                      fd);
     235           0 :         return -1;
     236             :     }
     237           0 :     return fd;
     238             : }
     239             : 
     240             : /*
     241             : ** Py_UniversalNewlineFgets is an fgets variation that understands
     242             : ** all of \r, \n and \r\n conventions.
     243             : ** The stream should be opened in binary mode.
     244             : ** If fobj is NULL the routine always does newline conversion, and
     245             : ** it may peek one char ahead to gobble the second char in \r\n.
     246             : ** If fobj is non-NULL it must be a PyFileObject. In this case there
     247             : ** is no readahead but in stead a flag is used to skip a following
     248             : ** \n on the next read. Also, if the file is open in binary mode
     249             : ** the whole conversion is skipped. Finally, the routine keeps track of
     250             : ** the different types of newlines seen.
     251             : ** Note that we need no error handling: fgets() treats error and eof
     252             : ** identically.
     253             : */
     254             : char *
     255           0 : Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
     256             : {
     257           0 :     char *p = buf;
     258             :     int c;
     259           0 :     int newlinetypes = 0;
     260           0 :     int skipnextlf = 0;
     261             : 
     262           0 :     if (fobj) {
     263           0 :         errno = ENXIO;          /* What can you do... */
     264           0 :         return NULL;
     265             :     }
     266           0 :     FLOCKFILE(stream);
     267           0 :     c = 'x'; /* Shut up gcc warning */
     268           0 :     while (--n > 0 && (c = GETC(stream)) != EOF ) {
     269           0 :         if (skipnextlf ) {
     270           0 :             skipnextlf = 0;
     271           0 :             if (c == '\n') {
     272             :                 /* Seeing a \n here with skipnextlf true
     273             :                 ** means we saw a \r before.
     274             :                 */
     275           0 :                 newlinetypes |= NEWLINE_CRLF;
     276           0 :                 c = GETC(stream);
     277           0 :                 if (c == EOF) break;
     278             :             } else {
     279             :                 /*
     280             :                 ** Note that c == EOF also brings us here,
     281             :                 ** so we're okay if the last char in the file
     282             :                 ** is a CR.
     283             :                 */
     284           0 :                 newlinetypes |= NEWLINE_CR;
     285             :             }
     286             :         }
     287           0 :         if (c == '\r') {
     288             :             /* A \r is translated into a \n, and we skip
     289             :             ** an adjacent \n, if any. We don't set the
     290             :             ** newlinetypes flag until we've seen the next char.
     291             :             */
     292           0 :             skipnextlf = 1;
     293           0 :             c = '\n';
     294           0 :         } else if ( c == '\n') {
     295           0 :             newlinetypes |= NEWLINE_LF;
     296             :         }
     297           0 :         *p++ = c;
     298           0 :         if (c == '\n') break;
     299             :     }
     300             :     /* if ( c == EOF && skipnextlf )
     301             :         newlinetypes |= NEWLINE_CR; */
     302           0 :     FUNLOCKFILE(stream);
     303           0 :     *p = '\0';
     304           0 :     if ( skipnextlf ) {
     305             :         /* If we have no file object we cannot save the
     306             :         ** skipnextlf flag. We have to readahead, which
     307             :         ** will cause a pause if we're reading from an
     308             :         ** interactive stream, but that is very unlikely
     309             :         ** unless we're doing something silly like
     310             :         ** exec(open("/dev/tty").read()).
     311             :         */
     312           0 :         c = GETC(stream);
     313           0 :         if ( c != '\n' )
     314           0 :             ungetc(c, stream);
     315             :     }
     316           0 :     if (p == buf)
     317           0 :         return NULL;
     318           0 :     return buf;
     319             : }
     320             : 
     321             : /* **************************** std printer ****************************
     322             :  * The stdprinter is used during the boot strapping phase as a preliminary
     323             :  * file like object for sys.stderr.
     324             :  */
     325             : 
     326             : typedef struct {
     327             :     PyObject_HEAD
     328             :     int fd;
     329             : } PyStdPrinter_Object;
     330             : 
     331             : static PyObject *
     332           0 : stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
     333             : {
     334             :     PyStdPrinter_Object *self;
     335             : 
     336             :     assert(type != NULL && type->tp_alloc != NULL);
     337             : 
     338           0 :     self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
     339           0 :     if (self != NULL) {
     340           0 :         self->fd = -1;
     341             :     }
     342             : 
     343           0 :     return (PyObject *) self;
     344             : }
     345             : 
     346             : static int
     347           0 : stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
     348             : {
     349           0 :     PyErr_SetString(PyExc_TypeError,
     350             :                     "cannot create 'stderrprinter' instances");
     351           0 :     return -1;
     352             : }
     353             : 
     354             : PyObject *
     355           1 : PyFile_NewStdPrinter(int fd)
     356             : {
     357             :     PyStdPrinter_Object *self;
     358             : 
     359           1 :     if (fd != fileno(stdout) && fd != fileno(stderr)) {
     360             :         /* not enough infrastructure for PyErr_BadInternalCall() */
     361           0 :         return NULL;
     362             :     }
     363             : 
     364           1 :     self = PyObject_New(PyStdPrinter_Object,
     365             :                         &PyStdPrinter_Type);
     366           1 :     if (self != NULL) {
     367           1 :         self->fd = fd;
     368             :     }
     369           1 :     return (PyObject*)self;
     370             : }
     371             : 
     372             : static PyObject *
     373           0 : stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
     374             : {
     375             :     char *c;
     376             :     Py_ssize_t n;
     377             : 
     378           0 :     if (self->fd < 0) {
     379             :         /* fd might be invalid on Windows
     380             :          * I can't raise an exception here. It may lead to an
     381             :          * unlimited recursion in the case stderr is invalid.
     382             :          */
     383           0 :         Py_RETURN_NONE;
     384             :     }
     385             : 
     386           0 :     if (!PyArg_ParseTuple(args, "s", &c)) {
     387           0 :         return NULL;
     388             :     }
     389           0 :     n = strlen(c);
     390             : 
     391           0 :     Py_BEGIN_ALLOW_THREADS
     392           0 :     errno = 0;
     393             : #if defined(MS_WIN64) || defined(MS_WINDOWS)
     394             :     if (n > INT_MAX)
     395             :         n = INT_MAX;
     396             :     n = write(self->fd, c, (int)n);
     397             : #else
     398           0 :     n = write(self->fd, c, n);
     399             : #endif
     400           0 :     Py_END_ALLOW_THREADS
     401             : 
     402           0 :     if (n < 0) {
     403           0 :         if (errno == EAGAIN)
     404           0 :             Py_RETURN_NONE;
     405           0 :         PyErr_SetFromErrno(PyExc_IOError);
     406           0 :         return NULL;
     407             :     }
     408             : 
     409           0 :     return PyLong_FromSsize_t(n);
     410             : }
     411             : 
     412             : static PyObject *
     413           0 : stdprinter_fileno(PyStdPrinter_Object *self)
     414             : {
     415           0 :     return PyLong_FromLong((long) self->fd);
     416             : }
     417             : 
     418             : static PyObject *
     419           0 : stdprinter_repr(PyStdPrinter_Object *self)
     420             : {
     421           0 :     return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
     422             :                                 self->fd, self);
     423             : }
     424             : 
     425             : static PyObject *
     426           0 : stdprinter_noop(PyStdPrinter_Object *self)
     427             : {
     428           0 :     Py_RETURN_NONE;
     429             : }
     430             : 
     431             : static PyObject *
     432           0 : stdprinter_isatty(PyStdPrinter_Object *self)
     433             : {
     434             :     long res;
     435           0 :     if (self->fd < 0) {
     436           0 :         Py_RETURN_FALSE;
     437             :     }
     438             : 
     439           0 :     Py_BEGIN_ALLOW_THREADS
     440           0 :     res = isatty(self->fd);
     441           0 :     Py_END_ALLOW_THREADS
     442             : 
     443           0 :     return PyBool_FromLong(res);
     444             : }
     445             : 
     446             : static PyMethodDef stdprinter_methods[] = {
     447             :     {"close",           (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
     448             :     {"flush",           (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
     449             :     {"fileno",          (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
     450             :     {"isatty",          (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
     451             :     {"write",           (PyCFunction)stdprinter_write, METH_VARARGS, ""},
     452             :     {NULL,              NULL}  /*sentinel */
     453             : };
     454             : 
     455             : static PyObject *
     456           0 : get_closed(PyStdPrinter_Object *self, void *closure)
     457             : {
     458           0 :     Py_INCREF(Py_False);
     459           0 :     return Py_False;
     460             : }
     461             : 
     462             : static PyObject *
     463           0 : get_mode(PyStdPrinter_Object *self, void *closure)
     464             : {
     465           0 :     return PyUnicode_FromString("w");
     466             : }
     467             : 
     468             : static PyObject *
     469           0 : get_encoding(PyStdPrinter_Object *self, void *closure)
     470             : {
     471           0 :     Py_RETURN_NONE;
     472             : }
     473             : 
     474             : static PyGetSetDef stdprinter_getsetlist[] = {
     475             :     {"closed", (getter)get_closed, NULL, "True if the file is closed"},
     476             :     {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
     477             :     {"mode", (getter)get_mode, NULL, "String giving the file mode"},
     478             :     {0},
     479             : };
     480             : 
     481             : PyTypeObject PyStdPrinter_Type = {
     482             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     483             :     "stderrprinter",                            /* tp_name */
     484             :     sizeof(PyStdPrinter_Object),                /* tp_basicsize */
     485             :     0,                                          /* tp_itemsize */
     486             :     /* methods */
     487             :     0,                                          /* tp_dealloc */
     488             :     0,                                          /* tp_print */
     489             :     0,                                          /* tp_getattr */
     490             :     0,                                          /* tp_setattr */
     491             :     0,                                          /* tp_reserved */
     492             :     (reprfunc)stdprinter_repr,                  /* tp_repr */
     493             :     0,                                          /* tp_as_number */
     494             :     0,                                          /* tp_as_sequence */
     495             :     0,                                          /* tp_as_mapping */
     496             :     0,                                          /* tp_hash */
     497             :     0,                                          /* tp_call */
     498             :     0,                                          /* tp_str */
     499             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     500             :     0,                                          /* tp_setattro */
     501             :     0,                                          /* tp_as_buffer */
     502             :     Py_TPFLAGS_DEFAULT,                         /* tp_flags */
     503             :     0,                                          /* tp_doc */
     504             :     0,                                          /* tp_traverse */
     505             :     0,                                          /* tp_clear */
     506             :     0,                                          /* tp_richcompare */
     507             :     0,                                          /* tp_weaklistoffset */
     508             :     0,                                          /* tp_iter */
     509             :     0,                                          /* tp_iternext */
     510             :     stdprinter_methods,                         /* tp_methods */
     511             :     0,                                          /* tp_members */
     512             :     stdprinter_getsetlist,                      /* tp_getset */
     513             :     0,                                          /* tp_base */
     514             :     0,                                          /* tp_dict */
     515             :     0,                                          /* tp_descr_get */
     516             :     0,                                          /* tp_descr_set */
     517             :     0,                                          /* tp_dictoffset */
     518             :     stdprinter_init,                            /* tp_init */
     519             :     PyType_GenericAlloc,                        /* tp_alloc */
     520             :     stdprinter_new,                             /* tp_new */
     521             :     PyObject_Del,                               /* tp_free */
     522             : };
     523             : 
     524             : 
     525             : #ifdef __cplusplus
     526             : }
     527             : #endif

Generated by: LCOV version 1.10