3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * Description: See Type.hh
38 #include "mem/slicc/symbols/Type.hh"
39 #include "mem/slicc/generator/fileio.hh"
40 #include "mem/gems_common/Map.hh"
41 #include "mem/slicc/symbols/StateMachine.hh"
43 Type::Type(string id
, const Location
& location
,
44 const Map
<string
, string
>& pairs
,
45 StateMachine
* machine_ptr
)
46 : Symbol(id
, location
, pairs
)
48 if (machine_ptr
== NULL
) {
50 } else if (isExternal() || isPrimitive()) {
51 if (existPair("external_name")) {
52 m_c_id
= lookupPair("external_name");
57 m_c_id
= machine_ptr
->toString() + "_" + id
; // Append with machine name
60 if(existPair("desc")){
61 m_desc
= lookupPair("desc");
63 m_desc
= "No description avaliable";
66 // check for interface that this Type implements
67 if(existPair("interface")) {
68 string interface
= lookupPair("interface");
69 if(interface
== "Message" || interface
== "NetworkMessage") {
70 addPair("message", "yes");
72 if(interface
== "NetworkMessage") {
73 addPair("networkmessage", "yes");
77 // FIXME - all of the following id comparisons are fragile hacks
78 if ((getIdent() == "CacheMemory") || (getIdent() == "NewCacheMemory") ||
79 (getIdent() == "TLCCacheMemory") || (getIdent() == "DNUCACacheMemory") ||
80 (getIdent() == "DNUCABankCacheMemory") || (getIdent() == "L2BankCacheMemory") ||
81 (getIdent() == "CompressedCacheMemory") || (getIdent() == "PrefetchCacheMemory")) {
82 addPair("cache", "yes");
85 if ((getIdent() == "TBETable") || (getIdent() == "DNUCATBETable") || (getIdent() == "DNUCAStopTable")) {
86 addPair("tbe", "yes");
89 if ((getIdent() == "NewTBETable")) {
90 addPair("newtbe", "yes");
93 if ((getIdent() == "TimerTable")) {
94 addPair("timer", "yes");
97 if ((getIdent() == "DirectoryMemory")) {
98 addPair("dir", "yes");
101 if ((getIdent() == "PersistentTable")) {
102 addPair("persistent", "yes");
105 if ((getIdent() == "Prefetcher")) {
106 addPair("prefetcher", "yes");
109 if ((getIdent() == "DNUCA_Movement")) {
110 addPair("mover", "yes");
113 if (id
== "MachineType") {
114 m_isMachineType
= true;
116 m_isMachineType
= false;
120 // Return false on error
121 bool Type::dataMemberAdd(string id
, Type
* type_ptr
, Map
<string
, string
>& pairs
,
124 if (dataMemberExist(id
)) {
125 return false; // Error
127 m_data_member_map
.add(id
, type_ptr
);
128 m_data_member_ident_vec
.insertAtBottom(id
);
129 m_data_member_type_vec
.insertAtBottom(type_ptr
);
130 m_data_member_pairs_vec
.insertAtBottom(pairs
);
131 m_data_member_init_code_vec
.insertAtBottom(init_code
);
137 string
Type::methodId(string name
,
138 const Vector
<Type
*>& param_type_vec
)
140 string paramStr
= "";
141 for (int i
= 0; i
< param_type_vec
.size(); i
++) {
142 paramStr
+= "_"+param_type_vec
[i
]->cIdent();
144 return name
+paramStr
;
147 bool Type::methodAdd(string name
,
148 Type
* return_type_ptr
,
149 const Vector
<Type
*>& param_type_vec
)
151 string id
= methodId(name
, param_type_vec
);
152 if (methodExist(id
)) {
153 return false; // Error
155 m_method_return_type_map
.add(id
, return_type_ptr
);
156 m_method_param_type_map
.add(id
, param_type_vec
);
161 bool Type::enumAdd(string id
, Map
<string
, string
> pairs_map
)
166 m_enum_map
.add(id
, true);
167 m_enum_vec
.insertAtBottom(id
);
168 m_enum_pairs
.insertAtBottom(pairs_map
);
171 if (!existPair("default")) {
172 addPair("default", cIdent()+"_NUM");
179 void Type::writeCFiles(string path
)
183 } else if (isEnumeration()) {
186 } else { // User defined structs and messages
192 void Type::printTypeH(string path
) const
195 int size
= m_data_member_type_vec
.size();
196 string type_name
= cIdent(); // Identifier for the type in C
199 out
<< "/** \\file " << type_name
<< ".hh" << endl
;
200 out
<< " * " << endl
;
201 out
<< " * Auto generated C++ code started by "<<__FILE__
<<":"<<__LINE__
<< endl
;
202 out
<< " */" << endl
;
204 out
<< "#ifndef " << type_name
<< "_H" << endl
;
205 out
<< "#define " << type_name
<< "_H" << endl
;
208 // Include all of the #includes needed
209 out
<< "#include \"mem/ruby/common/Global.hh\"" << endl
;
210 out
<< "#include \"mem/gems_common/Allocator.hh\"" << endl
;
211 for (int i
=0; i
< size
; i
++) {
212 Type
* type
= m_data_member_type_vec
[i
];
213 if (!type
->isPrimitive()) {
214 out
<< "#include \"mem/protocol/" << type
->cIdent() << ".hh" << "\"" << endl
;
217 string interface
= "";
218 if(existPair("interface")) {
219 interface
= lookupPair("interface");
220 out
<< "#include \"mem/protocol/" << interface
<< ".hh\"" << endl
;
224 out
<< "class " << type_name
;
226 if(interface
!= "") {
227 out
<< " : public " << interface
;
231 out
<< "public:" << endl
;
233 // ******** Default constructor ********
235 out
<< " " << type_name
<< "() " << endl
;
237 // Call superclass constructor
238 if (interface
!= "") {
239 out
<< " : " << interface
<< "()" << endl
;
245 for (int i
=0; i
< size
; i
++) {
247 Type
* type_ptr
= m_data_member_type_vec
[i
];
248 string id
= m_data_member_ident_vec
[i
];
249 if (m_data_member_pairs_vec
[i
].exist("default")) {
250 // look for default value
251 string default_value
= m_data_member_pairs_vec
[i
].lookup("default");
252 out
<< " m_" << id
<< " = " << default_value
<< "; // default for this field " << endl
;
253 } else if (type_ptr
->hasDefault()) {
254 // Look for the type default
255 string default_value
= type_ptr
->getDefault();
256 out
<< " m_" << id
<< " = " << default_value
<< "; // default value of " << type_ptr
->cIdent() << endl
;
258 out
<< " // m_" << id
<< " has no default" << endl
;
261 } // end of if(!isGlobal())
264 // ******** Default destructor ********
266 out
<< "~" << type_name
<< "() { };" << endl
;
268 // ******** Full init constructor ********
270 out
<< " " << type_name
<< "(";
272 for (int i
=0; i
< size
; i
++) {
276 Type
* type
= m_data_member_type_vec
[i
];
277 string id
= m_data_member_ident_vec
[i
];
278 out
<< "const " << type
->cIdent() << "& local_" << id
;
282 out
<< ", const unsigned local_proc_id" << flush
;
287 // Call superclass constructor
288 if (interface
!= "") {
289 out
<< " : " << interface
<< "()" << endl
;
293 for (int i
=0; i
< size
; i
++) {
294 Type
* type_ptr
= m_data_member_type_vec
[i
];
295 string id
= m_data_member_ident_vec
[i
];
296 out
<< " m_" << id
<< " = local_" << id
<< ";" << endl
;
297 if (m_data_member_pairs_vec
[i
].exist("nextLineCallHack")) {
298 string next_line_value
= m_data_member_pairs_vec
[i
].lookup("nextLineCallHack");
299 out
<< " m_" << id
<< next_line_value
<< ";" << endl
;
303 out
<< " proc_id = local_proc_id;" << endl
<< flush
;
306 } // end of if(!isGlobal())
308 // create a static factory method
309 if (interface
!= "") {
310 out
<< " static " << interface
<< "* create() {" << endl
;
311 out
<< " return new " << type_name
<< "(); " << endl
;
316 //******** Partial init constructor ********
317 //** Constructor needs only the first n-1 data members for init
318 //** HACK to create objects with partially specified data members
319 //** Need to get rid of this and use hierarchy instead
320 // if(! isGlobal()) {
321 // out << " " << type_name << "(";
323 // for (int i=0; i < size-1; i++) {
327 // Type* type = m_data_member_type_vec[i];
328 // string id = m_data_member_ident_vec[i];
329 // out << "const " << type->cIdent() << "& local_" << id;
331 // out << ")" << endl;
333 // // Call superclass constructor
334 // if (interface != "") {
335 // out << " : " << interface << "()" << endl;
338 // out << " {" << endl;
339 // for (int i=0; i < size-1; i++) {
340 // Type* type_ptr = m_data_member_type_vec[i];
341 // string id = m_data_member_ident_vec[i];
342 // out << " m_" << id << " = local_" << id << ";" << endl;
343 // if (m_data_member_pairs_vec[i].exist("nextLineCallHack")) {
344 // string next_line_value = m_data_member_pairs_vec[i].lookup("nextLineCallHack");
345 // out << " m_" << id << next_line_value << ";" << endl;
349 // out << " }" << endl;
350 // } // end of if(!isGlobal())
352 // ******** Message member functions ********
353 // FIXME: those should be moved into slicc file, slicc should support more of
354 // the c++ class inheritance
357 out
<< " Message* clone() const { checkAllocator(); return s_allocator_ptr->allocate(*this); }" << endl
;
358 out
<< " void destroy() { checkAllocator(); s_allocator_ptr->deallocate(this); }" << endl
;
359 out
<< " static Allocator<" << type_name
<< ">* s_allocator_ptr;" << endl
;
360 out
<< " static void checkAllocator() { if (s_allocator_ptr == NULL) { s_allocator_ptr = new Allocator<" << type_name
<< ">; }}" << endl
;
364 // const Get methods for each field
365 out
<< " // Const accessors methods for each field" << endl
;
366 for (int i
=0; i
< size
; i
++) {
367 Type
* type_ptr
= m_data_member_type_vec
[i
];
368 string type
= type_ptr
->cIdent();
369 string id
= m_data_member_ident_vec
[i
];
370 out
<< "/** \\brief Const accessor method for " << id
<< " field." << endl
;
371 out
<< " * \\return " << id
<< " field" << endl
;
372 out
<< " */" << endl
;
373 out
<< " const " << type
<< "& get" << id
374 << "() const { return m_" << id
<< "; }" << endl
;
379 // Non-const Get methods for each field
380 out
<< " // Non const Accessors methods for each field" << endl
;
381 for (int i
=0; i
< size
; i
++) {
382 Type
* type_ptr
= m_data_member_type_vec
[i
];
383 string type
= type_ptr
->cIdent();
384 string id
= m_data_member_ident_vec
[i
];
385 out
<< "/** \\brief Non-const accessor method for " << id
<< " field." << endl
;
386 out
<< " * \\return " << id
<< " field" << endl
;
387 out
<< " */" << endl
;
388 out
<< " " << type
<< "& get" << id
389 << "() { return m_" << id
<< "; }" << endl
;
394 // Set methods for each field
395 out
<< " // Mutator methods for each field" << endl
;
396 for (int i
=0; i
< size
; i
++) {
397 Type
* type_ptr
= m_data_member_type_vec
[i
];
398 string type
= type_ptr
->cIdent();
399 string id
= m_data_member_ident_vec
[i
];
400 out
<< "/** \\brief Mutator method for " << id
<< " field */" << endl
;
401 out
<< " void set" << id
<< "(const " << type
<< "& local_"
402 << id
<< ") { m_" << id
<< " = local_" << id
<< "; }" << endl
;
406 } // end of if(!isGlobal())
408 out
<< " void print(ostream& out) const;" << endl
;
409 out
<< "//private:" << endl
;
411 // Data members for each field
412 for (int i
=0; i
< size
; i
++) {
413 if (!m_data_member_pairs_vec
[i
].exist("abstract")) {
416 if(isGlobal()) out
<< "static const ";
418 Type
* type
= m_data_member_type_vec
[i
];
419 string id
= m_data_member_ident_vec
[i
];
420 out
<< type
->cIdent() << " m_" << id
;
423 string
* init_code
= m_data_member_init_code_vec
[i
];
425 // only global structure can have init value here
427 out
<< " = " << *init_code
<< " ";
430 if (m_data_member_pairs_vec
[i
].exist("desc")) {
431 string desc
= m_data_member_pairs_vec
[i
].lookup("desc");
432 out
<< " /**< " << desc
<< "*/";
439 out
<< " unsigned proc_id;" << endl
<< flush
;
442 out
<< "};" << endl
; // End class
444 out
<< "// Output operator declaration" << endl
;
445 out
<< "ostream& operator<<(ostream& out, const " << type_name
<< "& obj);" << endl
;
447 out
<< "// Output operator definition" << endl
;
448 out
<< "extern inline" << endl
;
449 out
<< "ostream& operator<<(ostream& out, const " << type_name
<< "& obj)" << endl
;
451 out
<< " obj.print(out);" << endl
;
452 out
<< " out << flush;" << endl
;
453 out
<< " return out;" << endl
;
456 out
<< "#endif // " << type_name
<< "_H" << endl
;
459 conditionally_write_file(path
+ type_name
+ ".hh", out
);
462 void Type::printTypeC(string path
) const
465 int size
= m_data_member_type_vec
.size();
466 string type_name
= cIdent(); // Identifier for the type in C
469 out
<< "/** \\file " << type_name
<< ".cc" << endl
;
470 out
<< " * " << endl
;
471 out
<< " * Auto generated C++ code started by "<<__FILE__
<<":"<<__LINE__
<< endl
;
472 out
<< " */" << endl
;
474 out
<< "#include \"mem/protocol/" << type_name
<< ".hh\"" << endl
;
477 out
<< "Allocator<" << type_name
<< ">* " << type_name
<< "::s_allocator_ptr = NULL;" << endl
;
479 out
<< "/** \\brief Print the state of this object */" << endl
;
480 out
<< "void " << type_name
<< "::print(ostream& out) const" << endl
;
482 out
<< " out << \"[" << type_name
<< ": \";" << endl
;
485 for (int i
=0; i
< size
; i
++) {
486 string id
= m_data_member_ident_vec
[i
];
487 out
<< " out << \"" << id
<< "=\" << m_" << id
<< " << \" \";" << endl
;
491 out
<< " out << \"" << "Time" << "=\" << getTime()" << " << \" \";" << endl
;
495 out
<< " out << \"]\";" << endl
;
499 conditionally_write_file(path
+ type_name
+ ".cc", out
);
502 void Type::printEnumH(string path
) const
505 int size
= m_enum_vec
.size();
506 string type_name
= cIdent(); // Identifier for the type in C
507 string type_desc
= desc();
510 out
<< "/** \\file " << type_name
<< ".hh" << endl
;
511 out
<< " * " << endl
;
512 out
<< " * Auto generated C++ code started by "<<__FILE__
<<":"<<__LINE__
<< endl
;
513 out
<< " */" << endl
;
515 out
<< "#ifndef " << type_name
<< "_H" << endl
;
516 out
<< "#define " << type_name
<< "_H" << endl
;
518 // Include all of the #includes needed
519 out
<< "#include \"mem/ruby/common/Global.hh\"" << endl
;
523 out
<< "/** \\enum " << type_name
<< endl
;
524 out
<< " * \\brief " << type_desc
<< endl
;
525 out
<< " */" << endl
;
526 out
<< "enum " << type_name
<< " {" << endl
;
528 out
<< " " << type_name
<< "_FIRST," << endl
;
531 for(int i
= 0; i
< size
; i
++ ) {
532 string id
= m_enum_vec
[i
];
534 if(m_enum_pairs
[i
].exist("desc")){
535 description
= m_enum_pairs
[i
].lookup("desc");
537 description
= "No description avaliable";
540 out
<< " " << type_name
<< "_" << id
<< " = " << type_name
<< "_FIRST, /**< " << description
<< " */" << endl
;
543 out
<< " " << type_name
<< "_" << id
<< ", /**< " << description
<< " */" << endl
;
546 out
<< " " << type_name
<< "_NUM" << endl
;
549 // Code to convert from a string to the enumeration
550 out
<< type_name
<< " string_to_" << type_name
<< "(const string& str);" << endl
;
552 // Code to convert state to a string
553 out
<< "string " << type_name
<< "_to_string(const " << type_name
<< "& obj);" << endl
;
555 // Code to increment an enumeration type
556 out
<< type_name
<< " &operator++( " << type_name
<< " &e);" << endl
;
558 // MachineType hack used to set the base component id for each Machine
559 if (m_isMachineType
) {
560 out
<< "int " << type_name
<< "_base_level(const " << type_name
<< "& obj);" << endl
;
561 out
<< "MachineType " << type_name
<< "_from_base_level(int);" << endl
;
562 out
<< "int " << type_name
<< "_base_number(const " << type_name
<< "& obj);" << endl
;
563 out
<< "int " << type_name
<< "_base_count(const " << type_name
<< "& obj);" << endl
;
564 // out << "int " << type_name << "_chip_count(const " << type_name << "& obj, int chipID);" << endl;
566 for(int i
= 0; i
< size
; i
++ ) {
567 string id
= m_enum_vec
[i
];
568 out
<< "#define MACHINETYPE_" << id
<< " 1" << endl
;
574 out
<< "ostream& operator<<(ostream& out, const " << type_name
<< "& obj);" << endl
;
576 out
<< "#endif // " << type_name
<< "_H" << endl
;
579 conditionally_write_file(path
+ type_name
+ ".hh", out
);
582 void Type::printEnumC(string path
) const
585 int size
= m_enum_vec
.size();
586 string type_name
= cIdent(); // Identifier for the type in C
589 out
<< "/** \\file " << type_name
<< ".hh" << endl
;
590 out
<< " * " << endl
;
591 out
<< " * Auto generated C++ code started by "<<__FILE__
<<":"<<__LINE__
<< endl
;
592 out
<< " */" << endl
;
595 out
<< "#include \"mem/protocol/" << type_name
<< ".hh\"" << endl
;
596 if (m_isMachineType
) {
597 out
<< "#include \"mem/protocol/ControllerFactory.hh\"" << endl
;
598 for( int i
= 0; i
<size
; i
++ ) {
599 out
<< "#include \"mem/protocol/" << m_enum_vec
[i
] << "_Controller.hh\"" << endl
;
605 // Code for output operator
606 out
<< "ostream& operator<<(ostream& out, const " << type_name
<< "& obj)" << endl
;
608 out
<< " out << " << type_name
<< "_to_string(obj);" << endl
;
609 out
<< " out << flush;" << endl
;
610 out
<< " return out;" << endl
;
613 // Code to convert state to a string
615 out
<< "string " << type_name
<< "_to_string(const " << type_name
<< "& obj)" << endl
;
617 out
<< " switch(obj) {" << endl
;
620 for( int i
= 0; i
<size
; i
++ ) {
621 out
<< " case " << type_name
<< "_" << m_enum_vec
[i
] << ":" << endl
;
622 out
<< " return \"" << m_enum_vec
[i
] << "\";" << endl
;
626 out
<< " default:" << endl
;
627 out
<< " ERROR_MSG(\"Invalid range for type " << type_name
<< "\");" << endl
;
628 out
<< " return \"\";" << endl
;
632 // Code to convert from a string to the enumeration
634 out
<< type_name
<< " string_to_" << type_name
<< "(const string& str)" << endl
;
636 out
<< " if (false) {" << endl
;
639 for( int i
= 0; i
<size
; i
++ ) {
640 out
<< " } else if (str == \"" << m_enum_vec
[i
] << "\") {" << endl
;
641 out
<< " return " << type_name
<< "_" << m_enum_vec
[i
] << ";" << endl
;
644 out
<< " } else {" << endl
;
645 out
<< " WARN_EXPR(str);" << endl
;
646 out
<< " ERROR_MSG(\"Invalid string conversion for type " << type_name
<< "\");" << endl
;
650 // Code to increment an enumeration type
652 out
<< type_name
<< "& operator++( " << type_name
<< "& e) {" << endl
;
653 out
<< " assert(e < " << type_name
<< "_NUM);" << endl
;
654 out
<< " return e = " << type_name
<< "(e+1);" << endl
;
657 // MachineType hack used to set the base level and number of components for each Machine
658 if (m_isMachineType
) {
660 out
<< "/** \\brief returns the base vector index for each machine type to be used by NetDest " << endl
;
661 out
<< " * " << endl
;
662 out
<< " * \\return the base vector index for each machine type to be used by NetDest" << endl
;
663 out
<< " * \\see NetDest.hh" << endl
;
664 out
<< " */" << endl
;
665 out
<< "int " << type_name
<< "_base_level(const " << type_name
<< "& obj)" << endl
;
667 out
<< " switch(obj) {" << endl
;
670 Vector
< string
> MachineNames
;
671 for( int i
= 0; i
<size
; i
++ ) {
672 out
<< " case " << type_name
<< "_" << m_enum_vec
[i
] << ":" << endl
;
673 out
<< " return " << MachineNames
.size() << ";" << endl
;
674 MachineNames
.insertAtBottom(m_enum_vec
[i
]);
678 out
<< " case " << type_name
<< "_NUM:" << endl
;
679 out
<< " return " << MachineNames
.size() << ";" << endl
;
682 out
<< " default:" << endl
;
683 out
<< " ERROR_MSG(\"Invalid range for type " << type_name
<< "\");" << endl
;
684 out
<< " return -1;" << endl
;
688 out
<< "/** \\brief returns the machine type for each base vector index used by NetDest" << endl
;
689 out
<< " * " << endl
;
690 out
<< " * \\return the MachineTYpe" << endl
;
691 out
<< " */" << endl
;
692 out
<< "MachineType " << type_name
<< "_from_base_level(int type)" << endl
;
694 out
<< " switch(type) {" << endl
;
697 MachineNames
.clear();
698 for( int i
= 0; i
<size
; i
++ ) {
699 out
<< " case " << MachineNames
.size() << ":" << endl
;
700 out
<< " return " << type_name
<< "_" << m_enum_vec
[i
] << ";" << endl
;
701 MachineNames
.insertAtBottom(m_enum_vec
[i
]);
705 out
<< " default:" << endl
;
706 out
<< " ERROR_MSG(\"Invalid range for type " << type_name
<< "\");" << endl
;
707 out
<< " return MachineType_NUM;" << endl
;
713 out
<< "/** \\brief The return value indicates the number of components created" << endl
;
714 out
<< " * before a particular machine's components" << endl
;
715 out
<< " * " << endl
;
716 out
<< " * \\return the base number of components for each machine" << endl
;
717 out
<< " */" << endl
;
718 out
<< "int " << type_name
<< "_base_number(const " << type_name
<< "& obj)" << endl
;
720 out
<< " switch(obj) {" << endl
;
723 MachineNames
.clear();
724 for( int i
= 0; i
<size
; i
++ ) {
725 out
<< " case " << type_name
<< "_" << m_enum_vec
[i
] << ":" << endl
;
727 for ( int m
= 0; m
<MachineNames
.size(); m
++) {
728 out
<< "+ " << MachineNames
[m
] << "_Controller::getNumControllers()";
731 MachineNames
.insertAtBottom(m_enum_vec
[i
]);
735 out
<< " case " << type_name
<< "_NUM:" << endl
;
737 for ( int m
= 0; m
<MachineNames
.size(); m
++) {
738 out
<< "+ " << MachineNames
[m
] << "_Controller::getNumControllers()";
743 out
<< " default:" << endl
;
744 out
<< " ERROR_MSG(\"Invalid range for type " << type_name
<< "\");" << endl
;
745 out
<< " return -1;" << endl
;
751 out
<< "/** \\brief returns the total number of components for each machine" << endl
;
752 out
<< " * \\return the total number of components for each machine" << endl
;
753 out
<< " */" << endl
;
754 out
<< "int " << type_name
<< "_base_count(const " << type_name
<< "& obj)" << endl
;
756 out
<< " switch(obj) {" << endl
;
759 for( int i
= 0; i
<size
; i
++ ) {
760 out
<< " case " << type_name
<< "_" << m_enum_vec
[i
] << ":" << endl
;
761 out
<< " return " << m_enum_vec
[i
] << "_Controller::getNumControllers();" << endl
;
765 out
<< " case " << type_name
<< "_NUM:" << endl
;
767 out
<< " default:" << endl
;
768 out
<< " ERROR_MSG(\"Invalid range for type " << type_name
<< "\");" << endl
;
769 out
<< " return -1;" << endl
;
778 conditionally_write_file(path
+ type_name
+ ".cc", out
);