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  */
60 bool
61 InterfaceChecker::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  */
87 bool
88 InterfaceChecker::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  */
146 bool
147 InterfaceChecker::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 
157 const std::set<std::string>
158 reserved_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 
236 const std::set<std::string>
237 reserved_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 };
InterfaceChecker::validValue
static bool validValue(const std::string &type, const std::string &value)
Check value validity for given type.
Definition: checker.cpp:88
InterfaceChecker::validType
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
InterfaceChecker::validName
static bool validName(const std::string &name, const std::set< std::string > &reserved_names)
Check identifiers.
Definition: checker.cpp:147
fawkes::Exception
Definition: exception.h:41