_dbus_bindings: split out conn, conn-methods into separate translation units
[dbus-python-phuang.git] / _dbus_bindings / validation-impl.h
blob2e776f7c98b316c959d39769a8b71557fd5f3e00
1 /* Implementation of various validation functions for use in dbus-python.
3 * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
5 * Licensed under the Academic Free License version 2.1
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * This program 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 2 of the License, or
12 * (at your option) any later version.
14 * This program 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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 dbus_bool_t
26 dbus_py_validate_bus_name(const char *name,
27 dbus_bool_t may_be_unique,
28 dbus_bool_t may_be_not_unique)
30 dbus_bool_t dot = FALSE;
31 dbus_bool_t unique;
32 char last;
33 const char *ptr;
35 if (name[0] == '\0') {
36 PyErr_SetString(PyExc_ValueError, "Invalid bus name: "
37 "may not be empty");
38 return FALSE;
40 unique = (name[0] == ':');
41 if (unique && !may_be_unique) {
42 PyErr_Format(PyExc_ValueError, "Invalid well-known bus name '%s':"
43 "only unique names may start with ':'", name);
44 return FALSE;
46 if (!unique && !may_be_not_unique) {
47 PyErr_Format(PyExc_ValueError, "Invalid unique bus name '%s': "
48 "unique names must start with ':'", name);
49 return FALSE;
51 if (strlen(name) > 255) {
52 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
53 "too long (> 255 characters)", name);
54 return FALSE;
56 last = '\0';
57 for (ptr = name + (unique ? 1 : 0); *ptr; ptr++) {
58 if (*ptr == '.') {
59 dot = TRUE;
60 if (last == '.') {
61 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
62 "contains substring '..'", name);
63 return FALSE;
65 else if (last == '\0') {
66 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
67 "must not start with '.'", name);
68 return FALSE;
71 else if (*ptr >= '0' && *ptr <= '9') {
72 if (!unique) {
73 if (last == '.') {
74 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
75 "a digit may not follow '.' except in a "
76 "unique name starting with ':'", name);
77 return FALSE;
79 else if (last == '\0') {
80 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
81 "must not start with a digit", name);
82 return FALSE;
86 else if ((*ptr < 'a' || *ptr > 'z') &&
87 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_' && *ptr != '-') {
88 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
89 "contains invalid character '%c'", name, *ptr);
90 return FALSE;
92 last = *ptr;
94 if (last == '.') {
95 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
96 "not end with '.'", name);
97 return FALSE;
99 if (!dot) {
100 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
101 "contain '.'", name);
102 return FALSE;
104 return TRUE;
107 PyDoc_STRVAR(validate_bus_name__doc__,
108 "validate_bus_name(name[, allow_unique=True[, allow_well_known=True]])\n"
109 "\n"
110 "Raise ValueError if the argument is not a valid bus name.\n"
111 "\n"
112 "By default both unique and well-known names are accepted.\n"
113 "\n"
114 ":Parameters:\n"
115 " `name` : str\n"
116 " The name to be validated\n"
117 " `allow_unique` : bool\n"
118 " If False, unique names of the form :1.123 will be rejected\n"
119 " `allow_well_known` : bool\n"
120 " If False, well-known names of the form com.example.Foo\n"
121 " will be rejected\n"
122 ":Since: 0.80\n"
125 static PyObject *
126 validate_bus_name(PyObject *unused UNUSED, PyObject *args, PyObject *kwargs)
128 const char *name;
129 int allow_unique = 1;
130 int allow_well_known = 1;
131 static char *argnames[] = { "name", "allow_unique", "allow_well_known",
132 NULL };
134 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
135 "s|ii:validate_bus_name", argnames,
136 &name, &allow_unique,
137 &allow_well_known)) {
138 return NULL;
140 if (!dbus_py_validate_bus_name(name, !!allow_unique, !!allow_well_known)) {
141 return NULL;
143 Py_RETURN_NONE;
146 dbus_bool_t
147 dbus_py_validate_member_name(const char *name)
149 const char *ptr;
151 if (name[0] == '\0') {
152 PyErr_SetString(PyExc_ValueError, "Invalid member name: may not "
153 "be empty");
154 return FALSE;
156 if (strlen(name) > 255) {
157 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
158 "too long (> 255 characters)", name);
159 return FALSE;
161 for (ptr = name; *ptr; ptr++) {
162 if (*ptr >= '0' && *ptr <= '9') {
163 if (ptr == name) {
164 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
165 "must not start with a digit", name);
166 return FALSE;
169 else if ((*ptr < 'a' || *ptr > 'z') &&
170 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
171 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
172 "contains invalid character '%c'", name, *ptr);
173 return FALSE;
176 return TRUE;
179 PyDoc_STRVAR(validate_member_name__doc__,
180 "validate_member_name(name)\n"
181 "\n"
182 "Raise ValueError if the argument is not a valid member (signal or method) "
183 "name.\n"
184 "\n"
185 ":Since: 0.80\n"
188 static PyObject *
189 validate_member_name(PyObject *unused UNUSED, PyObject *args)
191 const char *name;
193 if (!PyArg_ParseTuple(args, "s:validate_member_name", &name)) {
194 return NULL;
196 if (!dbus_py_validate_member_name(name)) {
197 return NULL;
199 Py_RETURN_NONE;
202 dbus_bool_t
203 dbus_py_validate_interface_name(const char *name)
205 dbus_bool_t dot = FALSE;
206 char last;
207 const char *ptr;
209 if (name[0] == '\0') {
210 PyErr_SetString(PyExc_ValueError, "Invalid interface or error name: "
211 "may not be empty");
212 return FALSE;
214 if (strlen(name) > 255) {
215 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
216 "too long (> 255 characters)", name);
217 return FALSE;
219 last = '\0';
220 for (ptr = name; *ptr; ptr++) {
221 if (*ptr == '.') {
222 dot = TRUE;
223 if (last == '.') {
224 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
225 "contains substring '..'", name);
226 return FALSE;
228 else if (last == '\0') {
229 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
230 "must not start with '.'", name);
231 return FALSE;
234 else if (*ptr >= '0' && *ptr <= '9') {
235 if (last == '.') {
236 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
237 "a digit may not follow '.'", name);
238 return FALSE;
240 else if (last == '\0') {
241 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
242 "must not start with a digit", name);
243 return FALSE;
246 else if ((*ptr < 'a' || *ptr > 'z') &&
247 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
248 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
249 "contains invalid character '%c'", name, *ptr);
250 return FALSE;
252 last = *ptr;
254 if (last == '.') {
255 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': must "
256 "not end with '.'", name);
257 return FALSE;
259 if (!dot) {
260 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': must "
261 "contain '.'", name);
262 return FALSE;
264 return TRUE;
267 PyDoc_STRVAR(validate_interface_name__doc__,
268 "validate_interface_name(name)\n\n"
269 "Raise ValueError if the given string is not a valid interface name.\n"
270 "\n"
271 ":Since: 0.80\n"
274 PyDoc_STRVAR(validate_error_name__doc__,
275 "validate_error_name(name)\n\n"
276 "Raise ValueError if the given string is not a valid error name.\n"
277 "\n"
278 ":Since: 0.80\n"
281 static PyObject *
282 validate_interface_name(PyObject *unused UNUSED, PyObject *args)
284 const char *name;
286 if (!PyArg_ParseTuple(args, "s:validate_interface_name", &name)) {
287 return NULL;
289 if (!dbus_py_validate_interface_name(name)) {
290 return NULL;
292 Py_RETURN_NONE;
296 dbus_bool_t
297 dbus_py_validate_object_path(const char *path)
299 const char *ptr;
301 if (path[0] != '/') {
302 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': does not "
303 "start with '/'", path);
304 return FALSE;
306 if (path[1] == '\0') return TRUE;
307 for (ptr = path + 1; *ptr; ptr++) {
308 if (*ptr == '/') {
309 if (ptr[-1] == '/') {
310 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
311 "contains substring '//'", path);
312 return FALSE;
315 else if ((*ptr < 'a' || *ptr > 'z') &&
316 (*ptr < 'A' || *ptr > 'Z') &&
317 (*ptr < '0' || *ptr > '9') && *ptr != '_') {
318 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
319 "contains invalid character '%c'", path, *ptr);
320 return FALSE;
323 if (ptr[-1] == '/') {
324 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': ends "
325 "with '/' and is not just '/'", path);
326 return FALSE;
328 return TRUE;
331 PyDoc_STRVAR(validate_object_path__doc__,
332 "validate_object_path(name)\n\n"
333 "Raise ValueError if the given string is not a valid object path.\n"
334 "\n"
335 ":Since: 0.80\n"
338 static PyObject *
339 validate_object_path(PyObject *unused UNUSED, PyObject *args)
341 const char *name;
343 if (!PyArg_ParseTuple(args, "s:validate_object_path", &name)) {
344 return NULL;
346 if (!dbus_py_validate_object_path(name)) {
347 return NULL;
349 Py_RETURN_NONE;
352 /* vim:set ft=c cino< sw=4 sts=4 et: */