00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <stdio.h>
00060 #include <cstdlib>
00061 #include <cassert>
00062 #include <ctype.h>
00063
00064 #include "sysc/kernel/sc_externs.h"
00065 #include "sysc/kernel/sc_kernel_ids.h"
00066 #include "sysc/kernel/sc_module.h"
00067 #include "sysc/kernel/sc_object.h"
00068 #include "sysc/kernel/sc_object_manager.h"
00069 #include "sysc/kernel/sc_process_handle.h"
00070 #include "sysc/kernel/sc_simcontext.h"
00071 #include "sysc/utils/sc_hash.h"
00072 #include "sysc/utils/sc_iostream.h"
00073 #include "sysc/utils/sc_list.h"
00074 #include "sysc/utils/sc_mempool.h"
00075
00076 namespace sc_core {
00077
00078 typedef int (*STRCMP)(const void*, const void*);
00079
00080 const char SC_HIERARCHY_CHAR = '.';
00081
00082
00083
00084
00085 bool sc_enable_name_checking = true;
00086
00087
00088
00089
00090
00091
00092
00093
00094 const char*
00095 sc_object::basename() const
00096 {
00097 const char* p = strrchr( m_name, SC_HIERARCHY_CHAR );
00098 return p ? (p + 1) : m_name;
00099 }
00100
00101 void
00102 sc_object::print(::std::ostream& os) const
00103 {
00104 os << name();
00105 }
00106
00107 void
00108 sc_object::dump(::std::ostream& os) const
00109 {
00110 os << "name = " << name() << "\n";
00111 os << "kind = " << kind() << "\n";
00112 }
00113
00114 static int sc_object_num = 0;
00115
00116 static char*
00117 sc_object_newname(char* name)
00118 {
00119 std::sprintf(name, "{%d}", sc_object_num);
00120 sc_object_num++;
00121 return name;
00122 }
00123
00124 void
00125 sc_object::sc_object_init(const char* nm)
00126 {
00127 bool clash;
00128 const char* leafname_p;
00129 char pathname[BUFSIZ];
00130 char pathname_orig[BUFSIZ];
00131 const char* parentname_p;
00132 bool put_in_table;
00133
00134
00135
00136
00137
00138 m_simc = sc_get_curr_simcontext();
00139 m_attr_cltn_p = 0;
00140 sc_object_manager* object_manager = m_simc->get_object_manager();
00141 sc_object* parent_p = object_manager->hierarchy_curr();
00142 if (!parent_p) {
00143 sc_object* proc = (sc_object*)sc_get_current_process_b();
00144 parent_p = proc;
00145 }
00146 m_parent = parent_p;
00147
00148
00149
00150
00151
00152
00153 parentname_p = parent_p ? parent_p->name() : "";
00154 if (nm && nm[0] )
00155 {
00156 leafname_p = nm;
00157 put_in_table = true;
00158 }
00159 else
00160 {
00161 leafname_p = sc_object_newname(pathname_orig);
00162 put_in_table = false;
00163 }
00164 if (parent_p) {
00165 std::sprintf(pathname, "%s%c%s", parentname_p,
00166 SC_HIERARCHY_CHAR, leafname_p
00167 );
00168 } else {
00169 strcpy(pathname, leafname_p);
00170 }
00171
00172
00173
00174 strcpy(pathname_orig, pathname);
00175
00176
00177
00178
00179
00180 clash = false;
00181 while (object_manager->find_object(pathname)) {
00182 clash = true;
00183 leafname_p = sc_gen_unique_name(leafname_p);
00184 if (parent_p) {
00185 std::sprintf(pathname, "%s%c%s", parentname_p,
00186 SC_HIERARCHY_CHAR, leafname_p
00187 );
00188 } else {
00189 strcpy(pathname, leafname_p);
00190 }
00191 }
00192 if (clash) {
00193 std::string message = pathname_orig;
00194 message += ". Latter declaration will be renamed to ";
00195 message += pathname;
00196 SC_REPORT_WARNING( SC_ID_OBJECT_EXISTS_, message.c_str());
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 char* ptr = new char[strlen( pathname ) + 2];
00207 ptr[0] = put_in_table;
00208 m_name = ptr + 1;
00209 strcpy(m_name, pathname);
00210
00211 if (put_in_table) {
00212 object_manager->insert_object(m_name, this);
00213 sc_module* curr_module = m_simc->hierarchy_curr();
00214 if( curr_module != 0 ) {
00215 curr_module->add_child_object( this );
00216 } else {
00217 sc_process_b* curr_proc = sc_get_current_process_b();
00218 if (curr_proc) {
00219 curr_proc->add_child_object( this );
00220 } else {
00221 m_simc->add_child_object( this );
00222 }
00223 }
00224 }
00225 }
00226
00227 sc_object::sc_object() : m_parent(0)
00228 {
00229 sc_object_init( sc_gen_unique_name("object") );
00230 }
00231
00232 static bool
00233 object_name_illegal_char(char ch)
00234 {
00235 return (ch == SC_HIERARCHY_CHAR) || isspace(ch);
00236 }
00237
00238 sc_object::sc_object(const char* nm) : m_parent(0)
00239 {
00240 int namebuf_alloc = 0;
00241 char* namebuf = 0;
00242 const char* p;
00243
00244
00245 if ( !nm || strlen(nm) == 0 )
00246 nm = sc_gen_unique_name("object");
00247 p = nm;
00248
00249 if (nm && sc_enable_name_checking) {
00250 namebuf_alloc = 1 + strlen(nm);
00251 namebuf = (char*) sc_mempool::allocate(namebuf_alloc);
00252 char* q = namebuf;
00253 const char* r = nm;
00254 bool has_illegal_char = false;
00255 while (*r) {
00256 if (object_name_illegal_char(*r)) {
00257 has_illegal_char = true;
00258 *q = '_';
00259 } else {
00260 *q = *r;
00261 }
00262 r++;
00263 q++;
00264 }
00265 *q = '\0';
00266 p = namebuf;
00267 if (has_illegal_char)
00268 {
00269 std::string message = nm;
00270 message += " substituted by ";
00271 message += namebuf;
00272 SC_REPORT_WARNING( SC_ID_ILLEGAL_CHARACTERS_, message.c_str());
00273 }
00274 }
00275 sc_object_init(p);
00276 sc_mempool::release( namebuf, namebuf_alloc );
00277 }
00278
00279 sc_object::~sc_object()
00280 {
00281 if (m_name[-1] && m_simc) {
00282 sc_object_manager* object_manager = m_simc->get_object_manager();
00283 object_manager->remove_object(m_name);
00284
00285 sc_module* parent_mod = DCAST<sc_module*>(m_parent);
00286 if (parent_mod) {
00287 parent_mod->remove_child_object( this );
00288 } else {
00289 sc_process_b* parent_proc = DCAST<sc_process_b*>(m_parent);
00290 if (parent_proc) {
00291 parent_proc->remove_child_object( this );
00292 } else {
00293 m_simc->remove_child_object( this );
00294 }
00295 }
00296 }
00297 delete [] (m_name-1);
00298 if ( m_attr_cltn_p ) delete m_attr_cltn_p;
00299 }
00300
00301 void
00302 sc_object::trace( sc_trace_file * ) const
00303 {
00304
00305 }
00306
00307
00308
00309
00310 bool
00311 sc_object::add_attribute( sc_attr_base& attribute_ )
00312 {
00313 if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00314 return ( m_attr_cltn_p->push_back( &attribute_ ) );
00315 }
00316
00317
00318
00319
00320 sc_attr_base*
00321 sc_object::get_attribute( const std::string& name_ )
00322 {
00323 if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00324 return ( (*m_attr_cltn_p)[name_] );
00325 }
00326
00327 const sc_attr_base*
00328 sc_object::get_attribute( const std::string& name_ ) const
00329 {
00330 if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00331 return ( (*m_attr_cltn_p)[name_] );
00332 }
00333
00334
00335
00336
00337 sc_attr_base*
00338 sc_object::remove_attribute( const std::string& name_ )
00339 {
00340 if ( m_attr_cltn_p )
00341 return ( m_attr_cltn_p->remove( name_ ) );
00342 else
00343 return 0;
00344 }
00345
00346
00347
00348
00349 void
00350 sc_object::remove_all_attributes()
00351 {
00352 if ( m_attr_cltn_p )
00353 m_attr_cltn_p->remove_all();
00354 }
00355
00356
00357
00358
00359 int
00360 sc_object::num_attributes() const
00361 {
00362 if ( m_attr_cltn_p )
00363 return ( m_attr_cltn_p->size() );
00364 else
00365 return 0;
00366 }
00367
00368
00369
00370
00371 sc_attr_cltn&
00372 sc_object::attr_cltn()
00373 {
00374 if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00375 return *m_attr_cltn_p;
00376 }
00377
00378 const sc_attr_cltn&
00379 sc_object::attr_cltn() const
00380 {
00381 if ( !m_attr_cltn_p ) m_attr_cltn_p = new sc_attr_cltn;
00382 return *m_attr_cltn_p;
00383 }
00384
00385 }