From 88737891545847276cab908499d179dbf42729c6 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 13:05:58 +0200 Subject: [PATCH 01/10] Add lemon/3.32.3 recipe --- recipes/lemon/all/CMakeLists.txt | 9 +++ recipes/lemon/all/conandata.yml | 4 ++ recipes/lemon/all/conanfile.py | 60 ++++++++++++++++ recipes/lemon/all/test_package/CMakeLists.txt | 13 ++++ recipes/lemon/all/test_package/conanfile.py | 17 +++++ recipes/lemon/all/test_package/gram.y | 71 +++++++++++++++++++ recipes/lemon/config.yml | 3 + 7 files changed, 177 insertions(+) create mode 100644 recipes/lemon/all/CMakeLists.txt create mode 100644 recipes/lemon/all/conandata.yml create mode 100644 recipes/lemon/all/conanfile.py create mode 100644 recipes/lemon/all/test_package/CMakeLists.txt create mode 100644 recipes/lemon/all/test_package/conanfile.py create mode 100644 recipes/lemon/all/test_package/gram.y create mode 100644 recipes/lemon/config.yml diff --git a/recipes/lemon/all/CMakeLists.txt b/recipes/lemon/all/CMakeLists.txt new file mode 100644 index 0000000000000..4492f0ecd9346 --- /dev/null +++ b/recipes/lemon/all/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8.14) +project(ConanLemon C) + +include(conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(lemon source_subfolder/tool/lemon.c) +install(TARGETS lemon RUNTIME DESTINATION bin) +install(FILES source_subfolder/tool/lempar.c DESTINATION bin) diff --git a/recipes/lemon/all/conandata.yml b/recipes/lemon/all/conandata.yml new file mode 100644 index 0000000000000..f5fadc9777a08 --- /dev/null +++ b/recipes/lemon/all/conandata.yml @@ -0,0 +1,4 @@ +"sources": + "3.32.3": + "url": "https://sqlite.org/2020/sqlite-src-3320300.zip" + "sha256": "9312f0865d3692384d466048f746d18f88e7ffd1758b77d4f07904e03ed5f5b9" diff --git a/recipes/lemon/all/conanfile.py b/recipes/lemon/all/conanfile.py new file mode 100644 index 0000000000000..351cd84d0dc4b --- /dev/null +++ b/recipes/lemon/all/conanfile.py @@ -0,0 +1,60 @@ +import os +from conans import CMake, ConanFile, tools + + +class LemonConan(ConanFile): + name = "lemon" + description = "The Lemon program reads a grammar of the input language and emits C-code to implement a parser for that language." + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://sqlite.org/lemon.html" + topics = ("conan", "lemon", "grammar", "lexer", "lalr", "parser", "generator", "sqlite") + license = "Public Domain" + exports_sources = "CMakeLists.txt" + settings = "os", "compiler", "arch", "build_type" + generators = "cmake" + + @property + def _source_subfolder(self): + return "source_subfolder" + + _cmake = None + + def configure(self): + del self.settings.compiler.libcxx + del self.settings.compiler.cppstd + + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + url = self.conan_data["sources"][self.version]["url"] + archive_name = os.path.basename(url) + archive_name = os.path.splitext(archive_name)[0] + os.rename(archive_name, self._source_subfolder) + + def _configure_cmake(self): + if self._cmake: + return self._cmake + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + + @property + def _lemon_exe(self): + return "lemon{}".format(".exe" if self.settings.os == "Windows" else "") + + def build(self): + cmake = self._configure_cmake() + cmake.build() + + def _extract_license_text(self): + header = tools.load(os.path.join(self._source_subfolder, "tool", "lempar.c")) + return "\n".join(line.strip(" \n*") for line in header[3:header.find("*******", 1)].splitlines()) + + def package(self): + tools.save(os.path.join(self.package_folder, "licenses", "LICENSE"), self._extract_license_text()) + cmake = self._configure_cmake() + cmake.install() + + def package_info(self): + bin_path = os.path.join(self.package_folder, "bin") + self.output.info("Appending PATH environment variable: {}".format(bin_path)) + self.env_info.PATH.append(bin_path) diff --git a/recipes/lemon/all/test_package/CMakeLists.txt b/recipes/lemon/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..288a9bc7d5d2c --- /dev/null +++ b/recipes/lemon/all/test_package/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.8.11) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_custom_command(OUTPUT gram.c gram.h + COMMAND lemon -s "${PROJECT_SOURCE_DIR}/gram.y" -d"${PROJECT_BINARY_DIR}" + BYPRODUCTS gram.out +) + +add_executable(${PROJECT_NAME} gram.c) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/lemon/all/test_package/conanfile.py b/recipes/lemon/all/test_package/conanfile.py new file mode 100644 index 0000000000000..bd7165a553cf4 --- /dev/null +++ b/recipes/lemon/all/test_package/conanfile.py @@ -0,0 +1,17 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self.settings): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) diff --git a/recipes/lemon/all/test_package/gram.y b/recipes/lemon/all/test_package/gram.y new file mode 100644 index 0000000000000..b8de662a2fdfa --- /dev/null +++ b/recipes/lemon/all/test_package/gram.y @@ -0,0 +1,71 @@ +%include { +#include +#include +} + +%extra_argument {double *res} +%token_type {double} + +res ::= expr(B). { *res = B; } +expr(A) ::= expr(B) PLUS expr(C). { A = B + C; } +expr(A) ::= expr(B) MINUS expr(C). { A = B - C; } +expr(A) ::= expr(B) TIMES expr(C). { A = B * C; } +expr(A) ::= expr(B) DIVIDE expr(C). { A = B / C;} +expr(A) ::= expr(B) MOD expr(C). { A = modf(B, &C); } +expr(A) ::= LPAREN expr(B) RPAREN. { A = B; } +expr(A) ::= VALUE(B). { A = B; } +expr(A) ::= MINUS expr(B). [UMINUS] { A = -B; } + +%left PLUS MINUS. +%left TIMES DIVIDE MOD. +%right UMINUS. + +%code { + +#include "gram.h" + +typedef struct { + int id; + double val; +} input_item_t; + +static input_item_t test_input[] = { + {VALUE, 1.}, + {PLUS, 0.}, + {VALUE, 2.}, + {PLUS, 0.}, + {VALUE, 3.}, + {TIMES, 0.}, + {VALUE, 4.}, + {TIMES, 0.}, + {VALUE, 5.}, + {TIMES, 0.}, + {LPAREN, 0.}, + {VALUE, 6.}, + {MINUS, 0.}, + {VALUE, 7.}, + {RPAREN, 0.}, + {0., 0.}, +}; + +#include +#include + +int main(int argc, char *argv) { + void *pParser = ParseAlloc(malloc); + double result = -123456.; + double val; + input_item_t *input = test_input; + while (1) { + Parse(pParser, input->id, input->val, &result); + if (input->id == 0) { + break; + } + ++input; + } + ParseFree(pParser, free); + printf("Result is %g.\n", result); + return 0; +} + +} diff --git a/recipes/lemon/config.yml b/recipes/lemon/config.yml new file mode 100644 index 0000000000000..2d5e8d76accb1 --- /dev/null +++ b/recipes/lemon/config.yml @@ -0,0 +1,3 @@ +"versions": + "3.32.3": + "folder": "all" From 261817684c408658eaa5be455a1a361216cb61bd Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 17:09:05 +0200 Subject: [PATCH 02/10] lemon: gcc accepts int main(int argc, char *argv)... --- recipes/lemon/all/test_package/gram.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/lemon/all/test_package/gram.y b/recipes/lemon/all/test_package/gram.y index b8de662a2fdfa..ffdacdab9288b 100644 --- a/recipes/lemon/all/test_package/gram.y +++ b/recipes/lemon/all/test_package/gram.y @@ -51,7 +51,7 @@ static input_item_t test_input[] = { #include #include -int main(int argc, char *argv) { +int main(int argc, const char *argv[]) { void *pParser = ParseAlloc(malloc); double result = -123456.; double val; From 72fe23956e181e09dce02e475b8b06a89b68c941 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:01:14 +0200 Subject: [PATCH 03/10] lemon: add patch to search for templates in bindir --- recipes/lemon/all/conandata.yml | 6 +- recipes/lemon/all/conanfile.py | 4 +- .../0001-use-executable-template-path.patch | 61 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 recipes/lemon/all/patches/0001-use-executable-template-path.patch diff --git a/recipes/lemon/all/conandata.yml b/recipes/lemon/all/conandata.yml index f5fadc9777a08..9614c3e605634 100644 --- a/recipes/lemon/all/conandata.yml +++ b/recipes/lemon/all/conandata.yml @@ -1,4 +1,8 @@ -"sources": +sources: "3.32.3": "url": "https://sqlite.org/2020/sqlite-src-3320300.zip" "sha256": "9312f0865d3692384d466048f746d18f88e7ffd1758b77d4f07904e03ed5f5b9" +patches: + "3.32.3": + - patch_file: "patches/0001-use-executable-template-path.patch" + base_path: "source_subfolder" diff --git a/recipes/lemon/all/conanfile.py b/recipes/lemon/all/conanfile.py index 351cd84d0dc4b..7c6cd928eb9e6 100644 --- a/recipes/lemon/all/conanfile.py +++ b/recipes/lemon/all/conanfile.py @@ -9,7 +9,7 @@ class LemonConan(ConanFile): homepage = "https://sqlite.org/lemon.html" topics = ("conan", "lemon", "grammar", "lexer", "lalr", "parser", "generator", "sqlite") license = "Public Domain" - exports_sources = "CMakeLists.txt" + exports_sources = "CMakeLists.txt", "patches/**" settings = "os", "compiler", "arch", "build_type" generators = "cmake" @@ -42,6 +42,8 @@ def _lemon_exe(self): return "lemon{}".format(".exe" if self.settings.os == "Windows" else "") def build(self): + for patch in self.conan_data.get("patches", {}).get(self.version, []): + tools.patch(**patch) cmake = self._configure_cmake() cmake.build() diff --git a/recipes/lemon/all/patches/0001-use-executable-template-path.patch b/recipes/lemon/all/patches/0001-use-executable-template-path.patch new file mode 100644 index 0000000000000..7de665813375c --- /dev/null +++ b/recipes/lemon/all/patches/0001-use-executable-template-path.patch @@ -0,0 +1,61 @@ +--- tool/lemon.c ++++ tool/lemon.c +@@ -3502,11 +3502,49 @@ + } + } + ++#ifdef _WIN32 ++# define WIN32_LEAN_AND_MEAN ++# include ++#else ++# include ++# include ++#endif ++#include ++ ++#define DEFAULT_PATH "." ++ ++static char *get_default_template_path(const char *filename) { ++ static char static_path[8192]; ++#ifdef _WIN32 ++ char joiner = '\\'; ++ int result = GetModuleFileNameA(NULL, static_path, sizeof(static_path)); ++ if (result != ERROR_SUCCESS) { ++ memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); ++ } ++#else ++ char joiner = '/'; ++ ssize_t nb = readlink("/proc/self/exe", static_path, sizeof(static_path)); ++ if (nb != -1) { ++ static_path[nb] = '\0'; ++ dirname(static_path); ++ } else { ++ memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); ++ } ++#endif ++ if (sizeof(static_path) < (strlen(static_path) + 1 + sizeof(filename) + 1)) { ++ memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); ++ return static_path; ++ } ++ strncat(static_path, &joiner, 1); ++ strncat(static_path, filename, sizeof(filename)); ++ return static_path; ++} ++ + /* The next function finds the template file and opens it, returning + ** a pointer to the opened file. */ + PRIVATE FILE *tplt_open(struct lemon *lemp) + { +- static char templatename[] = "lempar.c"; ++ char *templatename; + char buf[1000]; + FILE *in; + char *tpltname; +@@ -3530,6 +3568,7 @@ + return in; + } + ++ templatename = get_default_template_path("lempar.c"); + cp = strrchr(lemp->filename,'.'); + if( cp ){ + lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); From 5e3b9e47942f3e9cc70fceb56b66446fc8604e57 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:17:13 +0200 Subject: [PATCH 04/10] lemon: strip executable name from string --- .../0001-use-executable-template-path.patch | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/recipes/lemon/all/patches/0001-use-executable-template-path.patch b/recipes/lemon/all/patches/0001-use-executable-template-path.patch index 7de665813375c..a189d92b30734 100644 --- a/recipes/lemon/all/patches/0001-use-executable-template-path.patch +++ b/recipes/lemon/all/patches/0001-use-executable-template-path.patch @@ -1,6 +1,6 @@ --- tool/lemon.c +++ tool/lemon.c -@@ -3502,11 +3502,49 @@ +@@ -3502,11 +3502,53 @@ } } @@ -18,13 +18,17 @@ +static char *get_default_template_path(const char *filename) { + static char static_path[8192]; +#ifdef _WIN32 -+ char joiner = '\\'; ++# define JOINER "\\" + int result = GetModuleFileNameA(NULL, static_path, sizeof(static_path)); + if (result != ERROR_SUCCESS) { + memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); + } ++ char *pos = strrchr(static_path, '\\'); ++ if (pos) { ++ *pos = '\0'; ++ } +#else -+ char joiner = '/'; ++# define JOINER "/" + ssize_t nb = readlink("/proc/self/exe", static_path, sizeof(static_path)); + if (nb != -1) { + static_path[nb] = '\0'; @@ -37,7 +41,7 @@ + memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); + return static_path; + } -+ strncat(static_path, &joiner, 1); ++ strncat(static_path, JOINER, sizeof(JOINER)); + strncat(static_path, filename, sizeof(filename)); + return static_path; +} @@ -51,7 +55,7 @@ char buf[1000]; FILE *in; char *tpltname; -@@ -3530,6 +3568,7 @@ +@@ -3530,6 +3572,7 @@ return in; } From fe16920b564234bf16494b93642280d0c6d63cc1 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:34:13 +0200 Subject: [PATCH 05/10] lemon: check for error using GetLastError --- .../patches/0001-use-executable-template-path.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/recipes/lemon/all/patches/0001-use-executable-template-path.patch b/recipes/lemon/all/patches/0001-use-executable-template-path.patch index a189d92b30734..ecfebc37436f3 100644 --- a/recipes/lemon/all/patches/0001-use-executable-template-path.patch +++ b/recipes/lemon/all/patches/0001-use-executable-template-path.patch @@ -16,11 +16,12 @@ +#define DEFAULT_PATH "." + +static char *get_default_template_path(const char *filename) { -+ static char static_path[8192]; ++ static char static_path[MAX_PATH+1]; +#ifdef _WIN32 +# define JOINER "\\" ++ SetLastError(ERROR_SUCCESS); + int result = GetModuleFileNameA(NULL, static_path, sizeof(static_path)); -+ if (result != ERROR_SUCCESS) { ++ if (GetLastError() != ERROR_SUCCESS) { + memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); + } + char *pos = strrchr(static_path, '\\'); @@ -37,9 +38,8 @@ + memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); + } +#endif -+ if (sizeof(static_path) < (strlen(static_path) + 1 + sizeof(filename) + 1)) { -+ memcpy(static_path, DEFAULT_PATH, strlen(DEFAULT_PATH)); -+ return static_path; ++ if (sizeof(static_path) < (strlen(static_path) + sizeof(JOINER) + strlen(filename) + 1)) { ++ strcpy(static_path, DEFAULT_PATH); + } + strncat(static_path, JOINER, sizeof(JOINER)); + strncat(static_path, filename, sizeof(filename)); From 615b5cda4b165d04f0491ab6c86965079a29ed86 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:40:17 +0200 Subject: [PATCH 06/10] lemon: MAX_PATH is only known on Windows --- .../lemon/all/patches/0001-use-executable-template-path.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/lemon/all/patches/0001-use-executable-template-path.patch b/recipes/lemon/all/patches/0001-use-executable-template-path.patch index ecfebc37436f3..031dc360a18b7 100644 --- a/recipes/lemon/all/patches/0001-use-executable-template-path.patch +++ b/recipes/lemon/all/patches/0001-use-executable-template-path.patch @@ -16,7 +16,7 @@ +#define DEFAULT_PATH "." + +static char *get_default_template_path(const char *filename) { -+ static char static_path[MAX_PATH+1]; ++ static char static_path[8192]; +#ifdef _WIN32 +# define JOINER "\\" + SetLastError(ERROR_SUCCESS); From 8c8992a31f2f422f074f6efcfcb807c9c8be220e Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:51:00 +0200 Subject: [PATCH 07/10] lemon: aliase build_type and compiler --- recipes/lemon/all/conanfile.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recipes/lemon/all/conanfile.py b/recipes/lemon/all/conanfile.py index 7c6cd928eb9e6..19db64a912b0a 100644 --- a/recipes/lemon/all/conanfile.py +++ b/recipes/lemon/all/conanfile.py @@ -56,6 +56,10 @@ def package(self): cmake = self._configure_cmake() cmake.install() + def package_id(self): + del self.info.settings.build_type + del self.info.settings.compiler + def package_info(self): bin_path = os.path.join(self.package_folder, "bin") self.output.info("Appending PATH environment variable: {}".format(bin_path)) From 5690b0252d3d264ad0b07f7d132662fa726faa0f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 14 Jul 2020 18:58:48 +0200 Subject: [PATCH 08/10] lemon: remove unused function --- recipes/lemon/all/conanfile.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/recipes/lemon/all/conanfile.py b/recipes/lemon/all/conanfile.py index 19db64a912b0a..7dc84bb40f5c4 100644 --- a/recipes/lemon/all/conanfile.py +++ b/recipes/lemon/all/conanfile.py @@ -37,10 +37,6 @@ def _configure_cmake(self): self._cmake.configure() return self._cmake - @property - def _lemon_exe(self): - return "lemon{}".format(".exe" if self.settings.os == "Windows" else "") - def build(self): for patch in self.conan_data.get("patches", {}).get(self.version, []): tools.patch(**patch) From 474f19bfcac9e26cfa1f47995f9fcfbb8d8af1a1 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 16 Jul 2020 20:47:32 +0200 Subject: [PATCH 09/10] lemon: avoid ci building debug packages --- recipes/lemon/all/conanfile.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/recipes/lemon/all/conanfile.py b/recipes/lemon/all/conanfile.py index 7dc84bb40f5c4..0f7ae9388b6a8 100644 --- a/recipes/lemon/all/conanfile.py +++ b/recipes/lemon/all/conanfile.py @@ -52,10 +52,6 @@ def package(self): cmake = self._configure_cmake() cmake.install() - def package_id(self): - del self.info.settings.build_type - del self.info.settings.compiler - def package_info(self): bin_path = os.path.join(self.package_folder, "bin") self.output.info("Appending PATH environment variable: {}".format(bin_path)) From ba9309eb75328a04f5cdde4071a4c349d3c8362f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 17 Jul 2020 12:51:08 +0200 Subject: [PATCH 10/10] lemon: only build test_package when not cross building --- recipes/lemon/all/test_package/conanfile.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/recipes/lemon/all/test_package/conanfile.py b/recipes/lemon/all/test_package/conanfile.py index bd7165a553cf4..287e10a174c2f 100644 --- a/recipes/lemon/all/test_package/conanfile.py +++ b/recipes/lemon/all/test_package/conanfile.py @@ -7,9 +7,10 @@ class TestPackageConan(ConanFile): generators = "cmake" def build(self): - cmake = CMake(self) - cmake.configure() - cmake.build() + if not tools.cross_building(self.settings): + cmake = CMake(self) + cmake.configure() + cmake.build() def test(self): if not tools.cross_building(self.settings):