GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/util.c Lines: 59 63 93.7 %
Date: 2020-02-19 21:21:49 Branches: 23 32 71.9 %

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
24
static PyObject* pyalpm_error_str(PyObject* exception) {
38
24
  PyObject* args = PyObject_GetAttrString(exception, "args");
39
24
  PyObject* result;
40
24
  const char* errstring;
41
24
  enum _alpm_errno_t errcode;
42
24
  PyObject *data;
43
44
24
  int handle_format;
45
  {
46
    /* check whether alpm.error was set with standard args */
47
24
    PyObject *exctype, *excvalue, *exctraceback;
48
24
    PyErr_Fetch(&exctype, &excvalue, &exctraceback);
49
24
    handle_format = PyArg_ParseTuple(args, "siO",
50
        &errstring, &errcode, &data);
51
24
    if (!handle_format) {
52
3
      PyErr_Clear();
53
3
      result = PyObject_Str(args);
54
    }
55
24
    PyErr_Restore(exctype, excvalue, exctraceback);
56
  }
57
58
24
  if(handle_format) {
59
21
    if (data == Py_None) {
60
18
      result = PyUnicode_FromFormat("%s, pm_errno %d (%s)", errstring, errcode, alpm_strerror(errcode));
61
    } else {
62
3
      result = PyUnicode_FromFormat("%s, pm_errno %d (%s), %S", errstring, errcode, alpm_strerror(errcode), data);
63
    }
64
  }
65
66
24
  Py_DECREF(args);
67
24
  return result;
68
}
69
70
3
void init_pyalpm_error(PyObject* module) {
71
3
  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
3
  ((PyTypeObject*)alpm_error)->tp_str = pyalpm_error_str;
77
3
  PyModule_AddObject(module, "error", alpm_error);
78
3
  Py_INCREF(alpm_error);
79
3
}
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
51
int pylist_string_to_alpmlist(PyObject *list, alpm_list_t* *result)
87
{
88
51
  alpm_list_t *ret = NULL;
89
51
  PyObject *iterator = PyObject_GetIter(list);
90
51
  PyObject *item;
91
92
51
  if(iterator == NULL) {
93
    PyErr_SetString(PyExc_TypeError, "object is not iterable");
94
    return -1;
95
  }
96
97
99
  while((item = PyIter_Next(iterator)))
98
  {
99
51
    if (PyBytes_Check(item)) {
100
3
      ret = alpm_list_add(ret, strdup(PyBytes_AS_STRING(item)));
101
48
    } else if (PyUnicode_Check(item)) {
102
45
      PyObject* utf8 = PyUnicode_AsUTF8String(item);
103
45
      ret = alpm_list_add(ret, strdup(PyBytes_AS_STRING(utf8)));
104
45
      Py_DECREF(utf8);
105
    } else {
106
3
      PyErr_SetString(PyExc_TypeError, "list must contain only strings");
107
3
      FREELIST(ret);
108
3
      Py_DECREF(item);
109
3
      return -1;
110
    }
111
147
    Py_DECREF(item);
112
  }
113
48
  Py_DECREF(iterator);
114
115
48
  *result = ret;
116
48
  return 0;
117
}
118
119
39
PyObject* pyobject_from_string(void *s) {
120
39
  return Py_BuildValue("s", (char*)s);
121
}
122
123
126
PyObject* alpmlist_to_pylist(alpm_list_t *prt, PyObject* pybuilder(void*))
124
{
125
126
  PyObject *output, *stritem;
126
126
  alpm_list_t *tmp;
127
128
126
  output = PyList_New(0);
129
126
  if(output == NULL) {
130
    PyErr_SetString(PyExc_RuntimeError, "unable to create list object");
131
    return NULL;
132
  }
133
134
204
  for(tmp = prt; tmp; tmp = alpm_list_next(tmp)) {
135
78
    stritem = pybuilder(tmp->data);
136
78
    if (!stritem) {
137
126
      Py_CLEAR(stritem);
138
      return NULL;
139
    }
140
78
    PyList_Append(output, stritem);
141
78
    Py_CLEAR(stritem);
142
  }
143
144
  return output;
145
}
146
147
/* vim: set ts=2 sw=2 et: */