GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/util.c Lines: 50 62 80.6 %
Date: 2019-02-09 19:11:25 Branches: 17 32 53.1 %

Line Branch Exec Source
1
/**
2
 * util.c : utility functions for pyalpm
3
 *
4
 *  Copyright 2008 Imanol Celaya <ilcra1989@gmail.com>
5
 *  Copyright 2011 Rémy Oudompheng <remy@archlinux.org>
6
 *
7
 *  This file is part of pyalpm.
8
 *
9
 *  pyalpm is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation, either version 3 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  pyalpm is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with pyalpm.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
/* Include pyconfig for feature test macros. */
25
#include <pyconfig.h>
26
#include <string.h>
27
28
#include <Python.h>
29
#include <alpm.h>
30
#include <alpm_list.h>
31
32
/** Errors */
33
34
PyObject* alpm_error = NULL;
35
36
/** Formats an alpm.error exception using errno from libalpm. */
37
1
static PyObject* pyalpm_error_str(PyObject* exception) {
38
1
  PyObject* args = PyObject_GetAttrString(exception, "args");
39
1
  PyObject* result;
40
1
  const char* errstring;
41
1
  enum _alpm_errno_t errcode;
42
1
  PyObject *data;
43
44
1
  int handle_format;
45
  {
46
    /* check whether alpm.error was set with standard args */
47
1
    PyObject *exctype, *excvalue, *exctraceback;
48
1
    PyErr_Fetch(&exctype, &excvalue, &exctraceback);
49
1
    handle_format = PyArg_ParseTuple(args, "siO",
50
        &errstring, &errcode, &data);
51
1
    if (!handle_format) {
52
      PyErr_Clear();
53
      result = PyObject_Str(args);
54
    }
55
1
    PyErr_Restore(exctype, excvalue, exctraceback);
56
  }
57
58
1
  if(handle_format) {
59
1
    if (data == Py_None) {
60
      result = PyUnicode_FromFormat("%s, pm_errno %d (%s)", errstring, errcode, alpm_strerror(errcode));
61
    } else {
62
1
      result = PyUnicode_FromFormat("%s, pm_errno %d (%s), %S", errstring, errcode, alpm_strerror(errcode), data);
63
    }
64
  }
65
66
1
  Py_DECREF(args);
67
1
  return result;
68
}
69
70
1
void init_pyalpm_error(PyObject* module) {
71
1
  alpm_error = PyErr_NewExceptionWithDoc("alpm.error",
72
      "Exception raised when an error arises from libalpm\n"
73
      "The args attribute will usually contain a tuple "
74
      "(error message, errno from libalpm, extra data)\n",
75
      NULL, NULL);
76
1
  ((PyTypeObject*)alpm_error)->tp_str = pyalpm_error_str;
77
1
  PyModule_AddObject(module, "error", alpm_error);
78
1
  Py_INCREF(alpm_error);
79
1
}
80
81
/** Python lists and libalpm lists */
82
83
/** Converts a Python list of strings to an alpm_list_t linked list.
84
 * return 0 on success, -1 on failure
85
 */
86
12
int pylist_string_to_alpmlist(PyObject *list, alpm_list_t* *result)
87
{
88
12
  alpm_list_t *ret = NULL;
89
12
  PyObject *iterator = PyObject_GetIter(list);
90
12
  PyObject *item;
91
92
12
  if(iterator == NULL) {
93
    PyErr_SetString(PyExc_TypeError, "object is not iterable");
94
    return -1;
95
  }
96
97
24
  while((item = PyIter_Next(iterator)))
98
  {
99
12
    if (PyBytes_Check(item)) {
100
      ret = alpm_list_add(ret, strdup(PyBytes_AS_STRING(item)));
101
12
    } else if (PyUnicode_Check(item)) {
102
12
      PyObject* utf8 = PyUnicode_AsUTF8String(item);
103
12
      ret = alpm_list_add(ret, strdup(PyBytes_AS_STRING(utf8)));
104
12
      Py_DECREF(utf8);
105
    } else {
106
      PyErr_SetString(PyExc_TypeError, "list must contain only strings");
107
      FREELIST(ret);
108
      Py_DECREF(item);
109
      return -1;
110
    }
111
12
    Py_DECREF(item);
112
  }
113
12
  Py_DECREF(iterator);
114
115
12
  *result = ret;
116
12
  return 0;
117
}
118
119
10
PyObject* pyobject_from_string(void *s) {
120
10
  return Py_BuildValue("s", (char*)s);
121
}
122
123
38
PyObject* alpmlist_to_pylist(alpm_list_t *prt, PyObject* pybuilder(void*))
124
{
125
38
  PyObject *output, *stritem;
126
38
  alpm_list_t *tmp;
127
128
38
  output = PyList_New(0);
129
38
  if(output == NULL) {
130
    PyErr_SetString(PyExc_RuntimeError, "unable to create list object");
131
    return NULL;
132
  }
133
134
80
  for(tmp = prt; tmp; tmp = alpm_list_next(tmp)) {
135
42
    stritem = pybuilder(tmp->data);
136
42
    if (!stritem) {
137
      Py_CLEAR(stritem);
138
      return NULL;
139
    }
140
42
    PyList_Append(output, stritem);
141
42
    Py_CLEAR(stritem);
142
  }
143
144
  return output;
145
}
146
147
/* vim: set ts=2 sw=2 et: */