From 535d856a39b177642724bcfe6009985bf4262dbd Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 5 Aug 2016 15:03:14 +0200 Subject: o More flexible parsing. More rules needs to be updated. --- CMakeLists.txt | 3 +- cli/CMakeLists.txt | 4 +- cli/generate-header.cpp | 21 +++++----- core/KicadNetLexer.g4 | 2 +- core/KicadNetParser.g4 | 2 +- core/README.md | 10 +++++ core/include/trygvis/kicad.h | 3 ++ core/kicad.cpp | 18 ++++++-- examples/CMakeLists.txt | 19 +++++---- examples/arduino-led/CMakeLists.txt | 2 - examples/intel-quark-d2000/CMakeLists.txt | 6 +-- python/pybind11 | 2 +- template/arduino-uno.py | 19 --------- template/intel-quark-d2000.py | 69 ------------------------------- templates/arduino-uno.py | 19 +++++++++ templates/intel-quark-d2000.py | 69 +++++++++++++++++++++++++++++++ templates/nodemcu.py | 19 +++++++++ 17 files changed, 164 insertions(+), 123 deletions(-) create mode 100644 core/README.md delete mode 100644 template/arduino-uno.py delete mode 100644 template/intel-quark-d2000.py create mode 100644 templates/arduino-uno.py create mode 100644 templates/intel-quark-d2000.py create mode 100644 templates/nodemcu.py diff --git a/CMakeLists.txt b/CMakeLists.txt index e70bce4..3b4c6e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,5 @@ add_compile_options(-Wextra) add_subdirectory(core) add_subdirectory(python) add_subdirectory(cli) -#add_subdirectory(examples) -message(STATUS "The examples are not built as they depend on a full installation of kicad-utils. Do a make install first and then build the examples") +#add_subdirectory(examples) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index f3dd326..6cad70c 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -15,8 +15,8 @@ install(TARGETS generate-header LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) -install(DIRECTORY ../template/ - DESTINATION share/kicad-utils/template +install(DIRECTORY ../templates/ + DESTINATION share/kicad-utils/templates FILES_MATCHING PATTERN *.py PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) diff --git a/cli/generate-header.cpp b/cli/generate-header.cpp index 6fd64c6..9d5a4f4 100644 --- a/cli/generate-header.cpp +++ b/cli/generate-header.cpp @@ -21,15 +21,15 @@ namespace py = pybind11; #include #include +using namespace std; +namespace fs = std::experimental::filesystem; + #ifdef _WIN32 -static const char PATH_SEPARATOR = ';'; +static string PATH_SEPARATOR(";"); #else -static const char PATH_SEPARATOR = ':'; +static string PATH_SEPARATOR(":"); #endif -using namespace std; -namespace fs = std::experimental::filesystem; - char *program; __attribute__((noreturn)) @@ -118,9 +118,9 @@ opt find_py_template(const string &py_template, const vector bool generate(const string &ref, nl *const netlist, stringstream &out, const fs::path &py_template) { py::dict vars; - pybind11::module kicad_utils_py_module = py::module::import("kicad_utils_py"); - pybind11::module main_module = py::module::import("__main__"); - vars = main_module.attr("__dict__"); + py::module::import("kicad_utils_py"); + vars = py::module::import("__main__"). + attr("__dict__"); pybind11::object netlist_py = py::cast(netlist); @@ -128,7 +128,8 @@ bool generate(const string &ref, nl *const netlist, stringstream &out, const fs: vars["ref"] = py::cast(ref); string init; - init += "generateHeader = GenerateHeader(ref, netlist)\n"; + init += "import kicad_utils_py\n"; + init += "generateHeader = kicad_utils_py.GenerateHeader(ref, netlist)\n"; init += "del ref\n"; init += "del netlist\n"; py::eval(init, vars); @@ -210,7 +211,7 @@ int main(int argc, char **argv) { struct opts opts = parse_args(argc, argv); opts.template_libs.push_back(fs::current_path()); - opts.template_libs.push_back(basedir / "share" / "kicad-utils" / "template"); + opts.template_libs.push_back(basedir / "share" / "kicad-utils" / "templates"); kicad_net_loader loader; diff --git a/core/KicadNetLexer.g4 b/core/KicadNetLexer.g4 index e10f7e7..6d3ce95 100644 --- a/core/KicadNetLexer.g4 +++ b/core/KicadNetLexer.g4 @@ -26,7 +26,7 @@ STRING: '"' ~["]* '"'; INTEGER: [0-9]+; ID - : [/+~\_\-\.\*\?/a-zA-Z0-9]+ + : [/+~\_\-\.\*\?/a-zA-Z0-9:]+ ; BlockComment diff --git a/core/KicadNetParser.g4 b/core/KicadNetParser.g4 index 3971111..9914084 100644 --- a/core/KicadNetParser.g4 +++ b/core/KicadNetParser.g4 @@ -27,7 +27,7 @@ code: ; component: - '(' 'comp' ref value libsource keyValue* ')' + '(' 'comp' (ref | value | libsource | keyValue)* ')' ; field: diff --git a/core/README.md b/core/README.md new file mode 100644 index 0000000..585cca1 --- /dev/null +++ b/core/README.md @@ -0,0 +1,10 @@ +# Building + + mkdir build + cd build + cmake .. \ + -DAntlr4_DIR=$HOME/opt/antlr4-cpp/lib/cmake/Antlr4 \ + -DCMAKE_INSTALL_PREFIX=$HOME/opt/kicad-utils \ + -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=YES + make + make install diff --git a/core/include/trygvis/kicad.h b/core/include/trygvis/kicad.h index 0c5005d..bae250b 100644 --- a/core/include/trygvis/kicad.h +++ b/core/include/trygvis/kicad.h @@ -78,6 +78,9 @@ public: explicit kicad_parse_exception(const std::vector &messages) : runtime_error("Parse error"), messages(messages) {} + explicit kicad_parse_exception(const std::string &message) : + runtime_error("Parse error"), messages({message}) {} + ~kicad_parse_exception() {} const std::vector messages; diff --git a/core/kicad.cpp b/core/kicad.cpp index 1a6ca2f..a553b62 100644 --- a/core/kicad.cpp +++ b/core/kicad.cpp @@ -112,12 +112,22 @@ public: nodes.emplace_back(ref, pin); } + template + static + Ref onlyOne(const vector> items, const antlr4::ParserRuleContext *ctx, const string &parent, const string &item) { + if(items.size() != 1) { + throw kicad_parse_exception("Bad netlist: expected only one " + item + " inside of " + parent + ". Line: " + to_string(ctx->start->getLine()) + ":" + to_string(ctx->start->getCharPositionInLine())); + } + return items[0]; + } + virtual void exitComponent(KicadNetParser::ComponentContext *ctx) override { - auto ref = strings.get(ctx->ref()->string()); - auto value = strings.get(ctx->value()->string()); + auto ref = strings.get(onlyOne(ctx->ref(), ctx, "comp", "ref")->string()); + auto value = strings.get(onlyOne(ctx->value(), ctx, "comp", "value")->string()); + auto libsource = onlyOne(ctx->libsource(), ctx, "comp", "libsource"); - lib_source ls{strings.get(ctx->libsource()->lib()->string()), - strings.get(ctx->libsource()->part()->string())}; + lib_source ls{strings.get(libsource->lib()->string()), + strings.get(libsource->part()->string())}; components.emplace_back(ref, value, ls); } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 58048ff..2cb3286 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,14 @@ -cmake_minimum_required(VERSION 3.5) -project(kicad_utils_examples) +# If we're not included by the msgflo project, find the sources the normal way. This is what you should do in your +# application +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + cmake_minimum_required(VERSION 3.5) + project(kicad_utils_examples) -find_package(KicadUtils QUIET) - -if (NOT KicadUtils_FOUND) - message(FATAL_ERROR "The KicadUtils CMake package was not found. Did you pass the correct value for KicadUtils_DIR?\nIt should probably be something like KicadUtils_DIR=$HOME/opt/kicad-utils/lib/cmake/KicadUtils") + find_package(KicadUtils) + if (NOT KicadUtils_FOUND) + message(FATAL_ERROR "The KicadUtils CMake package was not found. Did you pass the correct value for KicadUtils_DIR?\nIt should probably be something like KicadUtils_DIR=$HOME/opt/kicad-utils/lib/cmake/KicadUtils") + endif () endif () -add_subdirectory(arduino-led) -add_subdirectory(intel-quark-d2000) +#add_subdirectory(arduino-led) +#add_subdirectory(intel-quark-d2000) diff --git a/examples/arduino-led/CMakeLists.txt b/examples/arduino-led/CMakeLists.txt index 7855dff..4cc7341 100644 --- a/examples/arduino-led/CMakeLists.txt +++ b/examples/arduino-led/CMakeLists.txt @@ -1,5 +1,3 @@ -find_package(KicadUtils) - kicad_generate_header( OUTPUT schematic.h NET schematic/arduino-led.net diff --git a/examples/intel-quark-d2000/CMakeLists.txt b/examples/intel-quark-d2000/CMakeLists.txt index 3920d4b..f3a6cc1 100644 --- a/examples/intel-quark-d2000/CMakeLists.txt +++ b/examples/intel-quark-d2000/CMakeLists.txt @@ -1,10 +1,8 @@ -find_package(KicadUtils) - kicad_generate_header( OUTPUT schematic.h NET schematic/intel-quark-d2000.net REF U1 - TEMPLATE intel-quark-d2000.py + TEMPLATE intel-quark-d2000 TEMPLATE_LIB_LIST .) if (FALSE) @@ -13,5 +11,5 @@ if (FALSE) #add_executable(arduino-led arduino-led.ino schematic.h) #target_include_directories(arduino-led PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/kicad-include) else () - add_custom_target(intel-quark-d2000 ALL DEPENDS schematic.h schematic-py.h) + add_custom_target(intel-quark-d2000 ALL DEPENDS schematic.h) endif () diff --git a/python/pybind11 b/python/pybind11 index f38f359..5289af5 160000 --- a/python/pybind11 +++ b/python/pybind11 @@ -1 +1 @@ -Subproject commit f38f359f96815421f1780c1a676715efd041f1ae +Subproject commit 5289af5fc08db5f8038c9bbe75a9a4ce31b19f6d diff --git a/template/arduino-uno.py b/template/arduino-uno.py deleted file mode 100644 index 0e0e0e1..0000000 --- a/template/arduino-uno.py +++ /dev/null @@ -1,19 +0,0 @@ -global generateHeader - -generateHeader.println(""" -namespace schematic { -""") - -usages = generateHeader.netlist.find_usages_of(generateHeader.ref) - -for usage in usages: - node = usage.node_for_ref(generateHeader.ref) - - if 7 <= node.pin <= 12: - generateHeader.println("static const int ANALOG_" + usage.name + " = " + (node.pin - 7) + ";") - elif 13 <= node.pin <= 26: - generateHeader.println("static const int ANALOG_" + usage.name + " = " + (node.pin - 13) + ";") - -generateHeader.println(""" -} // namespace schematic -""") diff --git a/template/intel-quark-d2000.py b/template/intel-quark-d2000.py deleted file mode 100644 index 85572c5..0000000 --- a/template/intel-quark-d2000.py +++ /dev/null @@ -1,69 +0,0 @@ -global generateHeader -gpio_map = { - 2: '10', - 3: '11', - 4: '12', - 5: '13', - 6: '14', - 7: '15', - 8: '16', - 9: '17', - 10: '18', - - 11: '9', - 13: '20', - 14: '21', - 15: '22', - 16: '23', - 18: '19', - - 21: '24', - - 31: '0', - 32: '1', - 33: '2', - 34: '3', - 35: '4', - 36: '5', - 37: '6', - 38: '7', - 39: '8' -} - -generateHeader.println(""" -#include -#include - -enum schematic_direction { - schematic_direction_out = 1, - schematic_direction_in = 2 -}; -""") - -usages = generateHeader.netlist.find_usages_of(generateHeader.ref) - -for usage in usages: - node = usage.node_for_ref(generateHeader.ref) - - gpio = gpio_map.get(node.pin) - - if gpio is None: - continue - - generateHeader.println( - 'static const uint8_t SCHEMATIC_' + usage.name + ' = ' + gpio + ';\n' - '\n' - 'static inline\n' - 'qm_rc_t schematic_' + usage.name + '_direction(enum schematic_direction dir) {\n' - ' qm_gpio_port_config_t cfg;\n' - '\n' - ' qm_gpio_get_config(QM_GPIO_0, &cfg);\n' - '\n' - ' if (dir == schematic_direction_out) {\n' - ' cfg.direction |= BIT(SCHEMATIC_' + usage.name + ');\n' - ' } else {\n' - ' cfg.direction &= ~BIT(SCHEMATIC_' + usage.name + ');\n' - ' }\n' - '\n' - ' return qm_gpio_set_config(QM_GPIO_0, &cfg);\n' - '}') diff --git a/templates/arduino-uno.py b/templates/arduino-uno.py new file mode 100644 index 0000000..a7b4ec7 --- /dev/null +++ b/templates/arduino-uno.py @@ -0,0 +1,19 @@ +global generateHeader + +generateHeader.println(""" +namespace schematic { +""") + +usages = generateHeader.netlist.find_usages_of(generateHeader.ref) + +for usage in usages: + node = usage.node_for_ref(generateHeader.ref) + + if 7 <= node.pin <= 12: + generateHeader.println("static const int ANALOG_" + usage.name + " = " + str(node.pin - 7) + ";") + elif 13 <= node.pin <= 26: + generateHeader.println("static const int ANALOG_" + usage.name + " = " + str(node.pin - 13) + ";") + +generateHeader.println(""" +} // namespace schematic +""") diff --git a/templates/intel-quark-d2000.py b/templates/intel-quark-d2000.py new file mode 100644 index 0000000..85572c5 --- /dev/null +++ b/templates/intel-quark-d2000.py @@ -0,0 +1,69 @@ +global generateHeader +gpio_map = { + 2: '10', + 3: '11', + 4: '12', + 5: '13', + 6: '14', + 7: '15', + 8: '16', + 9: '17', + 10: '18', + + 11: '9', + 13: '20', + 14: '21', + 15: '22', + 16: '23', + 18: '19', + + 21: '24', + + 31: '0', + 32: '1', + 33: '2', + 34: '3', + 35: '4', + 36: '5', + 37: '6', + 38: '7', + 39: '8' +} + +generateHeader.println(""" +#include +#include + +enum schematic_direction { + schematic_direction_out = 1, + schematic_direction_in = 2 +}; +""") + +usages = generateHeader.netlist.find_usages_of(generateHeader.ref) + +for usage in usages: + node = usage.node_for_ref(generateHeader.ref) + + gpio = gpio_map.get(node.pin) + + if gpio is None: + continue + + generateHeader.println( + 'static const uint8_t SCHEMATIC_' + usage.name + ' = ' + gpio + ';\n' + '\n' + 'static inline\n' + 'qm_rc_t schematic_' + usage.name + '_direction(enum schematic_direction dir) {\n' + ' qm_gpio_port_config_t cfg;\n' + '\n' + ' qm_gpio_get_config(QM_GPIO_0, &cfg);\n' + '\n' + ' if (dir == schematic_direction_out) {\n' + ' cfg.direction |= BIT(SCHEMATIC_' + usage.name + ');\n' + ' } else {\n' + ' cfg.direction &= ~BIT(SCHEMATIC_' + usage.name + ');\n' + ' }\n' + '\n' + ' return qm_gpio_set_config(QM_GPIO_0, &cfg);\n' + '}') diff --git a/templates/nodemcu.py b/templates/nodemcu.py new file mode 100644 index 0000000..a7b4ec7 --- /dev/null +++ b/templates/nodemcu.py @@ -0,0 +1,19 @@ +global generateHeader + +generateHeader.println(""" +namespace schematic { +""") + +usages = generateHeader.netlist.find_usages_of(generateHeader.ref) + +for usage in usages: + node = usage.node_for_ref(generateHeader.ref) + + if 7 <= node.pin <= 12: + generateHeader.println("static const int ANALOG_" + usage.name + " = " + str(node.pin - 7) + ";") + elif 13 <= node.pin <= 26: + generateHeader.println("static const int ANALOG_" + usage.name + " = " + str(node.pin - 13) + ";") + +generateHeader.println(""" +} // namespace schematic +""") -- cgit v1.2.3