23 #include "tolua_generator.h" 24 #include "exceptions.h" 26 #include <utils/misc/string_conversions.h> 60 std::string config_basename, std::string author,
61 std::string year, std::string creation_date,
62 std::string data_comment,
63 const unsigned char *hash,
size_t hash_size,
64 const std::vector<InterfaceConstant> &constants,
65 const std::vector<InterfaceEnumConstant> &enum_constants,
66 const std::vector<InterfaceField> &data_fields,
67 const std::vector<InterfacePseudoMap> &pseudo_maps,
68 const std::vector<InterfaceMessage> &messages
71 this->dir = directory;
72 if ( dir.find_last_of(
"/") != (dir.length() - 1) ) {
75 this->author = author;
77 this->creation_date = creation_date;
78 this->data_comment = data_comment;
80 this->hash_size = hash_size;
81 this->constants = constants;
82 this->enum_constants = enum_constants;
83 this->data_fields = data_fields;
84 this->pseudo_maps = pseudo_maps;
85 this->messages = messages;
87 filename_tolua = config_basename +
".tolua";
88 filename_h = config_basename +
".h";
90 if ( interface_name.find(
"Interface", 0) == string::npos ) {
92 class_name = interface_name +
"Interface";
94 class_name = interface_name;
114 if (c_type ==
"uint8_t") {
115 return "unsigned char";
116 }
else if (c_type ==
"uint16_t") {
117 return "unsigned short";
118 }
else if (c_type ==
"uint32_t") {
119 return "unsigned int";
120 }
else if (c_type ==
"uint64_t") {
121 #if __WORDSIZE == 64 || defined(__x86_64__) 122 return "unsigned long";
124 return "unsigned long long";
126 }
else if (c_type ==
"int8_t") {
128 }
else if (c_type ==
"int16_t") {
130 }
else if (c_type ==
"int32_t") {
132 }
else if (c_type ==
"int64_t") {
133 #if __WORDSIZE == 64 || defined(__x86_64__) 138 }
else if (c_type ==
"uint8_t *") {
139 return "unsigned char *";
140 }
else if (c_type ==
"uint16_t *") {
141 return "unsigned short *";
142 }
else if (c_type ==
"uint32_t *") {
143 return "unsigned int *";
144 }
else if (c_type ==
"uint64_t *") {
145 #if __WORDSIZE == 64 || defined(__x86_64__) 146 return "unsigned long *";
148 return "unsigned long long *";
150 }
else if (c_type ==
"int8_t *") {
152 }
else if (c_type ==
"int16_t *") {
154 }
else if (c_type ==
"int32_t *") {
156 }
else if (c_type ==
"int64_t *") {
157 #if __WORDSIZE == 64 || defined(__x86_64__) 160 return "long long *";
163 return c_type.c_str();
176 fprintf(f,
"\n/***************************************************************************\n");
177 fprintf(f,
" * %s - Fawkes BlackBoard Interface - %s - tolua++ wrapper\n", filename.c_str(), class_name.c_str());
179 if ( creation_date.length() > 0 ) {
180 fprintf(f,
" * Interface created: %s\n", creation_date.c_str());
182 fprintf(f,
" * Templated created: Thu Oct 12 10:49:19 2006\n");
183 fprintf(f,
" * Copyright %s %s\n", year.c_str(),
184 ((author.length() > 0) ? author.c_str() :
"AllemaniACs RoboCup Team") );
186 fprintf(f,
" ****************************************************************************/\n\n");
188 fprintf(f,
" * This program is free software; you can redistribute it and/or modify\n");
189 fprintf(f,
" * it under the terms of the GNU General Public License as published by\n");
190 fprintf(f,
" * the Free Software Foundation; either version 2 of the License, or\n");
191 fprintf(f,
" * (at your option) any later version.\n");
193 fprintf(f,
" * This program is distributed in the hope that it will be useful,\n");
194 fprintf(f,
" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
195 fprintf(f,
" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
196 fprintf(f,
" * GNU Library General Public License for more details.\n");
198 fprintf(f,
" * You should have received a copy of the GNU General Public License\n");
199 fprintf(f,
" * along with this program; if not, write to the Free Software Foundation,\n");
200 fprintf(f,
" * Inc., 51 Franklin Street, Fifth floor, Boston, MA 02111-1307, USA.\n");
201 fprintf(f,
" */\n\n");
211 for ( vector<InterfaceConstant>::iterator i = constants.begin(); i != constants.end(); ++i) {
212 fprintf(f,
" static const %s %s;\n", convert_type(i->getType()),
213 i->getName().c_str());
217 for ( vector<InterfaceEnumConstant>::iterator i = enum_constants.begin(); i != enum_constants.end(); ++i) {
218 fprintf(f,
" typedef enum {\n");
219 vector<InterfaceEnumConstant::EnumItem> items = (*i).get_items();
220 vector<InterfaceEnumConstant::EnumItem>::iterator j = items.begin();
221 while (j != items.end()) {
222 if (j->has_custom_value) {
223 fprintf(f,
" %s = %i", j->name.c_str(), j->custom_value);
225 fprintf(f,
" %s", j->name.c_str());
228 if ( j != items.end() ) {
234 fprintf(f,
" } %s;\n\n", (*i).get_name().c_str());
245 for (vector<InterfaceMessage>::iterator i = messages.begin(); i != messages.end(); ++i) {
246 fprintf(f,
" class %s : public Message\n" 247 " {\n", (*i).getName().c_str());
248 write_message_ctor_dtor_h(f,
" ", (*i).getName(), (*i).getFields());
249 write_message_superclass_h(f);
250 write_methods_h(f,
" ", (*i).getFields());
252 fprintf(f,
" };\n\n");
265 std::string classname)
270 is.c_str(), classname.c_str(),
271 is.c_str(), classname.c_str());
283 std::string classname,
284 std::vector<InterfaceField> fields)
286 vector<InterfaceField>::iterator i;
288 if ( fields.size() > 0 ) {
290 fprintf(f,
"%s%s(", is.c_str(), classname.c_str());
293 while (i != fields.end()) {
294 fprintf(f,
"%s ini_%s",
295 convert_type(i->getAccessType()), i->getName().c_str());
297 if ( i != fields.end() ) {
306 write_ctor_dtor_h(f, is, classname);
316 " bool oftype(const char *interface_type) const;\n" 317 " const void * datachunk() const;\n" 318 " unsigned int datasize() const;\n" 319 " const char * type() const;\n" 320 " const char * id() const;\n" 321 " const char * uid() const;\n" 322 " unsigned int serial() const;\n" 323 " unsigned int mem_serial() const;\n" 324 " bool operator== (Interface &comp) const;\n" 325 " const unsigned char * hash() const;\n" 326 " int hash_size() const;\n" 327 " const char * hash_printable() const;\n" 328 " bool is_writer() const;\n" 330 " void set_from_chunk(void *chunk);\n" 332 " virtual fawkes::Message * create_message @ create_message_generic(const char *type) const;\n" 337 " bool has_writer() const;\n" 338 " unsigned int num_readers() const;\n" 340 " bool changed() const;\n" 341 " const fawkes::Time * timestamp() const;\n" 342 " void set_auto_timestamping(bool enabled);\n" 343 " void set_timestamp(const fawkes::Time *t);\n" 344 " void set_clock(fawkes::Clock *clock);\n" 346 " unsigned int msgq_enqueue_copy(Message *message);\n" 347 " void msgq_remove(Message *message);\n" 348 " void msgq_remove(unsigned int message_id);\n" 349 " unsigned int msgq_size();\n" 350 " void msgq_flush();\n" 351 " void msgq_lock();\n" 352 " bool msgq_try_lock();\n" 353 " void msgq_unlock();\n" 354 " void msgq_pop();\n" 355 " fawkes::Message * msgq_first @ msgq_first_generic();\n" 356 " bool msgq_empty();\n" 369 " unsigned int id() const;\n" 371 " unsigned int sender_id() const;\n" 372 " const char * sender_thread_name() const;\n" 373 " Interface * interface() const;\n" 374 " const char * type() const;\n" 376 " const void * datachunk() const;\n" 377 " unsigned int datasize() const;\n" 379 " void set_from_chunk(const void *chunk);\n" 381 " /* from RefCount */\n" 384 " unsigned int refcount();\n" 399 "assert(fawkes.Interface.msgq_first)\n" 400 "assert(fawkes.Interface.msgq_enqueue)\n" 401 "assert(fawkes.Interface.create_message)\n\n" 402 "fawkes.%s.msgq_first = fawkes.Interface.msgq_first\n" 403 "fawkes.%s.msgq_enqueue = fawkes.Interface.msgq_enqueue\n" 404 "fawkes.%s.create_message = fawkes.Interface.create_message\n" 406 classname.c_str(), classname.c_str(), classname.c_str());
416 std::vector<InterfaceField> fields)
418 for (vector<InterfaceField>::iterator i = fields.begin(); i != fields.end(); ++i) {
420 if ( (i->getLengthValue() > 0) && (i->getType() !=
"string" ) ) {
422 "%s%s %s%s(int index);\n",
424 (i->getType() ==
"byte") ?
"unsigned int" : convert_type(i->getPlainAccessType()),
425 ( ((*i).getType() ==
"bool" ) ?
"is_" :
""),
426 (*i).getName().c_str());
429 "%svoid set_%s(unsigned int index, const %s new_%s);\n",
430 is.c_str(), (*i).getName().c_str(),
431 convert_type(i->getPlainAccessType()), i->getName().c_str());
435 is.c_str(), convert_type(i->getAccessType()),
436 ( ((*i).getType() ==
"bool" ) ?
"is_" :
""),
437 (*i).getName().c_str());
440 "%svoid set_%s(const %s new_%s);\n",
441 is.c_str(), (*i).getName().c_str(),
442 convert_type(i->getAccessType()), i->getName().c_str());
445 "%sint maxlenof_%s() const;\n",
446 is.c_str(), (*i).getName().c_str()
460 std::vector<InterfaceField> fields,
461 std::vector<InterfacePseudoMap> pseudo_maps)
463 write_methods_h(f, is, fields);
465 for (vector<InterfacePseudoMap>::iterator i = pseudo_maps.begin(); i != pseudo_maps.end(); ++i) {
467 "%s%s %s(%s key) const;\n" 468 "%svoid set_%s(const %s key, const %s new_value);\n",
469 is.c_str(), convert_type(i->getType()),
470 (*i).getName().c_str(), convert_type(i->getKeyType()),
471 is.c_str(), (*i).getName().c_str(),
472 convert_type(i->getKeyType()), convert_type(i->getType()));
484 "$#include <interfaces/%s>\n" 485 "$#include <utils/time/time.h>\n" 486 "$#include <utils/time/clock.h>\n" 487 "$using namespace fawkes;\n" 488 "namespace fawkes {\n" 489 "class %s : public Interface\n" 494 write_constants_h(f);
497 write_methods_h(f,
" ", data_fields, pseudo_maps);
498 write_superclass_h(f);
499 fprintf(f,
"\n};\n\n");
500 write_lua_code(f, class_name);
511 struct tm timestruct;
512 time_t t = time(NULL);
513 localtime_r(&t, ×truct);
514 asctime_r(×truct, timestring);
515 gendate = timestring;
519 toluaf = fopen(
string(dir + filename_tolua).c_str(),
"w");
521 if ( toluaf == NULL ) {
522 printf(
"Cannot open tolua file %s%s\n", dir.c_str(), filename_tolua.c_str());
525 write_toluaf(toluaf);
~ToLuaInterfaceGenerator()
Destructor.
void write_toluaf(FILE *f)
Write h file.
void write_superclass_h(FILE *f)
Write superclass methods.
void write_message_ctor_dtor_h(FILE *f, std::string is, std::string classname, std::vector< InterfaceField > fields)
Write constructor and destructor for message to h file.
void write_methods_h(FILE *f, std::string is, std::vector< InterfaceField > fields)
Write methods to h file.
void write_constants_h(FILE *f)
Write constants to h file.
const char * convert_type(std::string c_type)
Convert C type to Lua type.
void write_messages_h(FILE *f)
Write messages to h file.
void write_message_superclass_h(FILE *f)
Write superclass methods.
void write_header(FILE *f, std::string filename)
Write header to file.
void generate()
Generator cpp and h files.
ToLuaInterfaceGenerator(std::string directory, std::string interface_name, std::string config_basename, std::string author, std::string year, std::string creation_date, std::string data_comment, const unsigned char *hash, size_t hash_size, const std::vector< InterfaceConstant > &constants, const std::vector< InterfaceEnumConstant > &enum_constants, const std::vector< InterfaceField > &data_fields, const std::vector< InterfacePseudoMap > &pseudo_maps, const std::vector< InterfaceMessage > &messages)
Constructor.
void write_ctor_dtor_h(FILE *f, std::string is, std::string classname)
Write constructor and destructor to h file.
void write_lua_code(FILE *f, std::string classname)
Write additional Lua code to file.