Skip to content

Commit

Permalink
turn dispatcher into template class
Browse files Browse the repository at this point in the history
now it can be repurposed to dispatch other things, such as NetLang.
  • Loading branch information
felix-salfelder committed Jul 20, 2015
1 parent 13b7e11 commit 92eb34c
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 27 deletions.
1 change: 1 addition & 0 deletions qucs/qucs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ SET(QUCS_SRCS
syntax.cpp misc.cpp messagedock.cpp
imagewriter.cpp printerwriter.cpp projectView.cpp
sim/qucsator.cpp
sim/verilog.cpp
)

SET(QUCS_HDRS
Expand Down
1 change: 1 addition & 0 deletions qucs/qucs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ qucs_LDADD = components/libcomponents.a diagrams/libdiagrams.a \

# adding sim/qucsator.la does not work. this is a workaround.
qucs_LDADD+= sim/qucsator_la-qucsator.o
qucs_LDADD+= sim/verilog_la-verilog.o

noinst_HEADERS = $(MOCHEADERS) main.h wire.h qucsdoc.h element.h node.h \
wirelabel.h viewpainter.h mnemo.h mouseactions.h syntax.h module.h misc.h
Expand Down
2 changes: 1 addition & 1 deletion qucs/qucs/dialogs/simmessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ void SimMessage::startSimulator()
Stream << '\n';

isVerilog = ((Schematic*)DocWidget)->isVerilog;
auto sd = SimulatorDispatcher::get("qucsator");
auto sd = Dispatcher<Simulator>::get("qucsator");
assert(sd);
auto nl = sd->netLang();
assert(nl);
Expand Down
49 changes: 32 additions & 17 deletions qucs/qucs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,32 +783,35 @@ int main(int argc, char *argv[])
int dpi = 96;
QString color = "RGB";
QString orientation = "portraid";
QString default_simulator = "qucsator"; // FIXME: get from rc? maybe from environment?
QString netlang_name = default_simulator;

// simple command line parser
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
fprintf(stdout,
"Usage: %s [-hv] \n"
" qucs -n -i FILENAME -o FILENAME\n"
" qucs -p -i FILENAME -o FILENAME.[pdf|png|svg|eps] \n\n"
"Usage: %s [COMMAND] [OPTIONS]\n\n"
"Commands:\n"
" -h, --help display this help and exit\n"
" -v, --version display version information and exit\n"
" -n, --netlist convert Qucs schematic into netlist\n"
" -p, --print print Qucs schematic to file (eps needs inkscape)\n"
" --page [A4|A3|B4|B5] set print page size (default A4)\n"
" --dpi NUMBER set dpi value (default 96)\n"
" --color [RGB|RGB] set color mode (default RGB)\n"
" --orin [portraid|landscape] set orientation (default portraid)\n"
" -i FILENAME use file as input schematic\n"
" -o FILENAME use file as output netlist\n"
" -n, --netlist convert Qucs schematic into netlist, requires -i, -o\n"
" -p, --print print Qucs schematic to file, requires -i, -o (eps needs inkscape)\n"
" -icons create component icons under ./bitmaps_generated\n"
" -doc dump data for documentation:\n"
" * file with of categories: categories.txt\n"
" * one directory per category (e.g. ./lumped components/)\n"
" - CSV file with component data ([comp#]_data.csv)\n"
" - CSV file with component properties. ([comp#]_props.csv)\n"
" -list-entries list component entry formats for schematic and netlist\n"
, argv[0]);
"Options:\n"
" -i FILENAME use file as input schematic\n"
" -o FILENAME use file as output netlist\n"
" -l NETLANG language to be used by netlister, can be a simulator name\n"
" --page [A4|A3|B4|B5] set print page size (default A4)\n"
" --dpi NUMBER set dpi value (default 96)\n"
" --color [RGB|RGB] set color mode (default RGB)\n"
" --orin [portrait|landscape] set orientation (default portraid)\n"
,argv[0]);
return 0;
}
else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
Expand Down Expand Up @@ -843,6 +846,9 @@ int main(int argc, char *argv[])
else if (!strcmp(argv[i], "-o")) {
outputfile = argv[++i];
}
else if (!strcmp(argv[i], "-l")) {
netlang_name = argv[++i];
}
else if(!strcmp(argv[i], "-icons")) {
createIcons();
return 0;
Expand All @@ -861,6 +867,19 @@ int main(int argc, char *argv[])
}
}

NetLang const* netlang;
if((netlang = Dispatcher<NetLang>::get(netlang_name))){
// just use it.
}else if(auto sd = Dispatcher<Simulator>::get(netlang_name)){
// ask a simulator.
netlang = sd->netLang();
}
if(!netlang){
std::cerr << "Error: Cannot find language for "
<< std::string(netlang_name) << "\n";
return -1;
}

