Remove from EXTRA_DIST files we'd already be distributing
[dbus-python-phuang.git] / _dbus_bindings / validation.c
blob302c521285a8a2071d3cb7f85da6093e776879a7
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 #include "dbus_bindings-internal.h"
27 dbus_bool_t
28 dbus_py_validate_bus_name(const char *name,
29 dbus_bool_t may_be_unique,
30 dbus_bool_t may_be_not_unique)
32 dbus_bool_t dot = FALSE;
33 dbus_bool_t unique;
34 char last;
35 const char *ptr;
37 if (name[0] == '\0') {
38 PyErr_SetString(PyExc_ValueError, "Invalid bus name: "
39 "may not be empty");
40 return FALSE;
42 unique = (name[0] == ':');
43 if (unique && !may_be_unique) {
44 PyErr_Format(PyExc_ValueError, "Invalid well-known bus name '%s':"
45 "only unique names may start with ':'", name);
46 return FALSE;
48 if (!unique && !may_be_not_unique) {
49 PyErr_Format(PyExc_ValueError, "Invalid unique bus name '%s': "
50 "unique names must start with ':'", name);
51 return FALSE;
53 if (strlen(name) > 255) {
54 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
55 "too long (> 255 characters)", name);
56 return FALSE;
58 last = '\0';
59 for (ptr = name + (unique ? 1 : 0); *ptr; ptr++) {
60 if (*ptr == '.') {
61 dot = TRUE;
62 if (last == '.') {
63 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
64 "contains substring '..'", name);
65 return FALSE;
67 else if (last == '\0') {
68 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
69 "must not start with '.'", name);
70 return FALSE;
73 else if (*ptr >= '0' && *ptr <= '9') {
74 if (!unique) {
75 if (last == '.') {
76 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
77 "a digit may not follow '.' except in a "
78 "unique name starting with ':'", name);
79 return FALSE;
81 else if (last == '\0') {
82 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
83 "must not start with a digit", name);
84 return FALSE;
88 else if ((*ptr < 'a' || *ptr > 'z') &&
89 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_' && *ptr != '-') {
90 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
91 "contains invalid character '%c'", name, *ptr);
92 return FALSE;
94 last = *ptr;
96 if (last == '.') {
97 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
98 "not end with '.'", name);
99 return FALSE;
101 if (!dot) {
102 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
103 "contain '.'", name);
104 return FALSE;
106 return TRUE;
109 dbus_bool_t
110 dbus_py_validate_member_name(const char *name)
112 const char *ptr;
114 if (name[0] == '\0') {
115 PyErr_SetString(PyExc_ValueError, "Invalid member name: may not "
116 "be empty");
117 return FALSE;
119 if (strlen(name) > 255) {
120 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
121 "too long (> 255 characters)", name);
122 return FALSE;
124 for (ptr = name; *ptr; ptr++) {
125 if (*ptr >= '0' && *ptr <= '9') {
126 if (ptr == name) {
127 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
128 "must not start with a digit", name);
129 return FALSE;
132 else if ((*ptr < 'a' || *ptr > 'z') &&
133 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
134 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
135 "contains invalid character '%c'", name, *ptr);
136 return FALSE;
139 return TRUE;
142 dbus_bool_t
143 dbus_py_validate_interface_name(const char *name)
145 dbus_bool_t dot = FALSE;
146 char last;
147 const char *ptr;
149 if (name[0] == '\0') {
150 PyErr_SetString(PyExc_ValueError, "Invalid interface or error name: "
151 "may not be empty");
152 return FALSE;
154 if (strlen(name) > 255) {
155 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
156 "too long (> 255 characters)", name);
157 return FALSE;
159 last = '\0';
160 for (ptr = name; *ptr; ptr++) {
161 if (*ptr == '.') {
162 dot = TRUE;
163 if (last == '.') {
164 PyErr_Format(PyExc_ValueError, "Invalid interface or "
165 "error name '%s': contains substring '..'", name);
166 return FALSE;
168 else if (last == '\0') {
169 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
170 "name '%s': must not start with '.'", name);
171 return FALSE;
174 else if (*ptr >= '0' && *ptr <= '9') {
175 if (last == '.') {
176 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
177 "name '%s': a digit may not follow '.'", name);
178 return FALSE;
180 else if (last == '\0') {
181 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
182 "name '%s': must not start with a digit", name);
183 return FALSE;
186 else if ((*ptr < 'a' || *ptr > 'z') &&
187 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
188 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
189 "name '%s': contains invalid character '%c'",
190 name, *ptr);
191 return FALSE;
193 last = *ptr;
195 if (last == '.') {
196 PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
197 "'%s': must not end with '.'", name);
198 return FALSE;
200 if (!dot) {
201 PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
202 "'%s': must contain '.'", name);
203 return FALSE;
205 return TRUE;
209 dbus_bool_t
210 dbus_py_validate_object_path(const char *path)
212 const char *ptr;
214 if (path[0] != '/') {
215 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': does not "
216 "start with '/'", path);
217 return FALSE;
219 if (path[1] == '\0') return TRUE;
220 for (ptr = path + 1; *ptr; ptr++) {
221 if (*ptr == '/') {
222 if (ptr[-1] == '/') {
223 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
224 "contains substring '//'", path);
225 return FALSE;
228 else if ((*ptr < 'a' || *ptr > 'z') &&
229 (*ptr < 'A' || *ptr > 'Z') &&
230 (*ptr < '0' || *ptr > '9') && *ptr != '_') {
231 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
232 "contains invalid character '%c'", path, *ptr);
233 return FALSE;
236 if (ptr[-1] == '/') {
237 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': ends "
238 "with '/' and is not just '/'", path);
239 return FALSE;
241 return TRUE;
244 /* vim:set ft=c cino< sw=4 sts=4 et: */