From a8256910d40a0eee85bf539a3f120c9d92485f3f Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 26 Jul 2016 23:50:23 +0200 Subject: o Working version with support for Arduino parts. --- main.cpp | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 151 insertions(+), 15 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index b5e998d..cb5750e 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,21 @@ #include +#include +#include #include #include #include +#include +#include #include "trygvis/kicad.h" using namespace std; using namespace trygvis::kicad; +using trygvis::kicad::netlist::component; +using trygvis::kicad::netlist::kicad_net_loader; +using trygvis::kicad::netlist::kicad_parse_exception; +using trygvis::kicad::netlist::net; + char *program; __attribute__((noreturn)) @@ -14,37 +23,125 @@ void usage(const char *reason = nullptr) { if (reason) { fprintf(stderr, "%s\n", reason); } - fprintf(stderr, "usage: %s -f file -r ref\n", program); + fprintf(stderr, "usage: %s -n -r [-o ]\n", program); exit(EX_USAGE); } -void parse_args(int argc, char **argv, bool *debug, char **filename, char **ref) { +void parse_args(int argc, char **argv, bool *debug, char **net_filename, char **ref, char **out_filename) { *debug = false; - *filename = *ref = nullptr; + *ref = nullptr; + *out_filename = nullptr; + *ref = nullptr; int c; - while ((c = getopt(argc, argv, "Df:r:")) != -1) { + while ((c = getopt(argc, argv, "Dn:r:o:")) != -1) { switch (c) { case 'D': *debug = true; break; - case 'f': - *filename = optarg; + case 'n': + *net_filename = optarg; break; case 'r': *ref = optarg; break; + case 'o': + if (strcmp("-", optarg) != 0) { + *out_filename = optarg; + } + break; default: - abort(); + usage(); } } - if (!*filename) { + if (!*net_filename && !*ref) { usage(); } } -bool generate(const char *ref, const trygvis::kicad::netlist &netlist) { +class part { +public: + part(const string &name) : name(name) { + } + + virtual ~part() { + } + + const string name; + + virtual bool generate(stringstream &out, const string &ref, const vector usages) = 0; +}; + +class arduino_uno : public part { +public: + arduino_uno() : part("ARDUINO_UNO") { } + + ~arduino_uno() { + } + + virtual bool generate(stringstream &out, const string &ref, const vector usages) override { + out << "namespace schematic {" << endl; + for (auto &usage: usages) { + auto node = usage->node_for_ref(ref); + + if (node->pin >= 7 && node->pin <= 12) { + out << "static const int ANALOG_" << usage->name << " = " << (node->pin - 7) << ";" << endl; + } else if (node->pin >= 13 && node->pin <= 26) { + out << "static const int " << usage->name << " = " << (node->pin - 13) << ";" << endl; + } + } + out << "} // namespace schematic" << endl; + + return true; + } +}; + + +class library { +public: + library(const string &name) : name(name) { } + + library(library &&l) : name(std::move(l.name)), parts(std::move(l.parts)) { } + + const string name; + vector> parts; + + opt find_part(string name) const { + for (auto &part: parts) { + if (part->name == name) { + return part.get(); + } + } + + return nullptr; + } +}; + +class kicad_gen { +public: + vector libraries; + + kicad_gen() { + library kicad_utils("kicad_utils"); + kicad_utils.parts.push_back(make_unique()); + + libraries.push_back(std::move(kicad_utils)); + } + + opt find_library(string name) { + for (auto &l : libraries) { + if (l.name == name) { + return &l; + } + } + + return nullptr; + } +}; + +bool generate(const char *ref, const trygvis::kicad::netlist::netlist &netlist, stringstream &out) { + kicad_gen gen; opt componentO = netlist.find_component(ref); if (!componentO) { @@ -54,9 +151,38 @@ bool generate(const char *ref, const trygvis::kicad::netlist &netlist) { const component *c = *componentO; - cerr << "Generating connections for " << ref << endl; + cerr << "Generating connections for " << c->ref << " (" << c->value << ")" << endl; + + auto libraryO = gen.find_library(c->_lib_source.lib); + + if (!libraryO) { + cerr << "kicad_gen does not support library '" << c->_lib_source.lib << "'" << endl; + return false; + } + + const library *library = *libraryO; + + auto partName = c->_lib_source.part; + + auto partO = library->find_part(partName); + + if (!partO) { + cerr << "kicad_gen's library " << library->name << " does not have a component named " << partName << endl; + return false; + } + + part *part = *partO; + + out << "#ifndef SCHEMATIC_H" << endl; + out << "#define SCHEMATIC_H" << endl; + out << endl; + + auto usages = netlist.find_usage_of(ref); + + part->generate(out, ref, usages); - cerr << c->value << endl; + out << endl; + out << "#endif // SCHEMATIC_H" << endl; return true; } @@ -65,18 +191,28 @@ int main(int argc, char **argv) { program = argv[0]; bool debug; - char *filename; + char *net_filename; char *ref; - parse_args(argc, argv, &debug, &filename, &ref); + char *out_filename; + parse_args(argc, argv, &debug, &net_filename, &ref, &out_filename); kicad_net_loader loader; try { - auto netlist = loader.load(filename); + auto netlist = loader.load(net_filename); - auto ok = generate(ref, netlist); + stringstream out; + auto ok = generate(ref, netlist, out); if (ok) { + auto contents = out.str(); + if (out_filename != nullptr) { + ofstream outstream(out_filename); + outstream << contents; + outstream.close(); + } else { + cout << contents << flush; + } return EXIT_SUCCESS; } return EXIT_FAILURE; -- cgit v1.2.3