diff --git a/recipes/bison/all/conandata.yml b/recipes/bison/all/conandata.yml new file mode 100644 index 0000000000000..d3c6a0b0c557b --- /dev/null +++ b/recipes/bison/all/conandata.yml @@ -0,0 +1,14 @@ +sources: + "3.5.3": + sha256: "34e201d963156618a0ea5bc87220f660a1e08403dd3c7c7903d4f38db3f40039" + url: "https://ftp.gnu.org/gnu/bison/bison-3.5.3.tar.gz" +patches: + "3.5.3": + - patch_file: "patches/0001-create_pipe-uses-O_TEXT-not-O_BINARY-mode.patch" + base_path: "source_subfolder" + - patch_file: "patches/0002-open-source-file-in-binary-mode-MS-ftell-bug-ks-68337.patch" + base_path: "source_subfolder" + - patch_file: "patches/0003-3.5.3-msvc-changes.patch" + base_path: "source_subfolder" + - patch_file: "patches/0004-3.5.3-relocatable.patch" + base_path: "source_subfolder" diff --git a/recipes/bison/all/conanfile.py b/recipes/bison/all/conanfile.py new file mode 100644 index 0000000000000..cf99c33e9ae5a --- /dev/null +++ b/recipes/bison/all/conanfile.py @@ -0,0 +1,140 @@ +from conans import ConanFile, AutoToolsBuildEnvironment, tools +from contextlib import contextmanager +import os + + +class BisonConan(ConanFile): + name = "bison" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://www.gnu.org/software/bison/" + description = "Bison is a general-purpose parser generator" + topics = ("conan", "bison", "parser") + license = "GPL-3.0-or-later" + exports_sources = "patches/**" + + settings = "os", "arch", "compiler", "build_type" + options = { + "fPIC": [True, False], + } + default_options = { + "fPIC": True, + } + + _autotools = None + + @property + def _source_subfolder(self): + return "source_subfolder" + + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + extracted_dir = "bison-" + self.version + os.rename(extracted_dir, self._source_subfolder) + + def requirements(self): + self.requires("m4/1.4.18") + + def build_requirements(self): + if tools.os_info.is_windows and not tools.get_env("CONAN_BASH_PATH") and \ + tools.os_info.detect_windows_subsystem() != "msys2": + self.build_requires("msys2/20190524") + if self.settings.compiler == "Visual Studio": + self.build_requires("automake/1.16.1") + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + del self.settings.compiler.libcxx + del self.settings.compiler.cppstd + + @contextmanager + def _build_context(self): + if self.settings.compiler == "Visual Studio": + with tools.vcvars(self.settings): + build_env = { + "CC": "{} cl -nologo".format(tools.unix_path(self.deps_user_info["automake"].compile)), + "CXX": "{} cl -nologo".format(tools.unix_path(self.deps_user_info["automake"].compile)), + "CFLAGS": "-{}".format(self.settings.compiler.runtime), + "LD": "link", + "NM": "dumpbin -symbols", + "STRIP": ":", + "AR": "{} lib".format(tools.unix_path(self.deps_user_info["automake"].ar_lib)), + "RANLIB": ":", + } + with tools.environment_append(build_env): + yield + else: + yield + + def _configure_autotools(self): + if self._autotools: + return self._autotools + self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows) + args = [ + "--enable-relocatable", + "--disable-nls", + "--datarootdir={}".format(os.path.join(self.package_folder, "bin", "share").replace("\\", "/")), + ] + if self.settings.os == "Windows": + self._autotools.defines.append("_WINDOWS") + if self.settings.compiler == "Visual Studio": + self._autotools.flags.append("-FS") + self._autotools.configure(args=args, configure_dir=self._source_subfolder) + return self._autotools + + def _patch_sources(self): + for patch in self.conan_data["patches"][self.version]: + tools.patch(**patch) + + if self.settings.os == "Windows": + # replace embedded unix paths by windows paths + tools.replace_in_file(os.path.join(self._source_subfolder, "Makefile.in"), + "echo '#define BINDIR \"$(bindir)\"';", + "echo '#define BINDIR \"$(shell cygpath -m \"$(bindir)\")\"';") + tools.replace_in_file(os.path.join(self._source_subfolder, "Makefile.in"), + "echo '#define PKGDATADIR \"$(pkgdatadir)\"';", + "echo '#define PKGDATADIR \"$(shell cygpath -m \"$(pkgdatadir)\")\"';") + tools.replace_in_file(os.path.join(self._source_subfolder, "Makefile.in"), + "echo '#define DATADIR \"$(datadir)\"';", + "echo '#define DATADIR \"$(shell cygpath -m \"$(datadir)\")\"';") + tools.replace_in_file(os.path.join(self._source_subfolder, "Makefile.in"), + "echo '#define DATAROOTDIR \"$(datarootdir)\"';", + "echo '#define DATAROOTDIR \"$(shell cygpath -m \"$(datarootdir)\")\"';") + + tools.replace_in_file(os.path.join(self._source_subfolder, "Makefile.in"), + "dist_man_MANS = $(top_srcdir)/doc/bison.1", + "dist_man_MANS =") + tools.replace_in_file(os.path.join(self._source_subfolder, "src", "yacc.in"), + "@prefix@", + "${}_ROOT".format(self.name.upper())) + tools.replace_in_file(os.path.join(self._source_subfolder, "src", "yacc.in"), + "@bindir@", + "${}_ROOT/bin".format(self.name.upper())) + + def build(self): + self._patch_sources() + with self._build_context(): + env_build = self._configure_autotools() + env_build.make() + + def package(self): + with self._build_context(): + env_build = self._configure_autotools() + env_build.install() + self.copy(pattern="COPYING", dst="licenses", src=self._source_subfolder) + + if self.settings.compiler == "Visual Studio": + os.rename(os.path.join(self.package_folder, "lib", "liby.a"), + os.path.join(self.package_folder, "lib", "y.lib")) + + def package_info(self): + self.cpp_info.libs = ["y"] + + self.output.info('Setting BISON_ROOT environment variable: {}'.format(self.package_folder)) + self.env_info.BISON_ROOT = self.package_folder + + bindir = os.path.join(self.package_folder, "bin") + self.output.info('Appending PATH environment variable: {}'.format(bindir)) + self.env_info.PATH.append(bindir) diff --git a/recipes/bison/all/patches/0001-create_pipe-uses-O_TEXT-not-O_BINARY-mode.patch b/recipes/bison/all/patches/0001-create_pipe-uses-O_TEXT-not-O_BINARY-mode.patch new file mode 100644 index 0000000000000..9f229b7ee3cbb --- /dev/null +++ b/recipes/bison/all/patches/0001-create_pipe-uses-O_TEXT-not-O_BINARY-mode.patch @@ -0,0 +1,29 @@ +From dffa2a21edeba243ef76b75e0c2081ec15fe95bd Mon Sep 17 00:00:00 2001 +From: SSE4 +Date: Wed, 3 Apr 2019 19:48:12 +0700 +Subject: [PATCH 3/4] 0003 + +--- + lib/spawn-pipe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c +index 3af5167..09e9cad 100644 +--- a/lib/spawn-pipe.c ++++ b/lib/spawn-pipe.c +@@ -137,10 +137,10 @@ create_pipe (const char *progname, + prog_argv = prepare_spawn (prog_argv); + + if (pipe_stdout) +- if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0) ++ if (pipe2_safer (ifd, O_TEXT | O_CLOEXEC) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); + if (pipe_stdin) +- if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0) ++ if (pipe2_safer (ofd, O_TEXT | O_CLOEXEC) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); + /* Data flow diagram: + * +-- +2.7.4.windows.1 + diff --git a/recipes/bison/all/patches/0002-open-source-file-in-binary-mode-MS-ftell-bug-ks-68337.patch b/recipes/bison/all/patches/0002-open-source-file-in-binary-mode-MS-ftell-bug-ks-68337.patch new file mode 100644 index 0000000000000..faa2c494ab322 --- /dev/null +++ b/recipes/bison/all/patches/0002-open-source-file-in-binary-mode-MS-ftell-bug-ks-68337.patch @@ -0,0 +1,26 @@ +--- src/location.c ++++ src/location.c +@@ -268,6 +268,14 @@ caret_free (void) + static bool + caret_set_file (const char *file) + { ++#if defined(_WIN32) ++ /* ftell() is unusable on Windows in the face of text files ++ that use just LF and not Windows-style CR-LF as newlines ++ http://support.microsoft.com/kb/68337 */ ++ char fopen_mode[3] = "rb"; ++#else ++ char fopen_mode[2] = "r"; ++#endif + /* If a different file than before, close and let the rest open + the new one. */ + if (caret_info.pos.file && caret_info.pos.file != file) +@@ -278,7 +278,7 @@ caret_set_file (const char *file) + if (!caret_info.pos.file) + { + caret_info.pos.file = file; +- if ((caret_info.file = fopen (caret_info.pos.file, "r"))) ++ if ((caret_info.file = fopen (caret_info.pos.file, fopen_mode))) + { + /* If the file is not regular (imagine #line 1 "/dev/stdin" + in the input file for instance), don't try to quote the diff --git a/recipes/bison/all/patches/0003-3.5.3-msvc-changes.patch b/recipes/bison/all/patches/0003-3.5.3-msvc-changes.patch new file mode 100644 index 0000000000000..3e04d6ae94ee5 --- /dev/null +++ b/recipes/bison/all/patches/0003-3.5.3-msvc-changes.patch @@ -0,0 +1,261 @@ +src/parse-gram.y and src/scan-gram.l should be modified as well, +but aren't to avoid a dependency on a already-built flex and bison. + +--- src/location.c ++++ src/location.c +@@ -25,9 +25,13 @@ + #include + #include + #include /* fileno */ ++#if !defined(_WINDOWS) + #include ++#endif + #include /* fstat */ ++#if !defined(_WINDOWS) + #include ++#endif + + #ifdef WINSIZE_IN_PTEM + # include +--- src/parse-gram.c ++++ src/parse-gram.c +@@ -991,7 +991,7 @@ tron (yyo); + + case 43: /* "character literal" */ + #line 217 "src/parse-gram.y" +- { fputs (char_name (((*yyvaluep).CHAR)), yyo); } ++ { fputs (char_name (((*yyvaluep).CHAR_LITERAL)), yyo); } + #line 996 "src/parse-gram.c" + break; + +@@ -1027,7 +1027,7 @@ tron (yyo); + + case 56: /* "integer" */ + #line 234 "src/parse-gram.y" +- { fprintf (yyo, "%d", ((*yyvaluep).INT)); } ++ { fprintf (yyo, "%d", ((*yyvaluep).INTEGER)); } + #line 1032 "src/parse-gram.c" + break; + +@@ -2216,13 +2216,13 @@ yyreduce: + + case 12: + #line 330 "src/parse-gram.y" +- { expected_sr_conflicts = (yyvsp[0].INT); } ++ { expected_sr_conflicts = (yyvsp[0].INTEGER); } + #line 2221 "src/parse-gram.c" + break; + + case 13: + #line 331 "src/parse-gram.y" +- { expected_rr_conflicts = (yyvsp[0].INT); } ++ { expected_rr_conflicts = (yyvsp[0].INTEGER); } + #line 2227 "src/parse-gram.c" + break; + +@@ -2775,7 +2775,7 @@ yyreduce: + + case 102: + #line 679 "src/parse-gram.y" +- { grammar_current_rule_dprec_set ((yyvsp[0].INT), (yylsp[0])); } ++ { grammar_current_rule_dprec_set ((yyvsp[0].INTEGER), (yylsp[0])); } + #line 2780 "src/parse-gram.c" + break; + +@@ -2787,13 +2787,13 @@ yyreduce: + + case 104: + #line 683 "src/parse-gram.y" +- { grammar_current_rule_expect_sr ((yyvsp[0].INT), (yylsp[0])); } ++ { grammar_current_rule_expect_sr ((yyvsp[0].INTEGER), (yylsp[0])); } + #line 2792 "src/parse-gram.c" + break; + + case 105: + #line 685 "src/parse-gram.y" +- { grammar_current_rule_expect_rr ((yyvsp[0].INT), (yylsp[0])); } ++ { grammar_current_rule_expect_rr ((yyvsp[0].INTEGER), (yylsp[0])); } + #line 2798 "src/parse-gram.c" + break; + +@@ -2860,9 +2860,9 @@ yyreduce: + complain_indent (&loc, complaint, &indent, + _("definition of %s"), var); + } +- (yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR)), (yylsp[0])); ++ (yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR_LITERAL)), (yylsp[0])); + symbol_class_set ((yyval.id), token_sym, (yylsp[0]), false); +- symbol_user_token_number_set ((yyval.id), (yyvsp[0].CHAR), (yylsp[0])); ++ symbol_user_token_number_set ((yyval.id), (yyvsp[0].CHAR_LITERAL), (yylsp[0])); + } + #line 2868 "src/parse-gram.c" + break; +--- src/parse-gram.h ++++ src/parse-gram.h +@@ -122,7 +122,7 @@ extern int gram_debug; + BRACED_CODE = 40, + BRACED_PREDICATE = 41, + BRACKETED_ID = 42, +- CHAR = 43, ++ CHAR_LITERAL = 43, + COLON = 44, + EPILOGUE = 45, + EQUAL = 46, +@@ -135,7 +135,7 @@ extern int gram_debug; + TAG = 53, + TAG_ANY = 54, + TAG_NONE = 55, +- INT = 56, ++ INTEGER = 56, + PERCENT_PARAM = 57, + PERCENT_UNION = 58, + PERCENT_EMPTY = 59 +@@ -162,7 +162,7 @@ union GRAM_STYPE + /* code_props_type */ + code_props_type code_props_type; + /* "integer" */ +- int INT; ++ int INTEGER; + /* int.opt */ + int yytype_81; + /* named_ref.opt */ +@@ -226,7 +226,7 @@ union GRAM_STYPE + /* variable */ + uniqstr variable; + /* "character literal" */ +- unsigned char CHAR; ++ unsigned char CHAR_LITERAL; + /* value */ + value_type value; + #line 233 "src/parse-gram.h" +--- src/reader.c ++++ src/reader.c +@@ -803,7 +803,7 @@ check_and_convert_grammar (void) + + $accept: %start $end. */ + { +- symbol_list *p = symbol_list_sym_new (accept, empty_loc); ++ symbol_list *p = symbol_list_sym_new (bison_accept, empty_loc); + p->rhs_loc = grammar->rhs_loc; + p->next = symbol_list_sym_new (startsymbol, empty_loc); + p->next->next = symbol_list_sym_new (endtoken, empty_loc); +--- src/reduce.c ++++ src/reduce.c +@@ -160,9 +160,9 @@ inaccessable_symbols (void) + bitset Pp = bitset_create (nrules, BITSET_FIXED); + + /* If the start symbol isn't useful, then nothing will be useful. */ +- if (bitset_test (N, accept->content->number - ntokens)) ++ if (bitset_test (N, bison_accept->content->number - ntokens)) + { +- bitset_set (V, accept->content->number); ++ bitset_set (V, bison_accept->content->number); + + while (1) + { +@@ -301,7 +301,7 @@ nonterminals_reduce (void) + for (item_number *rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp) + if (ISVAR (*rhsp)) + *rhsp = symbol_number_as_item_number (nterm_map[*rhsp - ntokens]); +- accept->content->number = nterm_map[accept->content->number - ntokens]; ++ bison_accept->content->number = nterm_map[bison_accept->content->number - ntokens]; + } + + nsyms -= nuseless_nonterminals; +@@ -381,7 +381,7 @@ reduce_grammar (void) + { + reduce_print (); + +- if (!bitset_test (N, accept->content->number - ntokens)) ++ if (!bitset_test (N, bison_accept->content->number - ntokens)) + complain (&startsymbol_loc, fatal, + _("start symbol %s does not derive any sentence"), + startsymbol->tag); +--- src/scan-gram.c ++++ src/scan-gram.c +@@ -2223,12 +2223,12 @@ YY_RULE_SETUP + case 65: + YY_RULE_SETUP + #line 308 "/Users/akim/src/gnu/bison/src/scan-gram.l" +-RETURN_VALUE (INT, scan_integer (yytext, 10, *loc)); ++RETURN_VALUE (INTEGER, scan_integer (yytext, 10, *loc)); + YY_BREAK + case 66: + YY_RULE_SETUP + #line 309 "/Users/akim/src/gnu/bison/src/scan-gram.l" +-RETURN_VALUE (INT, scan_integer (yytext, 16, *loc)); ++RETURN_VALUE (INTEGER, scan_integer (yytext, 16, *loc)); + YY_BREAK + /* Identifiers may not start with a digit. Yet, don't silently + accept "1FOO" as "1 FOO". */ +@@ -2575,21 +2575,21 @@ YY_RULE_SETUP + { + STRING_FINISH; + loc->start = token_start; +- val->CHAR = last_string[0]; ++ val->CHAR_LITERAL = last_string[0]; + + /* FIXME: Eventually, make these errors. */ + if (last_string[0] == '\0') + { + complain (loc, Wother, _("empty character literal")); + /* '\0' seems dangerous even if we are about to complain. */ +- val->CHAR = '\''; ++ val->CHAR_LITERAL = '\''; + } + else if (last_string[1] != '\0') + complain (loc, Wother, + _("extra characters in character literal")); + STRING_FREE; + BEGIN INITIAL; +- return CHAR; ++ return CHAR_LITERAL; + } + YY_BREAK + case 95: +--- src/symtab.c ++++ src/symtab.c +@@ -52,7 +52,7 @@ static semantic_type **semantic_types_sorted = NULL; + symbol *errtoken = NULL; + symbol *undeftoken = NULL; + symbol *endtoken = NULL; +-symbol *accept = NULL; ++symbol *bison_accept = NULL; + symbol *startsymbol = NULL; + location startsymbol_loc; + +@@ -843,9 +843,9 @@ symbols_new (void) + symbol_free); + + /* Construct the accept symbol. */ +- accept = symbol_get ("$accept", empty_loc); +- accept->content->class = nterm_sym; +- accept->content->number = nvars++; ++ bison_accept = symbol_get ("$accept", empty_loc); ++ bison_accept->content->class = nterm_sym; ++ bison_accept->content->number = nvars++; + + /* Construct the error token */ + errtoken = symbol_get ("error", empty_loc); +--- src/symtab.h ++++ src/symtab.h +@@ -248,7 +248,7 @@ extern symbol *endtoken; + /** The genuine start symbol. + + $accept: start-symbol $end */ +-extern symbol *accept; ++extern symbol *bison_accept; + + /** The user start symbol. */ + extern symbol *startsymbol; +--- src/ielr.c ++++ src/ielr.c +@@ -429,7 +429,7 @@ + check all predecessors' goto follows for the LHS. */ + if (item_number_is_rule_number (ritem[s->items[item] - 2])) + { +- aver (lhs != accept->content->number); ++ aver (lhs != bison_accept->content->number); + for (state **predecessor = predecessors[s->number]; + *predecessor; + ++predecessor) diff --git a/recipes/bison/all/patches/0004-3.5.3-relocatable.patch b/recipes/bison/all/patches/0004-3.5.3-relocatable.patch new file mode 100644 index 0000000000000..90e68721739be --- /dev/null +++ b/recipes/bison/all/patches/0004-3.5.3-relocatable.patch @@ -0,0 +1,753 @@ +--- Makefile.in ++++ Makefile.in +@@ -637,10 +637,10 @@ am_src_bison_OBJECTS = src/bison-AnnotationList.$(OBJEXT) \ + src/bison-main.$(OBJEXT) src/bison-muscle-tab.$(OBJEXT) \ + src/bison-named-ref.$(OBJEXT) src/bison-nullable.$(OBJEXT) \ + src/bison-output.$(OBJEXT) src/bison-parse-gram.$(OBJEXT) \ +- src/bison-print-graph.$(OBJEXT) src/bison-print-xml.$(OBJEXT) \ +- src/bison-print.$(OBJEXT) src/bison-reader.$(OBJEXT) \ +- src/bison-reduce.$(OBJEXT) src/bison-relation.$(OBJEXT) \ +- src/bison-scan-code-c.$(OBJEXT) \ ++ src/bison-pathtools.$(OBJEXT) src/bison-print-graph.$(OBJEXT) \ ++ src/bison-print-xml.$(OBJEXT) src/bison-print.$(OBJEXT) \ ++ src/bison-reader.$(OBJEXT) src/bison-reduce.$(OBJEXT) \ ++ src/bison-relation.$(OBJEXT) src/bison-scan-code-c.$(OBJEXT) \ + src/bison-scan-gram-c.$(OBJEXT) \ + src/bison-scan-skel-c.$(OBJEXT) src/bison-state.$(OBJEXT) \ + src/bison-symlist.$(OBJEXT) src/bison-symtab.$(OBJEXT) \ +@@ -878,6 +878,7 @@ am__depfiles_remade = examples/c++/$(DEPDIR)/simple-simple.Po \ + src/$(DEPDIR)/bison-named-ref.Po \ + src/$(DEPDIR)/bison-nullable.Po src/$(DEPDIR)/bison-output.Po \ + src/$(DEPDIR)/bison-parse-gram.Po \ ++ src/$(DEPDIR)/bison-pathtools.Po \ + src/$(DEPDIR)/bison-print-graph.Po \ + src/$(DEPDIR)/bison-print-xml.Po src/$(DEPDIR)/bison-print.Po \ + src/$(DEPDIR)/bison-reader.Po src/$(DEPDIR)/bison-reduce.Po \ +@@ -3169,6 +3170,8 @@ src_bison_SOURCES = \ + src/output.c \ + src/output.h \ + src/parse-gram.y \ ++ src/pathtools.c \ ++ src/pathtools.h \ + src/print-graph.c \ + src/print-graph.h \ + src/print-xml.c \ +@@ -3992,6 +3995,8 @@ src/bison-output.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + src/bison-parse-gram.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) ++src/bison-pathtools.$(OBJEXT): src/$(am__dirstamp) \ ++ src/$(DEPDIR)/$(am__dirstamp) + src/bison-print-graph.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + src/bison-print-xml.$(OBJEXT): src/$(am__dirstamp) \ +@@ -4317,6 +4322,7 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-nullable.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-output.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-parse-gram.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-pathtools.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-print-graph.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-print-xml.Po@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bison-print.Po@am__quote@ # am--include-marker +@@ -7283,6 +7289,20 @@ src/bison-parse-gram.obj: src/parse-gram.c + @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -c -o src/bison-parse-gram.obj `if test -f 'src/parse-gram.c'; then $(CYGPATH_W) 'src/parse-gram.c'; else $(CYGPATH_W) '$(srcdir)/src/parse-gram.c'; fi` + ++src/bison-pathtools.o: src/pathtools.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -MT src/bison-pathtools.o -MD -MP -MF src/$(DEPDIR)/bison-pathtools.Tpo -c -o src/bison-pathtools.o `test -f 'src/pathtools.c' || echo '$(srcdir)/'`src/pathtools.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/bison-pathtools.Tpo src/$(DEPDIR)/bison-pathtools.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pathtools.c' object='src/bison-pathtools.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -c -o src/bison-pathtools.o `test -f 'src/pathtools.c' || echo '$(srcdir)/'`src/pathtools.c ++ ++src/bison-pathtools.obj: src/pathtools.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -MT src/bison-pathtools.obj -MD -MP -MF src/$(DEPDIR)/bison-pathtools.Tpo -c -o src/bison-pathtools.obj `if test -f 'src/pathtools.c'; then $(CYGPATH_W) 'src/pathtools.c'; else $(CYGPATH_W) '$(srcdir)/src/pathtools.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/bison-pathtools.Tpo src/$(DEPDIR)/bison-pathtools.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pathtools.c' object='src/bison-pathtools.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -c -o src/bison-pathtools.obj `if test -f 'src/pathtools.c'; then $(CYGPATH_W) 'src/pathtools.c'; else $(CYGPATH_W) '$(srcdir)/src/pathtools.c'; fi` ++ + src/bison-print-graph.o: src/print-graph.c + @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_bison_CPPFLAGS) $(CPPFLAGS) $(src_bison_CFLAGS) $(CFLAGS) -MT src/bison-print-graph.o -MD -MP -MF src/$(DEPDIR)/bison-print-graph.Tpo -c -o src/bison-print-graph.o `test -f 'src/print-graph.c' || echo '$(srcdir)/'`src/print-graph.c + @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/bison-print-graph.Tpo src/$(DEPDIR)/bison-print-graph.Po +@@ -9079,6 +9099,7 @@ distclean: distclean-recursive + -rm -f src/$(DEPDIR)/bison-nullable.Po + -rm -f src/$(DEPDIR)/bison-output.Po + -rm -f src/$(DEPDIR)/bison-parse-gram.Po ++ -rm -f src/$(DEPDIR)/bison-pathtools.Po + -rm -f src/$(DEPDIR)/bison-print-graph.Po + -rm -f src/$(DEPDIR)/bison-print-xml.Po + -rm -f src/$(DEPDIR)/bison-print.Po +@@ -9464,6 +9485,7 @@ maintainer-clean: maintainer-clean-recursive + -rm -f src/$(DEPDIR)/bison-nullable.Po + -rm -f src/$(DEPDIR)/bison-output.Po + -rm -f src/$(DEPDIR)/bison-parse-gram.Po ++ -rm -f src/$(DEPDIR)/bison-pathtools.Po + -rm -f src/$(DEPDIR)/bison-print-graph.Po + -rm -f src/$(DEPDIR)/bison-print-xml.Po + -rm -f src/$(DEPDIR)/bison-print.Po +--- src/files.c ++++ src/files.c +@@ -1,4 +1,5 @@ + /* Open and close files for Bison. ++ rse-gram.Po + + Copyright (C) 1984, 1986, 1989, 1992, 2000-2015, 2018-2020 Free + Software Foundation, Inc. +@@ -35,6 +36,7 @@ + #include "files.h" + #include "getargs.h" + #include "gram.h" ++#include "pathtools.h" + + /* Initializing some values below (such SPEC_NAME_PREFIX to 'yy') is + tempting, but don't do that: for the time being our handling of the +@@ -417,7 +419,11 @@ pkgdatadir (void) + else + { + char const *cp = getenv ("BISON_PKGDATADIR"); +- return cp ? cp : relocate2 (PKGDATADIR, &relocate_buffer); ++ if (cp) { ++ return cp; ++ } ++ const char *_dir = single_path_relocation(BINDIR, PKGDATADIR); ++ return _dir; + } + } + +--- src/local.mk ++++ src/local.mk +@@ -71,6 +71,8 @@ src_bison_SOURCES = \ + src/output.c \ + src/output.h \ + src/parse-gram.y \ ++ src/pathtools.c \ ++ src/pathtools.h \ + src/print-graph.c \ + src/print-graph.h \ + src/print-xml.c \ +--- src/output.c ++++ src/output.c +@@ -21,6 +21,7 @@ + #include + #include "system.h" + ++#include + #include /* IS_PATH_WITH_DIR */ + #include + #include +@@ -41,6 +42,7 @@ + #include "scan-skel.h" + #include "symtab.h" + #include "tables.h" ++#include "pathtools.h" + + static struct obstack format_obstack; + +@@ -573,7 +575,7 @@ static void + output_skeleton (void) + { + /* Compute the names of the package data dir and skeleton files. */ +- char const *m4 = (m4 = getenv ("M4")) ? m4 : M4; ++ char const *m4 = (m4 = getenv ("M4")) ? m4 : "m4" EXEEXT; //single_path_relocation(BINDIR, M4); + char const *datadir = pkgdatadir (); + char *skeldir = xpath_join (datadir, "skeletons"); + char *m4sugar = xpath_join (datadir, "m4sugar/m4sugar.m4"); +--- /dev/null ++++ src/pathtools.c +@@ -0,0 +1,536 @@ ++/* ++ .Some useful path tools. ++ .ASCII only for now. ++ .Written by Ray Donnelly in 2014. ++ .Licensed under CC0 (and anything. ++ .else you need to license it under). ++ .No warranties whatsoever. ++ .email: . ++ */ ++ ++#include "config.h" ++#if defined(__APPLE__) ++#include ++#else ++#include ++#include ++#endif ++#include ++#include ++#include ++#if defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__) ++#include ++#endif ++#include ++ ++#ifndef PATH_MAX ++#define PATH_MAX 4096 ++#endif ++ ++/* If you don't define this, then get_executable_path() ++ can only use argv[0] which will often not work well */ ++#define IMPLEMENT_SYS_GET_EXECUTABLE_PATH ++ ++#if defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH) ++#if defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__) || defined(_MSC_VER) ++/* Nothing needed, unistd.h is enough. */ ++#elif defined(__APPLE__) ++#include ++#elif defined(_WIN32) ++#define WIN32_MEAN_AND_LEAN ++#include ++#include ++#endif ++#endif /* defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH) */ ++ ++#include "pathtools.h" ++ ++char * ++malloc_copy_string(char const * original) ++{ ++ char * result = (char *) malloc (sizeof (char*) * strlen (original)+1); ++ if (result != NULL) ++ { ++ strcpy (result, original); ++ } ++ return result; ++} ++ ++void ++sanitise_path(char * path) ++{ ++ size_t path_size = strlen (path); ++ ++ /* Replace any '\' with '/' */ ++ char * path_p = path; ++ while ((path_p = strchr (path_p, '\\')) != NULL) ++ { ++ *path_p = '/'; ++ } ++ /* Replace any '//' with '/' */ ++ path_p = path; ++ while ((path_p = strstr (path_p, "//")) != NULL) ++ { ++ memmove (path_p, path_p + 1, path_size--); ++ } ++ return; ++} ++ ++char * ++get_relative_path(char const * from_in, char const * to_in) ++{ ++ size_t from_size = (from_in == NULL) ? 0 : strlen (from_in); ++ size_t to_size = (to_in == NULL) ? 0 : strlen (to_in); ++ size_t max_size = (from_size + to_size) * 2 + 4; ++ char * scratch_space = (char *) alloca (from_size + 1 + to_size + 1 + max_size + max_size); ++ char * from; ++ char * to; ++ char * common_part; ++ char * result; ++ size_t count; ++ ++ /* No to, return "./" */ ++ if (to_in == NULL) ++ { ++ return malloc_copy_string ("./"); ++ } ++ ++ /* If alloca failed or no from was given return a copy of to */ ++ if ( from_in == NULL ++ || scratch_space == NULL ) ++ { ++ return malloc_copy_string (to_in); ++ } ++ ++ from = scratch_space; ++ strcpy (from, from_in); ++ to = from + from_size + 1; ++ strcpy (to, to_in); ++ common_part = to + to_size + 1; ++ result = common_part + max_size; ++ simplify_path (from); ++ simplify_path (to); ++ ++ result[0] = '\0'; ++ ++ size_t match_size_dirsep = 0; /* The match size up to the last /. Always wind back to this - 1 */ ++ size_t match_size = 0; /* The running (and final) match size. */ ++ size_t largest_size = (from_size > to_size) ? from_size : to_size; ++ int to_final_is_slash = (to[to_size-1] == '/') ? 1 : 0; ++ char from_c; ++ char to_c; ++ for (match_size = 0; match_size < largest_size; ++match_size) ++ { ++ /* To simplify the logic, always pretend the strings end with '/' */ ++ from_c = (match_size < from_size) ? from[match_size] : '/'; ++ to_c = (match_size < to_size) ? to[match_size] : '/'; ++ ++ if (from_c != to_c) ++ { ++ if (from_c != '\0' || to_c != '\0') ++ { ++ match_size = match_size_dirsep; ++ } ++ break; ++ } ++ else if (from_c == '/') ++ { ++ match_size_dirsep = match_size; ++ } ++ } ++ strncpy (common_part, from, match_size); ++ common_part[match_size] = '\0'; ++ from += match_size; ++ to += match_size; ++ size_t ndotdots = 0; ++ char const* from_last = from + strlen(from) - 1; ++ while ((from = strchr (from, '/')) && from != from_last) ++ { ++ ++ndotdots; ++ ++from; ++ } ++ for (count = 0; count < ndotdots; ++count) ++ { ++ strcat(result, "../"); ++ } ++ if (strlen(to) > 0) ++ { ++ strcat(result, to+1); ++ } ++ /* Make sure that if to ends with '/' result does the same, and ++ vice-versa. */ ++ size_t size_result = strlen(result); ++ if ((to_final_is_slash == 1) ++ && (!size_result || result[size_result-1] != '/')) ++ { ++ strcat (result, "/"); ++ } ++ else if (!to_final_is_slash ++ && size_result && result[size_result-1] == '/') ++ { ++ result[size_result-1] = '\0'; ++ } ++ ++ return malloc_copy_string (result); ++} ++ ++void ++simplify_path(char * path) ++{ ++ ssize_t n_toks = 1; /* in-case we need an empty initial token. */ ++ ssize_t i, j; ++ size_t tok_size; ++ size_t in_size = strlen (path); ++ int it_ended_with_a_slash = (path[in_size - 1] == '/') ? 1 : 0; ++ char * result = path; ++ sanitise_path(result); ++ char * result_p = result; ++ ++ do ++ { ++ ++n_toks; ++ ++result_p; ++ } while ((result_p = strchr (result_p, '/')) != NULL); ++ ++ result_p = result; ++ char ** toks = (char **) alloca (sizeof (char const*) * n_toks); ++ n_toks = 0; ++ do ++ { ++ if (result_p > result) ++ { ++ *result_p++ = '\0'; ++ } ++ else if (*result_p == '/') ++ { ++ /* A leading / creates an empty initial token. */ ++ toks[n_toks++] = result_p; ++ *result_p++ = '\0'; ++ } ++ toks[n_toks++] = result_p; ++ } while ((result_p = strchr (result_p, '/')) != NULL); ++ ++ /* Remove all non-leading '.' and any '..' we can match ++ with an earlier forward path (i.e. neither '.' nor '..') */ ++ for (i = 1; i < n_toks; ++i) ++ { ++ int removals[2] = { -1, -1 }; ++ if ( strcmp (toks[i], "." ) == 0) ++ { ++ removals[0] = i; ++ } ++ else if ( strcmp (toks[i], ".." ) == 0) ++ { ++ /* Search backwards for a forward path to collapse. ++ If none are found then the .. also stays. */ ++ for (j = i - 1; j > -1; --j) ++ { ++ if ( strcmp (toks[j], "." ) ++ && strcmp (toks[j], ".." ) ) ++ { ++ removals[0] = j; ++ removals[1] = i; ++ break; ++ } ++ } ++ } ++ for (j = 0; j < 2; ++j) ++ { ++ if (removals[j] >= 0) /* Can become -2 */ ++ { ++ --n_toks; ++ memmove (&toks[removals[j]], &toks[removals[j]+1], (n_toks - removals[j])*sizeof (char*)); ++ --i; ++ if (!j) ++ { ++ --removals[1]; ++ } ++ } ++ } ++ } ++ result_p = result; ++ for (i = 0; i < n_toks; ++i) ++ { ++ tok_size = strlen(toks[i]); ++ memcpy (result_p, toks[i], tok_size); ++ result_p += tok_size; ++ if ((!i || tok_size) && ((i < n_toks - 1) || it_ended_with_a_slash == 1)) ++ { ++ *result_p = '/'; ++ ++result_p; ++ } ++ } ++ *result_p = '\0'; ++} ++ ++/* Returns actual_to by calculating the relative path from -> to and ++ applying that to actual_from. An assumption that actual_from is a ++ dir is made, and it may or may not end with a '/' */ ++char const * ++get_relocated_path (char const * from, char const * to, char const * actual_from) ++{ ++ char const * relative_from_to = get_relative_path (from, to); ++ char * actual_to = (char *) malloc (strlen(actual_from) + 2 + strlen(relative_from_to)); ++ return actual_to; ++} ++ ++int ++get_executable_path(char const * argv0, char * result, ssize_t max_size) ++{ ++ char * system_result = (char *) alloca (max_size); ++ ssize_t system_result_size = -1; ++ ssize_t result_size = -1; ++ ++ if (system_result != NULL) ++ { ++#if defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH) ++#if defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__) ++ system_result_size = readlink("/proc/self/exe", system_result, max_size); ++#elif defined(__APPLE__) ++ uint32_t bufsize = (uint32_t)max_size; ++ if (_NSGetExecutablePath(system_result, &bufsize) == 0) ++ { ++ system_result_size = (ssize_t)bufsize; ++ } ++#elif defined(_WIN32) ++ unsigned long bufsize = (unsigned long)max_size; ++ system_result_size = GetModuleFileNameA(NULL, system_result, bufsize); ++ if (system_result_size == 0 || system_result_size == (ssize_t)bufsize) ++ { ++ /* Error, possibly not enough space. */ ++ system_result_size = -1; ++ } ++ else ++ { ++ /* Early conversion to unix slashes instead of more changes ++ everywhere else .. */ ++ char * winslash; ++ system_result[system_result_size] = '\0'; ++ while ((winslash = strchr (system_result, '\\')) != NULL) ++ { ++ *winslash = '/'; ++ } ++ } ++#else ++#warning "Don't know how to get executable path on this system" ++#endif ++#endif /* defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH) */ ++ } ++ /* Use argv0 as a default in-case of failure */ ++ if (system_result_size != -1) ++ { ++ strncpy (result, system_result, system_result_size); ++ result[system_result_size] = '\0'; ++ } ++ else ++ { ++ if (argv0 != NULL) ++ { ++ strncpy (result, argv0, max_size); ++ result[max_size-1] = '\0'; ++ } ++ else ++ { ++ result[0] = '\0'; ++ } ++ } ++ result_size = strlen (result); ++ return result_size; ++} ++ ++char const * ++strip_n_prefix_folders(char const * path, size_t n) ++{ ++ if (path == NULL) ++ { ++ return NULL; ++ } ++ ++ if (path[0] != '/') ++ { ++ return path; ++ } ++ ++ char const * last = path; ++ while (n-- && path != NULL) ++ { ++ last = path; ++ path = strchr (path + 1, '/'); ++ } ++ return (path == NULL) ? last : path; ++} ++ ++void ++strip_n_suffix_folders(char * path, size_t n) ++{ ++ if (path == NULL) ++ { ++ return; ++ } ++ while (n--) ++ { ++ if (strrchr (path + 1, '/')) ++ { ++ *strrchr (path + 1, '/') = '\0'; ++ } ++ else ++ { ++ return; ++ } ++ } ++ return; ++} ++ ++size_t ++split_path_list(char const * path_list, char split_char, char *** arr) ++{ ++ size_t path_count; ++ size_t path_list_size; ++ char const * path_list_p; ++ ++ path_list_p = path_list; ++ if (path_list == NULL || path_list[0] == '\0') ++ { ++ return 0; ++ } ++ path_list_size = strlen (path_list); ++ ++ path_count = 0; ++ do ++ { ++ ++path_count; ++ ++path_list_p; ++ } ++ while ((path_list_p = strchr (path_list_p, split_char)) != NULL); ++ ++ /* allocate everything in one go. */ ++ char * all_memory = (char *) malloc (sizeof (char *) * path_count + strlen(path_list) + 1); ++ if (all_memory == NULL) ++ return 0; ++ *arr = (char **)all_memory; ++ all_memory += sizeof (char *) * path_count; ++ ++ path_count = 0; ++ path_list_p = path_list; ++ char const * next_path_list_p = 0; ++ do ++ { ++ next_path_list_p = strchr (path_list_p, split_char); ++ if (next_path_list_p != NULL) ++ { ++ ++next_path_list_p; ++ } ++ size_t this_size = (next_path_list_p != NULL) ++ ? next_path_list_p - path_list_p - 1 ++ : &path_list[path_list_size] - path_list_p; ++ memcpy (all_memory, path_list_p, this_size); ++ all_memory[this_size] = '\0'; ++ (*arr)[path_count++] = all_memory; ++ all_memory += this_size + 1; ++ } while ((path_list_p = next_path_list_p) != NULL); ++ ++ return path_count; ++} ++ ++char * ++get_relocated_path_list(char const * from, char const * to_path_list) ++{ ++ char exe_path[32768]; ++ char * temp; ++ get_executable_path (NULL, &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0])); ++ if ((temp = strrchr (exe_path, '/')) != NULL) ++ { ++ temp[1] = '\0'; ++ } ++ ++ char **arr = NULL; ++ /* Ask Alexey why he added this. Are we not 100% sure ++ that we're dealing with unix paths here? */ ++ char split_char = ':'; ++ if (strchr (to_path_list, ';')) ++ { ++ split_char = ';'; ++ } ++ size_t count = split_path_list (to_path_list, split_char, &arr); ++ int result_size = 1 + (count - 1); /* count - 1 is for ; delim. */ ++ size_t exe_path_size = strlen (exe_path); ++ size_t i; ++ /* Space required is: ++ count * (exe_path_size + strlen (rel_to_datadir)) ++ rel_to_datadir upper bound is: ++ (count * strlen (from)) + (3 * num_slashes (from)) ++ + strlen(arr[i]) + 1. ++ .. pathalogically num_slashes (from) is strlen (from) ++ (from = ////////) */ ++ size_t space_required = (count * (exe_path_size + 4 * strlen (from))) + count - 1; ++ for (i = 0; i < count; ++i) ++ { ++ space_required += strlen (arr[i]); ++ } ++ char * scratch = (char *) alloca (space_required); ++ if (scratch == NULL) ++ return NULL; ++ for (i = 0; i < count; ++i) ++ { ++ char * rel_to_datadir = get_relative_path (from, arr[i]); ++ scratch[0] = '\0'; ++ arr[i] = scratch; ++ strcat (scratch, exe_path); ++ strcat (scratch, rel_to_datadir); ++ simplify_path (arr[i]); ++ size_t arr_i_size = strlen (arr[i]); ++ result_size += arr_i_size; ++ scratch = arr[i] + arr_i_size + 1; ++ } ++ char * result = (char *) malloc (result_size); ++ if (result == NULL) ++ { ++ return NULL; ++ } ++ result[0] = '\0'; ++ for (i = 0; i < count; ++i) ++ { ++ strcat (result, arr[i]); ++ if (i != count-1) ++ { ++#if defined(_WIN32) ++ strcat (result, ";"); ++#else ++ strcat (result, ":"); ++#endif ++ } ++ } ++ free ((void*)arr); ++ return result; ++} ++ ++char * ++single_path_relocation(const char *from, const char *to) ++{ ++ char exe_path[PATH_MAX]; ++ get_executable_path (NULL, &exe_path[0], sizeof(exe_path)/sizeof(exe_path[0])); ++ if (strrchr (exe_path, '/') != NULL) ++ { ++ strrchr (exe_path, '/')[1] = '\0'; ++ } ++ char * rel_to_datadir = get_relative_path (from, to); ++ strcat (exe_path, rel_to_datadir); ++ simplify_path (&exe_path[0]); ++ return malloc_copy_string(exe_path); ++} ++ ++char * ++pathlist_relocation(const char *from_path, const char *to_path_list) ++{ ++ static char stored_path[PATH_MAX]; ++ static int stored = 0; ++ if (stored == 0) ++ { ++ char const * relocated = get_relocated_path_list(from_path, to_path_list); ++ strncpy (stored_path, relocated, PATH_MAX); ++ stored_path[PATH_MAX-1] = '\0'; ++ free ((void *)relocated); ++ stored = 1; ++ } ++ return stored_path; ++} +--- /dev/null ++++ src/pathtools.h +@@ -0,0 +1,53 @@ ++/* ++ .Some useful path tools. ++ .ASCII only for now. ++ .Written by Ray Donnelly in 2014. ++ .Licensed under CC0 (and anything. ++ .else you need to license it under). ++ .No warranties whatsoever. ++ .email: . ++ */ ++ ++#ifndef PATHTOOLS_H ++#define PATHTOOLS_H ++ ++#include ++#if defined(__APPLE__) ++#include ++#else ++#include ++#endif ++#include ++ ++char * malloc_copy_string(char const * original); ++ ++/* In-place replaces any '\' with '/' and any '//' with '/' */ ++void sanitise_path(char * path); ++ ++/* Uses a host OS specific function to determine the path of the executable, ++ if IMPLEMENT_SYS_GET_EXECUTABLE_PATH is defined, otherwise uses argv0. */ ++int get_executable_path(char const * argv0, char * result, ssize_t max_size); ++ ++/* Where possible, in-place removes occourances of '.' and 'path/..' */ ++void simplify_path(char * path); ++ ++/* Allocates (via malloc) and returns the path to get from from to to. */ ++char * get_relative_path(char const * from, char const * to); ++ ++size_t split_path_list(char const * path_list, char split_char, char *** arr); ++ ++/* Advances path along by the amount that removes n prefix folders. */ ++char const * ++strip_n_prefix_folders(char const * path, size_t n); ++ ++/* NULL terminates path to remove n suffix folders. */ ++void ++strip_n_suffix_folders(char * path, size_t n); ++ ++char const * get_relocated_path (char const * from, char const * to, char const * actual_from); ++char * get_relocated_path_list(char const * from, char const * to_path_list); ++ ++char * single_path_relocation(const char *from, const char *to); ++char * pathlist_relocation(const char *from_path, const char *to_path_list); ++ ++#endif /* PATHTOOLS_H */ +-- +2.21.1 + diff --git a/recipes/bison/all/test_package/CMakeLists.txt b/recipes/bison/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..4f4c5e469aecf --- /dev/null +++ b/recipes/bison/all/test_package/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.0) +project(test_package) + +set(CMAKE_CXX_STANDARD 11) + +set(CMAKE_VERBOSE_MAKEFILE TRUE) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +find_package(BISON) + +set(BISON_VARS + BISON_FOUND + BISON_EXECUTABLE + BISON_VERSION +) + +foreach(BISON_VAR ${BISON_VARS}) + message("${BISON_VAR}: ${${BISON_VAR}}") + if(NOT ${BISON_VAR}) + message(FATAL_ERROR "${BISON_VAR} NOT FOUND") + endif() +endforeach() + +bison_target(Bison_McParser + mc_parser.yy "${CMAKE_CURRENT_BINARY_DIR}/mc_parser.cpp" +) + +add_library(McParser STATIC + "${CMAKE_CURRENT_BINARY_DIR}/mc_parser.cpp" +) +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/bison/all/test_package/conanfile.py b/recipes/bison/all/test_package/conanfile.py new file mode 100644 index 0000000000000..71d237dc805d0 --- /dev/null +++ b/recipes/bison/all/test_package/conanfile.py @@ -0,0 +1,43 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + def build_requirements(self): + if tools.os_info.is_windows and not tools.get_env("CONAN_BASH_PATH") and \ + tools.os_info.detect_windows_subsystem() != "msys2": + self.build_requires("msys2/20190524") + + @ property + def _mc_parser_source(self): + return os.path.join(self.source_folder, "mc_parser.yy") + + def build(self): + if not tools.cross_building(self.settings): + # verify bison may run + self.run("bison --version", run_environment=True) + # verify yacc may run + self.run("yacc --version", run_environment=True, win_bash=tools.os_info.is_windows) + # verify bison may preprocess something + self.run("bison -d {}".format(self._mc_parser_source), run_environment=True) + + # verify CMake integration + 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) + + # verify bison works without M4 environment variables + with tools.environment_append({"M4": None}): + self.run("bison -d {}".format(self._mc_parser_source), run_environment=True) + + # verify bison works without BISON_PKGDATADIR and M4 environment variables + with tools.environment_append({"BISON_PKGDATADIR": None, "M4": None}): + self.run("bison -d {}".format(self._mc_parser_source), run_environment=True) diff --git a/recipes/bison/all/test_package/mc_parser.yy b/recipes/bison/all/test_package/mc_parser.yy new file mode 100644 index 0000000000000..9d219d506394d --- /dev/null +++ b/recipes/bison/all/test_package/mc_parser.yy @@ -0,0 +1,42 @@ +%{ +#include +#include +#include +#include //-- I need this for atoi +using namespace std; + +int yylex(); +int yyerror(const char *p) { cerr << "Error!" << endl; return 42; } +%} + +%union { + int val; + char sym; +}; +%token NUM +%token OPA OPM LP RP STOP +%type exp term sfactor factor res + +%% +run: res run | res /* forces bison to process many stmts */ + +res: exp STOP { cout << $1 << endl; } + +exp: exp OPA term { $$ = ($2 == '+' ? $1 + $3 : $1 - $3); } +| term { $$ = $1; } + +term: term OPM factor { $$ = ($2 == '*' ? $1 * $3 : $1 / $3); } +| sfactor { $$ = $1; } + +sfactor: OPA factor { $$ = ($1 == '+' ? $2 : -$2); } +| factor { $$ = $1; } + +factor: NUM { $$ = $1; } +| LP exp RP { $$ = $2; } + +%% +int main() +{ + yyparse(); + return 0; +} diff --git a/recipes/bison/all/test_package/test_package.cpp b/recipes/bison/all/test_package/test_package.cpp new file mode 100644 index 0000000000000..bd8eb53edd5e0 --- /dev/null +++ b/recipes/bison/all/test_package/test_package.cpp @@ -0,0 +1,13 @@ +#include + +extern "C" +{ + int yyerror(char *); +} + +int main() +{ + char error[] = "Bincrafters"; + std::cout << yyerror(error) << std::endl; + return 0; +} diff --git a/recipes/bison/config.yml b/recipes/bison/config.yml new file mode 100644 index 0000000000000..c868ac9924e90 --- /dev/null +++ b/recipes/bison/config.yml @@ -0,0 +1,3 @@ +versions: + "3.5.3": + folder: all