aboutsummaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp166
1 files changed, 151 insertions, 15 deletions
diff --git a/main.cpp b/main.cpp
index b5e998d..cb5750e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,12 +1,21 @@
#include <iostream>
+#include <fstream>
+#include <sstream>
#include <err.h>
#include <sysexits.h>
#include <getopt.h>
+#include <cstring>
+#include <memory>
#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 <net file> -r <ref> [-o <out file>]\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<const net *> 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<const net *> 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<unique_ptr<part>> parts;
+
+ opt<part *> find_part(string name) const {
+ for (auto &part: parts) {
+ if (part->name == name) {
+ return part.get();
+ }
+ }
+
+ return nullptr;
+ }
+};
+
+class kicad_gen {
+public:
+ vector<library> libraries;
+
+ kicad_gen() {
+ library kicad_utils("kicad_utils");
+ kicad_utils.parts.push_back(make_unique<arduino_uno>());
+
+ libraries.push_back(std::move(kicad_utils));
+ }
+
+ opt<library *> 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<const component *> 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;