// check operation and its required arguments
if (netlist_flag and print_flag) {
fprintf(stderr, "Error: --print and --netlist cannot be used together\n");
Expand All @@ -876,11 +895,7 @@ int main(int argc, char *argv[])
}
// create netlist from schematic
if (netlist_flag) {
auto sd = SimulatorDispatcher::get("qucsator");
assert(sd);
auto nl = sd->netLang();
assert(nl);
return doNetlist(inputfile, outputfile, nl);
return doNetlist(inputfile, outputfile, netlang);
} else if (print_flag) {
return doPrint(inputfile, outputfile,
page, dpi, color, orientation);
Expand Down
5 changes: 4 additions & 1 deletion qucs/qucs/qucs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2800,4 +2800,7 @@ void QucsApp::slotSaveSchematicToGraphicsFile(bool diagram)
delete writer;
}

std::map<std::string, Simulator const*> SimulatorDispatcher::Simulators;
template<>
std::map<std::string, Simulator const*> Dispatcher<Simulator>::Stash{};
template<>
std::map<std::string, NetLang const*> Dispatcher<NetLang>::Stash{};
7 changes: 6 additions & 1 deletion qucs/qucs/sim/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@
# Boston, MA 02110-1301, USA.
#

noinst_LTLIBRARIES = qucsator.la
noinst_LTLIBRARIES = qucsator.la verilog.la
AM_DEFAULT_SOURCE_EXT = .cpp

qucsator_la_LDFLAGS = -module -avoid-version
qucsator_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(abs_top_srcdir)/qucs
# need Qt for TextStream.
qucsator_la_CPPFLAGS += $(QT_INCLUDES)

verilog_la_LDFLAGS = -module -avoid-version
verilog_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(abs_top_srcdir)/qucs
# need Qt for TextStream.
verilog_la_CPPFLAGS += $(QT_INCLUDES)
2 changes: 1 addition & 1 deletion qucs/qucs/sim/qucsator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class Qucsator : public Simulator
};

static Qucsator Q;
static SimulatorDispatcher p("qucsator", &Q);
static Dispatcher<Simulator> p("qucsator", &Q);
}

// vim:ts=8:sw=2:noet
19 changes: 13 additions & 6 deletions qucs/qucs/sim/sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,28 @@ inline void NetLang::printItem(Element const* c, stream_t& s) const
/*!
* a dispatcher stub. hardly sophisticated, but functional
*/
class SimulatorDispatcher{
template<class T>
class Dispatcher{
public:
SimulatorDispatcher(std::string label, Simulator const* what)
Dispatcher(std::string label, T const* what)
{
qDebug() << "dispatcher install" << label.c_str();
assert(what);
Simulators[label] = what;
Stash[label] = what;
}
static Simulator const* get(std::string const& s)
static T const* get(std::string const& s)
{
qDebug() << "dispatcher get" << s.c_str();
return Simulators[s];
return Stash[s];
}
static T const* get(QString const& s){
return get(std::string(s));
}
static T const* get(char const* s){
return get(std::string(s));
}
private:
static std::map<std::string, Simulator const*> Simulators;
static std::map<std::string, T const*> Stash;
};

#define QUCS_SIM_H__
Expand Down
80 changes: 80 additions & 0 deletions qucs/qucs/sim/verilog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/***************************************************************************
verilog.cc
----------
begin : yes
copyright : (C) 2015 by Felix Salfelder
email : felix@salfelder.org
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "sim.h"
#include "../components/component.h"
#include "node.h"
#include <QString>

namespace {
class Verilog : public NetLang
{
virtual void printInstance(Component const*, QTextStream&) const;
} V;

static Dispatcher<NetLang> p("verilog", &V);

/*!
* print Components in Verilog
*/
void Verilog::printInstance(Component const* c, QTextStream& s) const
{
if(c->isOpen()) {
// nothing.
}else if(c->isShort()){
// replace by some resistors (hack?)
int z=0;
QListIterator<Port *> iport(c->ports());
Port *pp = iport.next();
QString Node1 = pp->Connection->Name;
while (iport.hasNext()){
s << "R:" << c->label() << "." << QString::number(z++) << " "
<< Node1 << " " << iport.next()->Connection->Name << " R=\"0\"\n";
}
}else{
QString netlist(c->getNetlist());
if(netlist!="obsolete") {
// still using obsolete netlister here.
std::cerr << "incomplete, see verilog.cpp";
assert(false);
// throw exceptionIncomplete("verilog: cannot netlist c->type()");
}else{ // normal netlisting
s << c->type() << " #(";

QString comma="";
for(auto p2 : c->params()) {
if(p2->Name != "Symbol") { // hack.
s << comma << "." << p2->Name << "(" << p2->Value << ")";
comma = ", ";
}
}
s << ") " << c->label() << "(";

// what about port names?
comma = "";
for(Port *p1 : c->ports()){
s << comma << p1->Connection->Name;
comma = ", ";
}

s << ");\n";
}
}
}
}

// vim:ts=8:sw=2:noet

0 comments on commit 92eb34c

Please sign in to comment.