Fawkes API Fawkes Development Version
checker.cpp
1
2/***************************************************************************
3 * type_checker.cpp - Interface generator type checker
4 *
5 * Generated: Wed Oct 11 15:39:10 2006
6 * Copyright 2006 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL file in the doc directory.
21 */
22
23#include <core/exception.h>
24#include <interfaces/generator/checker.h>
25#include <interfaces/generator/exceptions.h>
26
27#include <cerrno>
28#include <climits>
29#include <cmath>
30#include <cstdlib>
31
32// request setting of INT8_MAX etc. constants
33#ifndef __STDC_LIMIT_MACROS
34# define __STDC_LIMIT_MACROS
35#endif
36#include <stdint.h>
37
38/** @class InterfaceChecker <interfaces/generator/checker.h>
39 * @brief Check interface type and identifier validity.
40 */
41
42/** Decide if a supplied type is correct and in the case of constants if the
43 * supplied value matches the field type.
44 *
45 * Valid types are:
46 * - int
47 * - long int
48 * - unsigned int
49 * - unsigned long int
50 * - bool
51 * - float
52 * - double
53 * - byte (unsigned 8-bit number)
54 * - string
55 * @param type type string to check
56 * @param enum_constants an optional vector of enumeration constants that are used for
57 * type validation.
58 * @return true, if type is valid, false otherwise
59 */
60bool
61InterfaceChecker::validType(const std::string & type,
62 std::vector<InterfaceEnumConstant> *enum_constants)
63{
64 if ((type == "int8") || (type == "int16") || (type == "int32") || (type == "int64")
65 || (type == "uint8") || (type == "uint16") || (type == "uint32") || (type == "uint64")
66 || (type == "bool") || (type == "char") || (type == "float") || (type == "byte")
67 || (type == "string") || (type == "double")) {
68 return true;
69 } else if (enum_constants != NULL) {
70 std::vector<InterfaceEnumConstant>::iterator i;
71 for (i = enum_constants->begin(); i != enum_constants->end(); ++i) {
72 if (type == (*i).get_name()) {
73 return true;
74 }
75 }
76 return false;
77 } else {
78 return false;
79 }
80}
81
82/** Check value validity for given type.
83 * @param type type if value
84 * @param value value to check
85 * @return true, if value is valid for type, false otherwise
86 */
87bool
88InterfaceChecker::validValue(const std::string &type, const std::string &value)
89{
90 if (type.find("int") != std::string::npos) {
91 errno = 0;
92 char * endptr;
93 long long int rv = strtoll(value.c_str(), &endptr, 10);
94 if (((rv == LLONG_MIN) || (rv == LLONG_MAX)) && (errno == ERANGE)) {
95 throw fawkes::Exception("Could not convert value string '%s' to "
96 "long long int",
97 value.c_str());
98 }
99 if ((endptr != NULL) && (endptr[0] == '\0')) {
100 if (type == "uint8") {
101 return (rv >= 0) && (rv <= UINT8_MAX);
102 } else if (type == "uint16") {
103 return (rv >= 0) && (rv <= UINT16_MAX);
104 } else if (type == "uint32") {
105 return (rv >= 0) && (rv <= UINT32_MAX);
106 } else if (type == "uint64") {
107 return (rv >= 0) && ((uint64_t)rv <= UINT64_MAX);
108 } else if (type == "int8") {
109 return (rv >= INT8_MIN) && (rv <= INT8_MAX);
110 } else if (type == "int16") {
111 return (rv >= INT16_MIN) && (rv <= INT16_MAX);
112 } else if (type == "int32") {
113 return (rv >= INT32_MIN) && (rv <= INT32_MAX);
114 } else if (type == "int64") {
115 return (rv >= INT64_MIN) && (rv <= INT64_MAX);
116 } else {
117 return false;
118 }
119 } else {
120 return false;
121 }
122 } else if (type == "bool") {
123 return ((value == "true") || (value == "false") || (value == "yes") || (value == "no")
124 || (value == "0") || (value == "1"));
125 } else if ((type == "float") || (type == "double")) {
126 char *endptr;
127 float rv = strtod(value.c_str(), &endptr);
128 if ((rv == HUGE_VAL) || (rv == -HUGE_VAL)) {
129 throw fawkes::Exception("Could not convert string '%s' to float", value.c_str());
130 }
131 return ((endptr != NULL) && (endptr[0] == '\0'));
132 } else if (type == "string") {
133 return true;
134 } else {
135 return false;
136 }
137}
138
139/** Check identifiers.
140 * Identifiers that are used by the implementation and cannot be used
141 * as field or message names are rejected.
142 * @param name identifier to check
143 * @param reserved_names reserved names to reject
144 * @return true if name is valid, false otherwise
145 */
146bool
147InterfaceChecker::validName(const std::string &name, const std::set<std::string> &reserved_names)
148{
149 if (name.substr(0, 4) == "set_")
150 return reserved_names.find(name.substr(5)) == reserved_names.end();
151 if (name.substr(0, 3) == "is_")
152 return reserved_names.find(name.substr(4)) == reserved_names.end();
153 else
154 return reserved_names.find(name) == reserved_names.end();
155}
156
157const std::set<std::string>
158reserved_names_interface()
159{
160 return {"id",
161 "clone",
162 "oftype",
163 "datachunk",
164 "datasize",
165 "type",
166 "uid",
167 "serial",
168 "mem_serial",
169 "hash",
170 "hash_size",
171 "hash_printable",
172 "writer",
173 "validity",
174 "valid",
175 "owner",
176 "from_chunk",
177 "create_message",
178 "copy_values",
179 "enum_tostring",
180 "resize_buffers",
181 "num_buffers",
182 "copy_shared_to_buffer",
183 "copy_private_to_buffer",
184 "read_from_buffer",
185 "compare_buffers",
186 "buffer_timestamp",
187 "read",
188 "write",
189 "has_writer",
190 "num_readers",
191 "writer",
192 "readers",
193 "changed",
194 "auto_timestamping",
195 "timestamp",
196 "clock",
197 "mark_data_changed",
198 "get_message_types",
199 "msgq_enqueue",
200 "msgq_enqueue_copy",
201 "msgq_remove",
202 "msgq_size",
203 "msgq_flush",
204 "msgq_lock",
205 "msgq_try_lock",
206 "msgq_unlock",
207 "msgq_pop",
208 "msgq_first",
209 "msgq_empty",
210 "msgq_append",
211 "msgq_first_is",
212 "msgq_first",
213 "msgq_first_safe",
214 "msgq_begin",
215 "msgq_end",
216 "fields",
217 "fields_end",
218 "num_fields",
219 "parse_uid",
220 "reserved_names",
221 "message_valid",
222 "add_fieldinfo",
223 "add_messageinfo",
224 "data_ptr",
225 "data_size",
226 "data_changed",
227 "data_ts",
228 "type_id",
229 "instance_serial",
230 "mediators",
231 "memory",
232 "readwrite",
233 "owner"};
234};
235
236const std::set<std::string>
237reserved_names_message()
238{
239 return {"id",
240 "mark_enqueued",
241 "enqueued",
242 "time_enqueued",
243 "sender_id",
244 "sender_thread_name",
245 "interface",
246 "type",
247 "fields",
248 "fields_end",
249 "num_fields",
250 "datachunk",
251 "datasize",
252 "hops",
253 "from_chunk",
254 "recipient",
255 "clone",
256 "of_type",
257 "as_type"};
258};
static bool validValue(const std::string &type, const std::string &value)
Check value validity for given type.
Definition: checker.cpp:88
static bool validName(const std::string &name, const std::set< std::string > &reserved_names)
Check identifiers.
Definition: checker.cpp:147
static bool validType(const std::string &type, std::vector< InterfaceEnumConstant > *enum_constants=0)
Decide if a supplied type is correct and in the case of constants if the supplied value matches the f...
Definition: checker.cpp:61
Base class for exceptions in Fawkes.
Definition: exception.h:36