type_checker.cpp

00001
00002 /***************************************************************************
00003  *  type_checker.cpp - Interface generator type checker
00004  *
00005  *  Generated: Wed Oct 11 15:39:10 2006
00006  *  Copyright  2006  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include <interfaces/generator/type_checker.h>
00024 #include <interfaces/generator/exceptions.h>
00025 #include <core/exception.h>
00026 #include <cstdlib>
00027 #include <climits>
00028 #include <cmath>
00029 
00030 /** @class InterfaceDataTypeChecker <interfaces/generator/type_checker.h>
00031  * Type checker for interface types.
00032  * This classed is used by the generator to decide if a supplied type is
00033  * correct and in the case of constants if the supplied value matches the
00034  * field type.
00035  *
00036  * Valid types are:
00037  * - int
00038  * - long int
00039  * - unsigned int
00040  * - unsigned long int
00041  * - bool
00042  * - float
00043  * - double
00044  * - byte (unsigned 8-bit number)
00045  * - string
00046  */
00047
00048 
00049 /** Check type validity.
00050  * @param type type string to check
00051  * @param enum_constants an optional vector of enumeration constants that are used for
00052  * type validation.
00053  * @return true, if type is valid, false otherwise
00054  */
00055 bool
00056 InterfaceDataTypeChecker::validType(const std::string &type, std::vector<InterfaceEnumConstant> *enum_constants)
00057 {
00058   if (  (type == "int") ||
00059         (type == "long int") ||
00060         (type == "unsigned int") ||
00061         (type == "unsigned long int") ||
00062         (type == "bool") ||
00063         (type == "char") ||
00064         (type == "float") ||
00065         (type == "byte") ||
00066         (type == "string") ||
00067         (type == "double") ) {
00068     return true;
00069   } else if ( enum_constants != NULL ) {
00070     for (std::vector<InterfaceEnumConstant>::iterator i = enum_constants->begin(); i != enum_constants->end(); ++i) {
00071       if ( type == (*i).getName() ) {
00072         return true;
00073       }
00074     }
00075     return false;
00076   } else {
00077     return false;
00078   }
00079 }
00080
00081 
00082 /** Check value validity for given type.
00083  * @param type type if value
00084  * @param value value to check
00085  * @return true, if value is valid for type, false otherwise
00086  */
00087 bool
00088 InterfaceDataTypeChecker::validValue(const std::string &type, const std::string &value)
00089 {
00090   if ( (type == "int") || ( type == "long int")) {
00091     char *endptr;
00092     long int rv = strtol(value.c_str(), &endptr, 11);
00093     if ((rv == LONG_MIN) || (rv == LONG_MAX)) {
00094       throw fawkes::Exception("Could not convert value string '%s' to long int", value.c_str());
00095     }
00096     return ( (endptr != NULL) && (endptr[0] == '\0'));
00097   } else if (type == "unsigned int") {
00098     std::string::size_type notofnumber = value.find_first_not_of("0123456789");
00099     if ( notofnumber != std::string::npos ) {
00100       std::string suffix = value.substr(notofnumber);
00101       if ( (suffix != "U") && (suffix != "u") ) {
00102         return false;
00103       }
00104     }
00105     char *endptr;
00106     long int val = strtol(value.substr(0, notofnumber).c_str(), &endptr, 11);
00107     if ( (endptr == NULL) || (endptr[0] != '\0') ) {
00108       return false;
00109     } else {
00110       return (val >= 0);
00111     }
00112   } else if (type == "unsigned long int") {
00113     std::string::size_type notofnumber = value.find_first_not_of("0123456789");
00114     if ( notofnumber != std::string::npos ) {
00115       std::string suffix = value.substr(notofnumber);
00116       if ( (suffix != "UL") && (suffix != "ul") ) {
00117         return false;
00118       }
00119     }
00120     char *endptr;
00121     long int val = strtol(value.substr(0, notofnumber).c_str(), &endptr, 21);
00122     if ( (endptr == NULL) || (endptr[0] != '\0') ) {
00123       return false;
00124     } else {
00125       return (val >= 0);
00126     }
00127   } else if (type == "byte") {
00128     std::string::size_type notofnumber = value.find_first_not_of("0123456789");
00129     if ( notofnumber != std::string::npos ) {
00130       std::string suffix = value.substr(notofnumber);
00131       if ( (suffix != "U") && (suffix != "u") ) {
00132         return false;
00133       }
00134     }
00135     char *endptr;
00136     long int val = strtol(value.substr(0, notofnumber).c_str(), &endptr, 11);
00137     if ( (endptr == NULL) || (endptr[0] != '\0') ) {
00138       return false;
00139     } else {
00140       return ((val >= 0) && (val <= 255));
00141     }
00142   } else if ( type == "bool" ) {
00143     return ( (value == "true") ||
00144              (value == "false") ||
00145              (value == "yes") ||
00146              (value == "no") ||
00147              (value == "0") ||
00148              (value == "1") );
00149   } else if ( (type == "float") ||
00150               (type == "double") ) {
00151     char *endptr;
00152     float rv = strtod(value.c_str(), &endptr);
00153     if ((rv == HUGE_VAL) || (rv == -HUGE_VAL)) {
00154       throw fawkes::Exception("Could not convert string '%s' to float", value.c_str());
00155     }
00156     return ((endptr != NULL) && (endptr[0] == '\0'));
00157   } else if ( type == "string" ) {
00158     return true;
00159   } else {
00160     return false;
00161   }
00162 }