00001 /*! 00002 \file 00003 \brief Type informations. 00004 \author jaz 00005 */ 00006 00007 #include <lestes/lang/cplus/sem/ss_type.g.hh> 00008 #include <lestes/lang/cplus/sem/ss_type_builtin.g.hh> 00009 #include <lestes/md/types/tm_data_type.g.hh> 00010 #include <lestes/md/types/num_range.g.hh> 00011 #include <lestes/md/types/num_range_getter.g.hh> 00012 #include <lestes/md/types/type_info.g.hh> 00013 #include <lestes/md/types/ss_type2tm_type.g.hh> 00014 00015 #include <regex.h> 00016 00017 package(lestes); 00018 package(md); 00019 package(types); 00020 00021 using namespace ::lestes::md::types; 00022 using namespace ::lestes::lang::cplus::sem; 00023 00024 ptr<type_info> type_info::instance() { 00025 if ( !singleton_instance_get() ) { 00026 singleton_instance_set(type_info::create()); 00027 } 00028 return singleton_instance_get(); 00029 } 00030 00031 /*! 00032 \brief Returns ss_type corresponding to ptrdiff_t type. 00033 */ 00034 ptr<ss_type> type_info::get_ptrdiff_t_type() { 00035 return ss_type_sint::instance(); 00036 } 00037 00038 00039 /*! 00040 \brief Returns ss_type corresponding to size_t type. 00041 */ 00042 ptr<ss_type> type_info::get_size_t_type() { 00043 return ss_type_uint::instance(); 00044 } 00045 00046 /*! 00047 \brief Tells whether a value is of given type. 00048 00049 \param The value. 00050 \param The type. 00051 \return True if the value is of the type. False otherwise. 00052 */ 00053 bool type_info::does_value_match_type(ucn_string value, ptr<ss_type> type) { 00054 lassert(type); 00055 00056 //Get target type fro type. 00057 ptr<tm_data_type_base> tm_type = type->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance()); 00058 00059 //Non-basic types are not accepted. 00060 lassert(tm_type->kind_get()==tm_data_type_base::SIMPLE); 00061 00062 //Get range for type. 00063 ptr<num_range> range = num_range_getter::instance()->get_range(tm_type); 00064 lassert(range); 00065 00066 switch ( tm_type->id_get() ) { 00067 case DT_INT_8P : 00068 case DT_INT_8U : 00069 case DT_INT_8S : 00070 case DT_INT_16U : 00071 case DT_INT_16S : 00072 case DT_INT_32U : 00073 case DT_INT_32S :{ 00074 //Get decimal representation. 00075 lstring decimal_value = get_decimal_representation(value,tm_type); 00076 00077 //Check number length. 00078 ulint max_digits = range->digits_get(); 00079 00080 if ( decimal_value.length() > max_digits ) { 00081 //Number is too long. Too many digits. 00082 return false; 00083 } 00084 00085 /* 00086 Check if value is less than maximum value for type. 00087 This can be done as string comparation, because length of the value 00088 is the same or shorter than length of maximum. 00089 */ 00090 if ( decimal_value.length() == max_digits && decimal_value.compare(range->max_get())>0 ) { 00091 //Number is out of range. 00092 return false; 00093 } 00094 00095 //Check number format. 00096 char* pattern = "^[0-9]+$"; 00097 00098 regex_t re; 00099 lassert(regcomp(&re,pattern,REG_EXTENDED|REG_NOSUB)==0); 00100 int status = regexec(&re,decimal_value.c_str(),(size_t)0,NULL,0); 00101 regfree(&re); 00102 00103 return (status==0); 00104 00105 } break; 00106 00107 default: 00108 break; 00109 } 00110 lassert(false); 00111 return false; 00112 } 00113 00114 end_package(types); 00115 end_package(md); 00116 end_package(lestes); 00117
1.5.1-20070107