Merge branch 'precalc_last-2' into precalc_last-uf
[gnucap-felix.git] / modelgen / mg_out_h.cc
blobbffd57cbb999916c6ee4c0ca94e0197bcf6e44ab
1 /*$Id: mg_out_h.cc,v 1.5 2010-07-14 15:17:30 felix Exp $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
22 //testing=script 2006.11.01
23 #include "mg_out.h"
24 /*--------------------------------------------------------------------------*/
25 static void make_header(std::ofstream& out, const File& in,
26 const std::string& dump_name)
28 out << in.head()
29 << "/* This file is automatically generated. DO NOT EDIT */\n"
30 "#ifndef " << to_upper(dump_name) << "_H_INCLUDED\n"
31 "#define " << to_upper(dump_name) << "_H_INCLUDED\n"
32 << in.h_headers() <<
33 "#include \"u_sdp.h\"\n"
34 "#include \"e_node.h\"\n"
35 "#include \"e_subckt.h\"\n"
36 "#include \"e_model.h\"\n"
37 "#include <boost/assign.hpp>\n"
38 "#include <boost/algorithm/string.hpp>\n"
39 "/*--------------------------------------"
40 "------------------------------------*/\n";
42 /*--------------------------------------------------------------------------*/
43 static void make_sdp(std::ofstream& out, const Model& m)
45 out << "class SDP_" << m.name()
46 << "\n :public SDP_" << m.inherit()
47 << "{\n"
48 "public:\n"
49 " explicit SDP_" << m.name() << "(const COMMON_COMPONENT* c) : SDP_"
50 << m.inherit() << "(c) {init(c);}\n"
51 " void init(const COMMON_COMPONENT*);\n"
52 "public:\n";
53 Parameter_List::const_iterator p = m.size_dependent().raw().begin();
54 for (;;) {
55 if (p == m.size_dependent().raw().end()) {
56 p = m.size_dependent().calculated().begin();
57 }else{
59 if (p == m.size_dependent().calculated().end()) {
60 break;
61 }else{
63 out << " " << (**p).type() << " " << (**p).code_name()
64 << ";\t// " << (**p).comment() << '\n';
65 ++p;
67 out << "};\n"
68 "/*--------------------------------------"
69 "------------------------------------*/\n";
71 /*--------------------------------------------------------------------------*/
72 static void make_tdp(std::ofstream& out, const Model& m)
74 out << "class DEV_" << m.dev_type() << ";\n";
75 out << "class TDP_" << m.name();
76 if (!m.hide_base()) {
77 out << "\n :public TDP_" << m.inherit();
78 }else{
80 out <<
81 "{\n"
82 "public:\n"
83 " explicit TDP_"<< m.name() <<"(const DEV_" << m.dev_type() << "*);\n"
84 "public:\n";
85 for (Parameter_List::const_iterator
86 p = m.temperature().calculated().begin();
87 p != m.temperature().calculated().end();
88 ++p) {
89 out << " " << (**p).type() << " " << (**p).code_name()
90 << ";\t// " << (**p).comment() << '\n';
92 out << "};\n"
93 "/*--------------------------------------"
94 "------------------------------------*/\n";
96 /*--------------------------------------------------------------------------*/
97 static void make_model(std::ofstream& out, const Model& m)
99 std::string class_name = "MODEL_" + m.name().to_string();
100 out <<
101 "class " << class_name << "\n"
102 " :public MODEL_" << m.inherit() << "{\n"
103 "protected:\n"
104 " explicit " << class_name << "(const " << class_name << "& p);\n"
105 "public:\n"
106 " explicit " << class_name << "(const BASE_SUBCKT*);\n"
107 " ~" << class_name << "() {--_count;}\n"
108 "public: // override virtual\n"
109 " std::string dev_type()const;\n"
110 " void set_dev_type(const std::string& nt);\n"
111 " CARD* clone()const {return new " << class_name << "(*this);}\n"
112 " void precalc_first();\n"
113 " void precalc_last();\n"
114 " SDP_CARD* new_sdp(COMMON_COMPONENT* c)const;\n"
115 " void set_param_by_index(int, std::string&, int);\n"
116 " bool param_is_printable(int)const;\n"
117 " std::string param_name(int)const;\n"
118 " std::string param_name(int,int)const;\n"
119 " std::string param_value(int)const;\n"
120 " int param_count()const {return (" << 1 + m.independent().override().size()
121 + 4 * m.size_dependent().raw().size() + m.independent().raw().size();
122 if (!m.hide_base()) {
123 out << " + MODEL_" << m.inherit() << "::param_count());}\n";
124 }else{
125 out << ");}\n";
127 if (!m.tt_eval().is_empty()) {
128 out << "void tt_eval(COMPONENT*)const;\n";
129 }else{
130 out << "";
132 out <<
133 " bool is_valid(const COMPONENT*)const;\n"
134 " void tr_eval(COMPONENT*)const;\n"
135 " virtual void stress_apply(COMPONENT*)const{ std::cerr<<\"virtual stress apply(C)\\n\" ;}\n"
136 "public: // not virtual\n"
137 " static int count() {return _count;}\n"
138 "private: // strictly internal\n";
139 out <<
140 " static int _count;\n"
141 "public: // input parameters\n";
142 for (Parameter_List::const_iterator
143 p = m.size_dependent().raw().begin();
144 p != m.size_dependent().raw().end();
145 ++p) {
146 out << " " << "SDP" << " " << (**p).code_name()
147 << ";\t// " << (**p).comment() << '\n';
149 for (Parameter_List::const_iterator
150 p = m.independent().raw().begin();
151 p != m.independent().raw().end();
152 ++p) {
153 out << " PARAMETER<" << (**p).type() << "> " << (**p).code_name()
154 << ";\t// " << (**p).comment() << '\n';
156 out << "public: // calculated parameters\n";
157 for (Parameter_List::const_iterator
158 p = m.independent().calculated().begin();
159 p != m.independent().calculated().end();
160 ++p) {
161 out << " " << (**p).type() << " " << (**p).code_name()
162 << ";\t// " << (**p).comment() << '\n';
164 out << "};\n"
165 "/*--------------------------------------"
166 "------------------------------------*/\n";
168 /*--------------------------------------------------------------------------*/
169 static void make_common(std::ofstream& out, const Device& d)
171 std::string class_name = "COMMON_" + d.name().to_string();
172 out <<
173 "class " << class_name << "\n"
174 " :public COMMON_COMPONENT{\n"
175 "public:\n"
176 " explicit " << class_name << "(const " << class_name << "& p);\n"
177 " explicit " << class_name << "(int c=0);\n"
178 " ~" << class_name << "();\n"
179 " bool operator==(const COMMON_COMPONENT&)const;\n"
180 " COMMON_COMPONENT* clone()const {return new "<<class_name<<"(*this);}\n"
181 " void set_param_by_index(int, std::string&, int);\n"
182 " void set_param_by_name(std::string, std::string);\n"
183 " bool param_is_printable(int)const;\n"
184 " std::string param_name(int)const;\n"
185 " std::string param_name(int,int)const;\n"
186 " std::string param_value(int)const;\n"
187 " int param_count()const {return ("
188 << d.common().override().size() + d.common().raw().size()
189 << " + COMMON_COMPONENT::param_count());}\n"
190 " void expand(const COMPONENT*);\n"
191 " void precalc_last(const CARD_LIST*);\n"
192 " std::string name()const {itested();return \"" << d.parse_name() << "\";}\n"
193 " const SDP_CARD* sdp()const {return _sdp;}\n"
194 " bool has_sdp()const {untested();return _sdp;}\n"
195 " static int count() {return _count;}\n"
196 "private: // strictly internal\n"
197 " static map<std::string, PARA_BASE " << class_name << "::*> param_dict;\n"
198 " static map<std::string, PARA_BASE " << class_name << "::*> param_dict_low;\n"
199 " static int _count;\n"
200 "public: // input parameters\n";
201 for (Parameter_List::const_iterator
202 p = d.common().raw().begin();
203 p != d.common().raw().end();
204 ++p) {
205 out << " PARAMETER<" << (**p).type() << "> " << (**p).code_name()
206 << ";\t// " << (**p).comment() << '\n';
208 out <<
209 "public: // calculated parameters\n"
210 " SDP_CARD* _sdp;\n";
211 for (Parameter_List::const_iterator
212 p = d.common().calculated().begin();
213 p != d.common().calculated().end();
214 ++p) {
215 out << " " << (**p).type() << " " << (**p).code_name()
216 << ";\t// " << (**p).comment() << '\n';
218 out << "public: // attached commons\n";
219 for (Args_List::const_iterator
220 p = d.circuit().args_list().begin();
221 p != d.circuit().args_list().end();
222 ++p) {
223 out << " COMMON_COMPONENT* _" << (**p).name() << ";\n";
225 out << "};\n"
226 "/*--------------------------------------"
227 "------------------------------------*/\n";
229 /*--------------------------------------------------------------------------*/
230 static void make_device(std::ofstream& out, const Device& d)
232 std::string class_name = "DEV_" + d.name().to_string();
233 out <<
234 "class " << class_name << " : public BASE_SUBCKT {\n"
235 "private:\n"
236 " explicit " << class_name << "(const " << class_name << "& p);\n"
237 "public:\n"
238 " explicit " << class_name << "();\n"
239 " ~" << class_name << "() {--_count;}\n"
240 "private: // override virtual\n"
241 " char id_letter()const {untested();return '" << d.id_letter() << "';}\n"
242 " bool print_type_in_spice()const {return true;}\n"
243 " std::string value_name()const {return \"area\";}\n"
244 " //std::string dev_type()const; //BASE_SUBCKT\n"
245 " uint_t max_nodes()const {return " << d.max_nodes() << ";}\n"
246 " uint_t min_nodes()const {return " << d.min_nodes() << ";}\n";
247 if (d.max_nodes() != d.min_nodes()) {
248 out <<
249 " //int matrix_nodes()const; //BASE_SUBCKT\n"
250 " //int net_nodes()const; //BASE_SUBCKT\n";
251 }else{
252 out <<
253 " //int matrix_nodes()const; //BASE_SUBCKT\n"
254 " uint_t net_nodes()const {return " << d.max_nodes() << ";}\n";
256 out <<
257 " uint_t int_nodes()const {return "
258 << d.circuit().local_nodes().size() << ";}\n"
259 " CARD* clone()const {return new "
260 << class_name << "(*this);}\n"
261 " void precalc_first() {COMPONENT::precalc_first(); if(subckt()) subckt()->precalc_first();}\n"
262 " void expand();\n"
263 " void precalc_last() {COMPONENT::precalc_last(); assert(subckt()); subckt()->precalc_last();}\n"
264 " //void map_nodes(); //BASE_SUBCKT\n"
265 " //void tr_begin(); //BASE_SUBCKT\n"
266 " //void tr_restore(); //BASE_SUBCKT\n";
267 if (d.tt_eval().is_empty()) {
268 trace0( "tt_eval isempty" );
269 out <<
270 " //void tt_commit(); //BASE_SUBCKT\n"
271 " //void tt_prepare(); //BASE_SUBCKT\n";
272 }else{
273 out <<
274 " void stress_apply(); //BASE_SUBCKT\n"
275 " void tt_commit(); //BASE_SUBCKT\n"
276 " void tt_prepare(); //BASE_SUBCKT\n";
278 if (d.tr_eval().is_empty()) {
279 trace0( "tr_eval isempty" );
280 out <<
281 " //void dc_advance(); //BASE_SUBCKT\n"
282 " //void tr_advance(); //BASE_SUBCKT\n"
283 " //void tr_regress(); //BASE_SUBCKT\n"
284 " //bool tr_needs_eval()const;//BASE_SUBCKT\n"
285 " //void tr_queue_eval(); //BASE_SUBCKT\n"
286 " //bool do_tr(); //BASE_SUBCKT\n";
287 }else{
288 out <<
289 " void dc_advance() {set_not_converged(); BASE_SUBCKT::dc_advance();}\n"
290 " void tr_advance() {set_not_converged(); BASE_SUBCKT::tr_advance();}\n"
291 " void tr_regress() {set_not_converged(); BASE_SUBCKT::tr_regress();}\n"
292 " bool tr_needs_eval()const;\n"
293 " // ????? what is this good for?\n"
294 " void tr_queue_eval() {if(tr_needs_eval()){q_eval();}}\n"
295 " bool do_tr();\n";
297 out <<
298 " //void tr_load(); //BASE_SUBCKT\n"
299 " //double tr_review(); //BASE_SUBCKT\n"
300 " //void tr_accept(); //BASE_SUBCKT\n"
301 " //void tr_unload(); //BASE_SUBCKT\n"
302 " double tr_probe_num(const std::string&)const;\n"
303 " double tt_probe_num(const std::string&)const;\n"
304 " //void ac_begin(); //BASE_SUBCKT\n"
305 " //void do_ac(); //BASE_SUBCKT\n"
306 " //void ac_load(); //BASE_SUBCKT\n"
307 " //XPROBE ac_probe_ext(CS&)const;//CKT_BASE/nothing\n"
308 "public:\n"
309 " static int count() {return _count;}\n"
310 "public: // may be used by models\n";
311 for (Function_List::const_iterator
312 p = d.function_list().begin();
313 p != d.function_list().end();
314 ++p) {
315 out << " void " << (**p).name() << ";\n";
317 out <<
318 "private: // not available even to models\n"
319 " static int _count;\n";
320 out << "public: // input parameters\n";
321 for (Parameter_List::const_iterator
322 p = d.device().raw().begin();
323 p != d.device().raw().end();
324 ++p) {untested();
325 untested();
326 out << " PARAMETER<" << (**p).type() << "> " << (**p).code_name()
327 << ";\t// " << (**p).comment() << '\n';
329 out << "public: // calculated parameters\n";
330 for (Parameter_List::const_iterator
331 p = d.device().calculated().begin();
332 p != d.device().calculated().end();
333 ++p) {
334 out << " " << (**p).type() << " " << (**p).code_name()
335 << ";\t// " << (**p).comment() << '\n';
337 out << "public: // netlist\n";
338 for (Element_List::const_iterator
339 p = d.circuit().elements().begin();
340 p != d.circuit().elements().end();
341 ++p) {
342 out << " COMPONENT* _" << (**p).name() << ";\n";
344 out << "private: // node list\n"
345 " enum {";
346 for (Port_List::const_iterator
347 p = d.circuit().req_nodes().begin();
348 p != d.circuit().req_nodes().end();
349 ++p) {
350 if (p != d.circuit().req_nodes().begin()) {
351 out << ", ";
352 }else{
354 out << "n_" << (**p).name();
356 for (Port_List::const_iterator
357 p = d.circuit().opt_nodes().begin();
358 p != d.circuit().opt_nodes().end();
359 ++p) {
360 out << ", ";
361 out << "n_" << (**p).name();
363 for (Port_List::const_iterator
364 p = d.circuit().local_nodes().begin();
365 p != d.circuit().local_nodes().end();
366 ++p) {
367 out << ", n_" << (**p).name();
369 size_t total_nodes = d.circuit().req_nodes().size() + d.circuit().opt_nodes().size()
370 + d.circuit().local_nodes().size();
371 out << "};\n"
372 " node_t _nodes[" << total_nodes << "];\n"
373 " std::string port_name(uint_t i)const {\n"
374 " assert(i < " << d.circuit().req_nodes().size() + d.circuit().opt_nodes().size() << ");\n"
375 " static std::string names[] = {";
376 for (Port_List::const_iterator
377 p = d.circuit().req_nodes().begin();
378 p != d.circuit().req_nodes().end();
379 ++p) {
380 out << '"' << (**p).name() << "\", ";
382 for (Port_List::const_iterator
383 p = d.circuit().opt_nodes().begin();
384 p != d.circuit().opt_nodes().end();
385 ++p) {
386 out << '"' << (**p).name() << "\", ";
388 out << "\"\"};\n"
389 " return names[i];\n"
390 " }\n"
391 "};\n"
392 "/*--------------------------------------"
393 "------------------------------------*/\n";
395 /*--------------------------------------------------------------------------*/
396 static void make_eval(std::ofstream& out, const Eval& e,
397 const String_Arg& dev_name)
399 std::string class_name = "EVAL_" + dev_name.to_string() + '_'
400 + e.name().to_string();
401 out <<
402 "class " << class_name << " : public COMMON_COMPONENT {\n"
403 "private:\n"
404 " explicit "<< class_name << "(const "<< class_name << "& p)\n"
405 " :COMMON_COMPONENT(p) {}\n"
406 "public:\n"
407 " explicit "<< class_name << "(int c=0) :COMMON_COMPONENT(c) {}\n"
408 " bool operator==(const COMMON_COMPONENT& x)const "
409 "{return COMMON_COMPONENT::operator==(x);}\n"
410 " COMMON_COMPONENT* clone()const {return new "<<class_name<<"(*this);}\n"
411 " std::string name()const {untested(); return \""<< class_name << "\";}\n"
412 " void tr_eval(ELEMENT*d)const;\n"
413 " bool has_tr_eval()const {return true;}\n"
414 " bool has_ac_eval()const {return false;}\n"
415 "};\n"
416 "/*--------------------------------------"
417 "------------------------------------*/\n";
419 /*--------------------------------------------------------------------------*/
420 static void make_evals(std::ofstream& out, const Device& d)
422 for (Eval_List::const_iterator
423 e = d.eval_list().begin();
424 e != d.eval_list().end();
425 ++e) {
426 make_eval(out, **e, d.name());
429 /*--------------------------------------------------------------------------*/
430 static void make_tail(std::ofstream& out, const File& in)
432 out << "// h_direct\n" << in.h_direct() <<
433 "/*--------------------------------------"
434 "------------------------------------*/\n"
435 "/*--------------------------------------"
436 "------------------------------------*/\n"
437 "#endif\n";
439 /*--------------------------------------------------------------------------*/
440 void make_h_file(const File& in)
442 std::string dump_name = in.name();
443 { // chop suffix .model
444 std::string::size_type loc = dump_name.rfind(".model");
445 if (loc == std::string::npos) {
446 untested();
447 loc = dump_name.rfind(".vams");
448 }else{
450 if (loc != std::string::npos) {
451 dump_name.erase(loc);
452 }else{untested();
455 { // chop prefix path
456 std::string::size_type loc = dump_name.find_last_of(ENDDIR);
457 if (loc != std::string::npos) {
458 dump_name.erase(0, loc+1);
459 }else{itested();
463 // open file
464 std::ofstream out((dump_name+".h").c_str());
465 if (!out) {untested();
466 os_error(dump_name);
467 }else{
470 make_header(out, in, dump_name);
472 for (Model_List::const_iterator
473 m = in.models().begin();
474 m != in.models().end();
475 ++m) {
476 make_sdp(out, **m);
477 make_tdp(out, **m);
478 make_model(out, **m);
480 for (Device_List::const_iterator
481 m = in.devices().begin();
482 m != in.devices().end();
483 ++m) {
484 make_common(out, **m);
485 make_evals(out, **m);
486 make_device(out, **m);
488 make_tail(out, in);
490 /*--------------------------------------------------------------------------*/
491 /*--------------------------------------------------------------------------*/