diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9651322 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.m4 text eol=lf +*.awk text eol=lf +*.c text eol=lf +*.h text eol=lf +*.php text eol=lf +*.json text eol=lf +*.md text eol=lf diff --git a/.gitignore b/.gitignore index 3dcd021..d6b2cf8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,26 @@ php53 php54 php55 +php56 +php70 +php71 +php72 phpmaster php +!lib/php +!bin/php rmtools-client rmtools.base logs PFTT - +\.tmp +\.cache +oracle +# either these two become submodules, or uncomment them +#pgo-build +#rmtools* +phpsdk-local.bat +pgo/work +!pgo/tpl/php +!lib/php/libsdk/SDK/Build/PGO/Server/PHP +*.swp diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4eaf95c --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +Copyright 2017-2019 Anatol Belski + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index fa10403..636348f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,230 @@ -# PHP SDK - -PHP SDK is a toolset for building PHP under windows - -## Usage - -- git checkout https://github.com/OSTC/php-sdk-binary-tools.git c:\php-sdk -- follow the instructions on the PHP [wiki page](https://wiki.php.net/internals/windows/stepbystepbuild "PHP wiki page") \ No newline at end of file +# PHP SDK + +PHP SDK is a tool kit for Windows PHP builds. + +# License + +The PHP SDK itself and the SDK own tools and code are licensed under the BSD 2-Clause license. With the usage of the other tools, you accept the respective licenses. + +# Overview + +The toolset consists on a mix of the hand written scripts, selected MSYS2 parts and standalone programs. It supports any workflows, be it a custom, local or a CI build whatsoever. + +The PHP SDK 2.2+ is compatible with PHP 7.2 and above. + +The PHP SDK 2.1 is required to build PHP 7.1 or 7.0. + +The legacy binary tools SDK is available from the [legacy branch](https://github.com/php/php-sdk-binary-tools/tree/legacy) and is suitable to build PHP 5. + +# Requirements + +- A 64-bit build host +- Windows 7 or later +- `Visual C++ 2017` or `Visual C++ 2019` must be installed prior SDK usage. Required components + - C++ dev + - Windows SDK + - .NET dev +- if `Cygwin`, `MingW` or any other cross solution is installed, please read notes in the pitfalls section + +# Tools + +## SDK + +- starter scripts, named phpsdk-<crt>-<arch>.bat +- `phpsdk_buildtree` - initialize the development filesystem structure +- `phpsdk_deps` - handle dependency libraries +- `phpsdk_dllmap` - create a JSON listing of DLLs contained in zip files +- `phpsdk_pgo` - run PGO training +- `phpsdk_version` - show SDK version +- `task.exe` - wrapper to hide the given command line + +## Other tools + +- `bison` 3.3.2, `re2c` 1.1.1, `lemon` +- `awk`, `gawk`, `sed`, `grep`, `jq` +- `diff`, `diff3`, `patch` +- `md5sum`, `sha1sum`, `sha224sum`, `sha256sum`, `sha384sum`, `sha512sum` +- `7za`, `zip`, `unzip`, `unzipsfx` +- `wget`, `pwgen` + +## Optional, not included + +These are not included with the PHP SDK, but might be useful. While Visual C++ is the only required, the others might enable some additional functionality. Care yourself about making them available on your system, if relevant. + +- `Git` - useful for PHP source management +- `Cppcheck` - used for static analysis +- `clang` - useful for experimental builds and for static analysis +- `ICC` - useful for experimental builds +- `ConEmu` - console emulator with tabs and more + +# Usage + +The PHP SDK should be unzipped into the shortest possible path, preferably somewhere near the drive root. + +Usually, the first step to start the PHP SDK is by invoking one of the suitable starter scripts. This automatically puts the console on the correct environment relevant for the desired PHP build configuration. + +It is not required to hold the source in the PHP SDK directory. It could be useful, for example, to simplify the SDK updates. + +## Basic usage example + +- `git clone https://github.com/php/php-sdk-binary-tools.git c:\php-sdk` +- `cd c:\php-sdk` +- `git checkout php-sdk-2.1.9` or later +- invoke `phpsdk-vc15-x64.bat` +- `phpsdk_buildtree phpmaster` +- `git clone https://github.com/php/php-src.git && cd php-src`, or fetch a zipball +- `phpsdk_deps --update --branch master`, use `phpsdk_deps --update --branch X.Y` for a non master branch +- do the build, eg. `buildconf && configure --enable-cli && nmake` + +More extensive documentation can be found on the [wiki](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2 "PHP wiki page"). + +## The old way + +- `git clone https://github.com/php/php-sdk-binary-tools.git c:\php-sdk` +- follow the instructions on the PHP [wiki page](https://wiki.php.net/internals/windows/stepbystepbuild "PHP wiki page") + +# Customizing + +## Custom environment setup + +A script called phpsdk-local.bat has to be put into the PHP SDK root. If present, it will be automatically picked up by the starter script. A template for such a script is included with the PHP SDK. This allows to automatically meet any required preparations, that are not foreseen by the standard PHP SDK startup. Be careful while creating your own phpsdk-local. It's your responsibility to ensure the regular PHP SDK startup isn't broken after phpsdk-local.bat was injected into the startup sequence. + +## Console emulator integration + +The starter scripts can be also easy integrated with the consoles other than standard cmd.exe. For the reference, here's an example ConEmu task + +`C:\php-sdk\phpsdk-vc15-x64.bat -cur_console:d:C:\php-sdk\php72\vc15\x64\php-src` + +## Unattended builds + +An elementary functionality to run unattended builds is included. See an example on how to setup a simple unattended build task in the doc directory. + +Be aware, that starter scripts always start a new shell. Scripts intended to run as a task need to be passed with `-t` argument to a starter script. + +# Upgrading + +- backup phpsdk-local.bat +- backup the source trees and any other custom files in the PHP SDK root, if any present +- move the PHP SDK folder into trash +- download, unpack and the new PHP SDK version under the same path +- move the custom files back in their respective places + +If the PHP SDK is kept as a git checkout, merely what is needed instead is to git fetch and to checkout an updated git tag. + +# Extending + +The SDK tools are based on the KISS principle and should be kept so. Basic tools are implemented as simple batch script. The minimalistic `PHP` is available for internal SDK purposes. It can be used, if more complexity is required. A suitable PHP binary is bound with the PHP SDK. If you have an idea for some useful tool or workflow, please open a ticket or PR, so it can be discussed, implemented and added to the SDK. By contributing an implementation, you should also accept the SDK license. + +# PGO + +As of the version 2.1.0, the SDK includes a tool for the [PGO](https://docs.microsoft.com/en-us/cpp/build/reference/profile-guided-optimizations) optimization. Several training cases are included by default, which are based on the real life opensource applications. The PGO optimization can give an overall speedup up to 30%. The work on adding more training scenarios for the widely used opensource apps is ongoing. If you have a training scenario to share, please create a PR to this repo. Any new training cases are thoroughly validated through the extensive performance tests. + +## Preparing PGO training environment +- the pgo folder in the SDK root dir contains templates and scenarios for PGO training +- adjust and execute [doc/phpsdk_pgo_prep_elevated.bat.example](doc/phpsdk_pgo_prep_elevated.bat.example) to open ports required for PHP SDK training servers +- run `phpsdk_pgo --init`. Note that composer requires huge amounts of memory, so + it may be necessary to set the environment variable `COMPOSER_MEMORY_LIMIT=-1`. + The PGO initialization may not succeed in x86 enviroments. + +## Creating PGO build +- compile PHP configured using `--enable-pgi` +- run `phpsdk_pgo --train` +- run `nmake clean-pgo` +- rebuild PHP `--with-pgo` + +## Adding custom PGO training scenario + +A custom scenario can be used to produce a custom PHP binary dedicated to an arbitrary application. + +The existing training cases can be found in [pgo/cases](pgo/cases). Assumed the case would be named `myapp`, the general steps to setup were + +- create the case directory under `pgo/cases/myapp` +- create `pgo/cases/myapp/phpsdk_pgo.json` with the necessary definitions +- create `pgo/cases/myapp/nginx.partial.conf` with a partial NGINX template +- create `pgo/cases/myapp/TrainingCaseHandler.php` with a class as defined in the [interface](lib/php/libsdk/SDK/Build/PGO/Interfaces/TrainingCase.php) + +After a training case is implemented and put under `pgo/cases`, the work environment needs to be reinitialized. The tool puts all the training data and necessary applications under `pgo/work`. Rename or remove that directory and rerun `phpsdk_pgo --init`. + +To skip a training case, add a file named `inactive` into the case folder. + +# Debugging PHP + +This part covers debugging possibilities for the builds produced by the native VS compilers. +For the cross compiled builds produced with toolsets other than VC++, please check the +documentation for the corresponding toolsets. In any case, general principles on debugging +native programs apply. + +Either a debug build of PHP or enabled debug symbols are required to be able to debug PHP. +A debug build is usually more suitable for the development process and can be produced by +adding `--enable-debug` to the configure options. A release build with debug symbols can +be produced by adding `--enable-debug-pack`. These options are mutually exclusive. + +## Debugging with Visual Studio + +- Configure with either `--enable-debug` or `--enable-debug-pack`. +- A debug build might bring better experience for dev, but sometimes you want to debug a release build. +- `nmake run ARGS=yourscript.php DEBUGGER=1`, that will open a Visual Studio window. +- Any additional runtime options for PHP or the script executed go to ARGS, too. +- Select `Debug -> New Breakpoint -> Function Breakpoint` and add a function where the debugger should break. +- Click `Start`. + +Adding a breakpoint before starting debugging might be not necessary, if a crash is debugged. When such a script runs +under the debugger, the debugger will stop at the crashing point. In that case, a breakpoint can be added +around the crashed code directly. + +## Debugging test suite with Visual Studio + +The [Microsoft Child Process Debugging Power Tool](https://marketplace.visualstudio.com/items?itemName=vsdbgplat.MicrosoftChildProcessDebuggingPowerTool) +plugin for Visual Studio is required. After installing it, following these steps + +- `nmake test TESTS=ext/myext/tests/sometest.phpt DEBUGGER=1` +- Select `Debug -> Other Debug Targets -> Child Process Debugging Settings` and enable child process debugging. +- If necessary, add a breakpoint and start debugging as described in the previous section. + +## Debugging with WinDbg + +PHP can also be debugged with the tools from the WinDbg package. There is currently no way +implemented in the Makefile to start the WinDbg integrated, so it needs to de done manually. +Either a debug build or a release build with debug symbols is still required, as described +previously. + +# Support + +- Join `#winphp-dev` on Freenode to discuss any ideas or questions +- File an issue on GitHub + +# Pitfalls + +- SDK or PHP sources put into paths including spaces might cause issue. +- SDK or PHP sources put into too long paths, will cause an issue. +- If Cygwin, MSYS2 or MinGW flavors are exposed in global PATH, it might cause issues. If it's unavoidable, ensure SDK preceeds it on the PATH. +- When fetching the binary SDK from git, git `core.autocrlf` configuration directive set to `false` is recommended. +- Tools, based on MSYS2, only accept paths with forward slashes. +- Both Visual C++ toolset and the Windows SDK components have to be installed for the PHP SDK to work properly. +- The VC++ toolset is still required, even if another compiler, fe. clang, is intended to be used. +- `task.exe` is not a console application, some systems might not propagate exit code except the batch is explicitly run from `cmd /c`, etc. +- `7za` should be preferred over `unzip` and `zip` for compatibility reasons. +- If you experience some strange crashes on MSYS2 tools, try the phpsdk_rebase_msys2 tool. MSYS2 tools might be have unstable + on ASLR enabled systems. + +# Internal notes + +## Releases + +Users of the PHP SDK are supposed to use tagged versions for stability and +reproducability. This requires the maintainers of the PHP SDK to create such +tags for *all* *relevant* *changes*. The tag format should be `php-sdk-X.Y.Z`, +with the common major, minor and revision numbers. + +Comprehensive changes, which would be hard to test extensively, such as updates +to the bundled PHP or the MinGW tools, should walk through a QA (aka. pre-release) +process, typically with beta versions (e.g. `php-sdk-X.Y.Zbeta1`). Only after +these have been thoroughly tested, and all relevant issues have been resolved, +a GA release should be tagged. + +After each tag, a couple of other repositories should be informed about the +available update, ideally in form of a pull request. These repositories are: + +* https://github.com/php/php-src (for Windows CI) +* https://github.com/php/php-windows-builder +* https://github.com/php/setup-php-sdk diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..39901a4 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.4.0-dev diff --git a/bin/7za.dll b/bin/7za.dll new file mode 100644 index 0000000..cf19f1b Binary files /dev/null and b/bin/7za.dll differ diff --git a/bin/7za.exe b/bin/7za.exe new file mode 100755 index 0000000..ada25ff Binary files /dev/null and b/bin/7za.exe differ diff --git a/bin/7zxa.dll b/bin/7zxa.dll new file mode 100644 index 0000000..e0f55bc Binary files /dev/null and b/bin/7zxa.dll differ diff --git a/bin/Copy of bison.exe b/bin/Copy of bison.exe deleted file mode 100644 index ab9cd98..0000000 Binary files a/bin/Copy of bison.exe and /dev/null differ diff --git a/bin/Copy of bison.simple b/bin/Copy of bison.simple deleted file mode 100644 index 33084f4..0000000 --- a/bin/Copy of bison.simple +++ /dev/null @@ -1,761 +0,0 @@ -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/local/share/bison.simple" -/* This file comes from bison-1.28. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 217 "/usr/local/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - -$ /* the action file gets copied in in place of this dollarsign */ -#line 543 "/usr/local/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} diff --git a/bin/SFXWiz32.exe b/bin/SFXWiz32.exe deleted file mode 100644 index 8883098..0000000 Binary files a/bin/SFXWiz32.exe and /dev/null differ diff --git a/bin/awk.exe b/bin/awk.exe deleted file mode 100644 index bdedce5..0000000 Binary files a/bin/awk.exe and /dev/null differ diff --git a/bin/bison.exe b/bin/bison.exe deleted file mode 100644 index a56f1cb..0000000 Binary files a/bin/bison.exe and /dev/null differ diff --git a/bin/bison.simple b/bin/bison.simple deleted file mode 100644 index 5bddbcb..0000000 --- a/bin/bison.simple +++ /dev/null @@ -1,761 +0,0 @@ -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "bison.simple" -/* This file comes from bison-1.27. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 216 "bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - -$ /* the action file gets copied in in place of this dollarsign */ -#line 542 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} diff --git a/bin/cvs.exe b/bin/cvs.exe deleted file mode 100644 index 347f889..0000000 Binary files a/bin/cvs.exe and /dev/null differ diff --git a/bin/dateformat.bat b/bin/dateformat.bat deleted file mode 100644 index 3c8fa0c..0000000 --- a/bin/dateformat.bat +++ /dev/null @@ -1,82 +0,0 @@ -@ECHO OFF -IF NOT "%OS%"=="Windows_NT" GOTO Syntax -IF "%?1"=="" GOTO Syntax -IF NOT "%?6"=="" GOTO Syntax -ECHO .%* | FIND "?" > NUL && GOTO Syntax - -SETLOCAL ENABLEDELAYEDEXPANSION -FOR /F "tokens=2-4 delims=(/-)" %%A IN ('VER ?| DATE') DO ( - SET Var1=%%A - SET Var2=%%B - SET Var3=%%C -) -FOR /F "tokens=2 delims=:" %%A IN ('VER ?| DATE ?| FIND /V "("') DO ( - FOR /F "tokens=1-3 delims=/- " %%B IN ("%%A") DO ( - SET %Var1%=%%B - SET %Var2%=%%C - SET %Var3%=%%D - ) -) -IF /I NOT "%?1"=="%Var1%" IF /I NOT "%?1"=="%Var2%" IF /I NOT "%?1"=="%Var3%" ( - ENDLOCAL - GOTO Syntax -) -IF /I "%?4"=="/LZ" (SET Delim=) ELSE (SET Delim=%4) -IF /I NOT "%?3"=="%Var1%" IF /I NOT "%?3"=="%Var2%" IF /I NOT "%?3"=="%Var3%" IF /I NOT "%?3"=="/LZ" (SET Delim=%?3) -IF /I NOT "%?2"=="%Var1%" IF /I NOT "%?2"=="%Var2%" IF /I NOT "%?2"=="%Var3%" IF /I NOT "%?2"=="/LZ" (SET Delim=%?2) -ECHO.%* | FIND /I "/LZ" >NUL -IF NOT ERRORLEVEL 1 CALL :AddLeadingZero -SET DateFmt=!%1! -IF /I NOT "%?2"=="%Delim%" IF /I NOT "%?2"=="/LZ" (SET DateFmt=%DateFmt%%Delim%!%2!) -IF /I NOT "%?3"=="%Delim%" IF /I NOT "%?3"=="/LZ" (SET DateFmt=%DateFmt%%Delim%!%3!) -ENDLOCAL & SET DateFmt=%DateFmt% - -SET DateFmt - -GOTO:EOF - - -:AddLeadingZero -CALL SET Char1=%%%Var1%:?0,1%% -IF NOT "%Char1%"=="0" ( - IF !%Var1%! LSS 10 SET %Var1%=0!%Var1%! -) -CALL SET Char1=%%%Var2%:?0,1%% -IF NOT "%Char1%"=="0" ( - IF !%Var2%! LSS 10 SET %Var2%=0!%Var2%! -) -CALL SET Char1=%%%Var3%:?0,1%% -IF NOT "%Char1%"=="0" ( - IF !%Var3%! LSS 10 SET %Var3%=0!%Var3%! -) -GOTO:EOF - - -:Syntax -ECHO DateFmt.bat, Version 0.52 BETA for Windows NT 4 and later -ECHO Display the current date in the specified format -ECHO. -ECHO Usage: DATEFMT date_format [ delimiter ] [ /LZ ] -ECHO. -IF "%OS%"=="Windows_NT" FOR /F "tokens=2-4 delims=()/-" %%A IN ('VER ?| DATE ?| FIND "("') DO ECHO Where: date_format is any combination of %%A, %%B and/or %%C -IF NOT "%OS%"=="Windows_NT" ECHO Where: date_format is any combination of dd, mm and/or yy -ECHO (these date_format options are always in the computer's -IF NOT "%OS%"=="Windows_NT" ECHO local language; to look them up, type VER � DATE) -IF NOT "%OS%"=="Windows_NT" GOTO Skip -ECHO local language; to look them up, type VER ?| DATE) -:Skip -ECHO delimiter is the delimiter to be used in the end result -ECHO /LZ use leading zeroes in the end result -ECHO. -ECHO Examples (for English Windows versions): -ECHO DATEFMT yy mm dd --- 2007115 (January 15 or November 5, 2007) -ECHO DATEFMT yy mm dd - --- 2007-11-5 (November 5, 2007) -ECHO DATEFMT yy mm dd - /LZ --- 2007-11-05 (November 5, 2007) -ECHO DATEFMT mm /LZ --- 01 (January) -ECHO DATEFMT yy mm - /LZ --- 2007-06 (June 2007) -ECHO DATEFMT dd mm dd * /LZ --- 11*03*11 (March 11) -ECHO. -ECHO Inspired by Simon Sheppard's GetDate.bat -ECHO http://www.ss64.com/ntsyntax/getdate.html -ECHO Written by Rob van der Woude -ECHO http://www.robvanderwoude.com diff --git a/bin/datetime.bat b/bin/datetime.bat deleted file mode 100644 index d391109..0000000 --- a/bin/datetime.bat +++ /dev/null @@ -1,3 +0,0 @@ -for /F "tokens=1-4 delims=:., " %%a in ('time/T') do set _TIME=%%a%%b%%c -for /F "tokens=2-5 delims=:.,/ " %%a in ('date/T') do set _DATE=%%a%%b%%c -SET SNAPDATETIME=%_DATE%%_TIME% diff --git a/bin/deplister.exe b/bin/deplister.exe new file mode 100755 index 0000000..6a9e23a Binary files /dev/null and b/bin/deplister.exe differ diff --git a/bin/detoured.dll b/bin/detoured.dll deleted file mode 100644 index 0f0dcf6..0000000 Binary files a/bin/detoured.dll and /dev/null differ diff --git a/bin/exRay.exe b/bin/exRay.exe deleted file mode 100644 index 72672e7..0000000 Binary files a/bin/exRay.exe and /dev/null differ diff --git a/bin/exRayScope.dll b/bin/exRayScope.dll deleted file mode 100644 index f6fec34..0000000 Binary files a/bin/exRayScope.dll and /dev/null differ diff --git a/bin/fciv.exe b/bin/fciv.exe deleted file mode 100644 index 4c29ea5..0000000 Binary files a/bin/fciv.exe and /dev/null differ diff --git a/bin/flex.exe b/bin/flex.exe deleted file mode 100644 index 3a56f69..0000000 Binary files a/bin/flex.exe and /dev/null differ diff --git a/bin/funzip.exe b/bin/funzip.exe deleted file mode 100644 index 74fe2c6..0000000 Binary files a/bin/funzip.exe and /dev/null differ diff --git a/bin/gawk.exe b/bin/gawk.exe deleted file mode 100644 index bdedce5..0000000 Binary files a/bin/gawk.exe and /dev/null differ diff --git a/bin/grep.exe b/bin/grep.exe deleted file mode 100644 index 110c6f0..0000000 Binary files a/bin/grep.exe and /dev/null differ diff --git a/bin/jam.exe b/bin/jam.exe deleted file mode 100644 index 301b2b7..0000000 Binary files a/bin/jam.exe and /dev/null differ diff --git a/bin/jq.exe b/bin/jq.exe new file mode 100755 index 0000000..cf9f37e Binary files /dev/null and b/bin/jq.exe differ diff --git a/bin/lemon.exe b/bin/lemon.exe new file mode 100755 index 0000000..a62df91 Binary files /dev/null and b/bin/lemon.exe differ diff --git a/bin/libintl3.dll b/bin/libintl3.dll deleted file mode 100644 index ec11e6b..0000000 Binary files a/bin/libintl3.dll and /dev/null differ diff --git a/bin/m4.exe b/bin/m4.exe deleted file mode 100644 index a667342..0000000 Binary files a/bin/m4.exe and /dev/null differ diff --git a/bin/md5sums.exe b/bin/md5sums.exe deleted file mode 100644 index 0fcf7cf..0000000 Binary files a/bin/md5sums.exe and /dev/null differ diff --git a/bin/patch.bat b/bin/patch.bat deleted file mode 100644 index c14efc8..0000000 --- a/bin/patch.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -c:\Users\pierre\Documents\php-sdk\bin\patch.exe < %1 -pause diff --git a/bin/patch.exe b/bin/patch.exe deleted file mode 100644 index 1b22a07..0000000 Binary files a/bin/patch.exe and /dev/null differ diff --git a/bin/pcre3.dll b/bin/pcre3.dll deleted file mode 100644 index b5fd2a6..0000000 Binary files a/bin/pcre3.dll and /dev/null differ diff --git a/bin/php/DONT_PUT_THIS_FOLDER_ONTO_PATH! b/bin/php/DONT_PUT_THIS_FOLDER_ONTO_PATH! new file mode 100644 index 0000000..e69de29 diff --git a/bin/php/do_php.bat b/bin/php/do_php.bat new file mode 100755 index 0000000..09dccf5 --- /dev/null +++ b/bin/php/do_php.bat @@ -0,0 +1,3 @@ +@echo ofF + +%~dp0php.exe -c %~dp0php.ini -d curl.cainfo=%PHP_SDK_ROOT_PATH%\msys2\usr\ssl\cert.pem -d extension_dir=%~dp0ext %* diff --git a/bin/php/ext/php_curl.dll b/bin/php/ext/php_curl.dll new file mode 100644 index 0000000..7e26962 Binary files /dev/null and b/bin/php/ext/php_curl.dll differ diff --git a/bin/php/ext/php_ftp.dll b/bin/php/ext/php_ftp.dll new file mode 100644 index 0000000..e552dcb Binary files /dev/null and b/bin/php/ext/php_ftp.dll differ diff --git a/bin/php/ext/php_mbstring.dll b/bin/php/ext/php_mbstring.dll new file mode 100644 index 0000000..8dacdaa Binary files /dev/null and b/bin/php/ext/php_mbstring.dll differ diff --git a/bin/php/ext/php_mysqli.dll b/bin/php/ext/php_mysqli.dll new file mode 100644 index 0000000..4fe11f7 Binary files /dev/null and b/bin/php/ext/php_mysqli.dll differ diff --git a/bin/php/ext/php_openssl.dll b/bin/php/ext/php_openssl.dll new file mode 100644 index 0000000..66b9c68 Binary files /dev/null and b/bin/php/ext/php_openssl.dll differ diff --git a/bin/php/ext/php_sqlite3.dll b/bin/php/ext/php_sqlite3.dll new file mode 100644 index 0000000..d4cbf4f Binary files /dev/null and b/bin/php/ext/php_sqlite3.dll differ diff --git a/bin/php/ext/php_zip.dll b/bin/php/ext/php_zip.dll new file mode 100644 index 0000000..4d0665e Binary files /dev/null and b/bin/php/ext/php_zip.dll differ diff --git a/bin/php/libcrypto-3-x64.dll b/bin/php/libcrypto-3-x64.dll new file mode 100644 index 0000000..bd8a44a Binary files /dev/null and b/bin/php/libcrypto-3-x64.dll differ diff --git a/bin/php/libsqlite3.dll b/bin/php/libsqlite3.dll new file mode 100644 index 0000000..8ece6a4 Binary files /dev/null and b/bin/php/libsqlite3.dll differ diff --git a/bin/php/libssh2.dll b/bin/php/libssh2.dll new file mode 100644 index 0000000..c15596d Binary files /dev/null and b/bin/php/libssh2.dll differ diff --git a/bin/php/libssl-3-x64.dll b/bin/php/libssl-3-x64.dll new file mode 100644 index 0000000..9d46d4d Binary files /dev/null and b/bin/php/libssl-3-x64.dll differ diff --git a/bin/php/nghttp2.dll b/bin/php/nghttp2.dll new file mode 100644 index 0000000..a260920 Binary files /dev/null and b/bin/php/nghttp2.dll differ diff --git a/bin/php/php.exe b/bin/php/php.exe new file mode 100755 index 0000000..8f51599 Binary files /dev/null and b/bin/php/php.exe differ diff --git a/bin/php/php.ini b/bin/php/php.ini new file mode 100644 index 0000000..2cb9c24 --- /dev/null +++ b/bin/php/php.ini @@ -0,0 +1,13 @@ + +extension=php_curl.dll +extension=php_ftp.dll +extension=php_sqlite3.dll +extension=php_openssl.dll +extension=php_mbstring.dll +extension=php_mysqli.dll +extension=php_zip.dll +memory_limit=4G + +error_reporting=-1 +display_errors=1 +display_startup_errors=1 diff --git a/bin/php/php8.dll b/bin/php/php8.dll new file mode 100644 index 0000000..985219a Binary files /dev/null and b/bin/php/php8.dll differ diff --git a/bin/phpsdk_buildtree.bat b/bin/phpsdk_buildtree.bat old mode 100644 new mode 100755 index 387ff61..21e5800 --- a/bin/phpsdk_buildtree.bat +++ b/bin/phpsdk_buildtree.bat @@ -4,38 +4,43 @@ IF "%1" EQU "" GOTO Help IF "%2" NEQ "" SET _=%2\%1 IF "%2" EQU "" SET _=%CD%\%1 -MD %_%\vc9\x86\deps\bin -MD %_%\vc9\x86\deps\lib -MD %_%\vc9\x86\deps\include -MD %_%\vc9\x64\deps\bin -MD %_%\vc9\x64\deps\lib -MD %_%\vc9\x64\deps\include - -MD %_%\vc11\x86\deps\bin -MD %_%\vc11\x86\deps\lib -MD %_%\vc11\x86\deps\include -MD %_%\vc11\x64\deps\bin -MD %_%\vc11\x64\deps\lib -MD %_%\vc11\x64\deps\include - -MD %_%\vc12\x86\deps\bin -MD %_%\vc12\x86\deps\lib -MD %_%\vc12\x86\deps\include -MD %_%\vc12\x64\deps\bin -MD %_%\vc12\x64\deps\lib -MD %_%\vc12\x64\deps\include - -MD %_%\vc14\x86\deps\bin -MD %_%\vc14\x86\deps\lib -MD %_%\vc14\x86\deps\include -MD %_%\vc14\x64\deps\bin -MD %_%\vc14\x64\deps\lib -MD %_%\vc14\x64\deps\include +rem if we're in the starter script shell, create the only struct that corresponds to the current env +rem otherwise - retain the old behavior, create structs for all the known build combinations and don't cd + +cmd /c "exit /b 0" + +if "%PHP_SDK_ARCH%" NEQ "" ( + if "%PHP_SDK_VS%" NEQ "" ( + MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\bin + MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\lib + MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\include + cd %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH% + goto exit + ) + goto create_all +) else ( +:create_all + for %%i in (vc14 vc15 vs16 vs17) do ( + MD %_%\%%i\x86\deps\bin + MD %_%\%%i\x86\deps\lib + MD %_%\%%i\x86\deps\include + MD %_%\%%i\x64\deps\bin + MD %_%\%%i\x64\deps\lib + MD %_%\%%i\x64\deps\include + MD %_%\%%i\arm64\deps\bin + MD %_%\%%i\arm64\deps\lib + MD %_%\%%i\arm64\deps\include + ) +) + +set _= GOTO EXIT :help -echo createbuildtree ^ [PATH] +echo phpsdk_buildtree ^ [PATH] echo Create the common directory structure used by the PHP SDK :EXIT +exit /b %errorlevel% + diff --git a/bin/phpsdk_deps.bat b/bin/phpsdk_deps.bat new file mode 100755 index 0000000..b9345af --- /dev/null +++ b/bin/phpsdk_deps.bat @@ -0,0 +1,16 @@ +@echo off + +cmd /c "exit /b 0" + +if "%PHP_SDK_PHP_CMD%"=="" ( + call %~dp0phpsdk_setvars.bat + if "!PHP_SDK_PHP_CMD!"=="" ( + echo PHP SDK is not setup + exit /b 3 + ) +) + +call %PHP_SDK_PHP_CMD% %PHP_SDK_BIN_PATH%\phpsdk_deps.php %* + +exit /b %errorlevel% + diff --git a/bin/phpsdk_deps.php b/bin/phpsdk_deps.php new file mode 100644 index 0000000..31869c9 --- /dev/null +++ b/bin/phpsdk_deps.php @@ -0,0 +1,217 @@ + $val) { + switch ($name) { + default: + throw new Exception("Unknown switch '$name'"); + break; + + case "h": + case "help": + usage(0); + break; + + case "b": + case "branch": + /* Branch config depends on other information. We can set it + right away, because the option order can't be guaranteed. */ + $branch = $val; + break; + + case "s": + case "stability": + Config::setCurrentStabilityName($val); + break; + + case "a": + case "arch": + Config::setCurrentArchName($val); + break; + + case "d": + case "deps": + Config::setDepsLocalPath($val); + break; + + case "c": + case "check": + $cmd = "check"; + break; + case "u": + case "update": + $cmd = "update"; + break; + + case "t": + case "crt": + Config::setCurrentCrtName($val); + break; + + case "f": + case "force": + $force = true; + break; + + case "n": + case "no-backup": + $backup = false; + break; + + case "p": + case "pack": + $cmd = "pack"; + break; + } + } + + if (NULL == $branch) { + $branch = Config::guessCurrentBranchName(); + if (NULL == $branch) { + throw new Exception("Couldn't determine current branch name, expect an explicit input."); + } + } + Config::setCurrentBranchName($branch); + + if (NULL === $cmd) { + usage(); + } + + if (NULL === Config::getDepsLocalPath()) { + usage(3); + } + + $branch = Config::getCurrentBranchName(); + if (NULL == $branch) { + usage(3); + } + + $arch = Config::getCurrentArchName(); + if (NULL === $arch) { + usage(3); + } + + if (NULL === Config::getCurrentCrtName()) { + usage(3); + } + /* The current CRT needs to match the config one. */ + $active_crt = getenv("PHP_SDK_VS"); + if (Config::getCurrentCrtName() != $active_crt && !$force) { + throw new Exception("Active CRT name '$active_crt' differs from the branch CRT name '" . Config::getCurrentCrtName() . "'."); + } + + $branch_data = Config::getCurrentBranchData(); + echo "\nConfiguration: " . Config::getCurrentBranchName() . "-$branch_data[crt]-$branch_data[arch]-$branch_data[stability]\n\n"; + + /* Let the dep manager to run the command. */ + $dm = new SDK\Build\Dependency\Manager(Config::getDepsLocalPath(), $branch_data["stability"], $branch_data["arch"]); + switch ($cmd) { + default: + throw new Exception("Unknown command '$cmd'"); + break; + case "check": + $ret = $dm->updatesAvailable(); + if ($ret) { + msg("Updates are available.", 7); + } else { + msg("No updates are available."); + } + break; + case "update": + if ($force) { + print "Replacing the current deps by the force option.\n\n"; + } + $dm->performUpdate($msg, $force, $backup); + msg($msg); + break; + case "pack": + $path_to_pack = Config::getDepsLocalPath(); + $pack_path = dirname($path_to_pack) . DIRECTORY_SEPARATOR . "deps-$branch-$branch_data[crt]-$branch_data[arch].7z"; + print "Packaging '$path_to_pack' as '$pack_path'.\n\n"; + if ($force && is_file($pack_path)) { + unlink($pack_path); + } + system("7za a $pack_path $path_to_pack", $st); + exit((int)$st); + break; + } + +} catch (Throwable $e) { + //var_dump($e); + //echo "\nError: ", $e->getMessage(), PHP_EOL; + throw $e; + exit(3); +} + +function usage(int $code = -1) +{ + echo "PHP SDK dependency handling tool.", PHP_EOL; + echo "Usage: ", PHP_EOL, PHP_EOL; + echo "Configuration:", PHP_EOL; + echo " -b --branch Branch name, eg. 7.0, 7.1, etc. If omited, several guess methods apply.", PHP_EOL; + echo " -a --arch Architecture, x86 or x64 or arm64. If omited, cl.exe is used to guess.", PHP_EOL; + echo " -t --crt CRT, marked by the corresponding VC++ version, eg. vc11, vc14, etc.", PHP_EOL; + echo " -s --stability One of stable or staging.", PHP_EOL, PHP_EOL; + echo "Commands:", PHP_EOL; + echo " -c --check Check for dependency updates. If updates are available, the exit code is set to 7.", PHP_EOL; + echo " -u --update Update dependencies. If deps directory already exists, backup copy is created automatically.", PHP_EOL; + echo " -p --pack Archive the dependency directory.", PHP_EOL, PHP_EOL; + echo "Misc:", PHP_EOL; + echo " -d --deps Path to the dependencies directory. If omited, CWD is used to guess.", PHP_EOL; + echo " -f --force Force the operation even if there are no upgrades available.", PHP_EOL; + echo " -n --no-backup Replace the current dependencies without creating backup.", PHP_EOL; + echo " -h --help Show help message.", PHP_EOL, PHP_EOL; + echo "Example: ", PHP_EOL; + echo " phpsdk_deps -c -b master", PHP_EOL; + echo " phpsdk_deps -u -b 7.0 -a x86 -d c:\\path\\to\\deps\\dir", PHP_EOL, PHP_EOL; + + $code = -1 == $code ? 0 : $code; + exit($code); +} + +function msg(string $s, int $code = 0) { + echo $s, PHP_EOL; + exit($code); +} + +exit(0); + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/bin/phpsdk_dllmap.bat b/bin/phpsdk_dllmap.bat new file mode 100755 index 0000000..a048a6c --- /dev/null +++ b/bin/phpsdk_dllmap.bat @@ -0,0 +1,16 @@ +@echo off + +cmd /c "exit /b 0" + +if "%PHP_SDK_PHP_CMD%"=="" ( + call %~dp0phpsdk_setvars.bat + if "!PHP_SDK_PHP_CMD!"=="" ( + echo PHP SDK is not setup + exit /b 3 + ) +) + +call %PHP_SDK_PHP_CMD% %PHP_SDK_BIN_PATH%\phpsdk_dllmap.php %* + +exit /b %errorlevel% + diff --git a/bin/dllmap.php b/bin/phpsdk_dllmap.php similarity index 59% rename from bin/dllmap.php rename to bin/phpsdk_dllmap.php index 83fb632..3ce5dc5 100644 --- a/bin/dllmap.php +++ b/bin/phpsdk_dllmap.php @@ -6,7 +6,7 @@ - create mappings between dll filename and zip filename Usage: - php dllmap.php path0 [ path1 ... ] > dllmapping.json + php dllmap.php [--pretty] path0 [ path1 ... ] > dllmapping.json */ @@ -20,8 +20,25 @@ "C:\\tmp\\libs", );*/ +$sopt = "p"; +$lopt = array( + "pretty", +); + +$flags = 0; +$opt = getopt($sopt, $lopt); +foreach ($opt as $name => $val) { + switch ($name) { + case "p": + case "pretty": + $flags = JSON_PRETTY_PRINT; + break; + } +} + + $dirs = array(); -foreach (array_slice($_SERVER["argv"], 1) as $item) { +foreach (array_slice($_SERVER["argv"], (0 == $flags ? 1 : 2)) as $item) { if (file_exists($item) && is_dir($item)) { $dirs[] = $item; } @@ -32,26 +49,7 @@ die; } - -$out = array( - "vc9" => array( - "x86" => array(), - "x64" => array(), - ), - "vc11" => array( - "x86" => array(), - "x64" => array(), - ), - "vc12" => array( - "x86" => array(), - "x64" => array(), - ), - "vc14" => array( - "x86" => array(), - "x64" => array(), - ), -); - +$out = array(); foreach ($dirs as $path) { $dir = new DirectoryIterator($path); @@ -67,29 +65,36 @@ continue; } - if (!preg_match(",.*-(vc\d+)-(x\d\d)\.zip,", $filename, $m)) { + if (!preg_match(",.*-(v[c|s]\d+)-(x\d\d)\.zip,", $filename, $m)) { continue; } $crt = $m[1]; $arch = $m[2]; + if (!isset($out[$crt])) { + $out[$crt] = array(); + } + if (!isset($out[$crt][$arch])) { + $out[$crt][$arch] = array(); + } + $zip = new ZipArchive(); $zip->open($pathname); $dlls = array(); - for( $i = 0; $i < $zip->numFiles; $i++ ){ - $stat = $zip->statIndex( $i ); - + for ($i = 0; $i < $zip->numFiles; $i++) { + $stat = $zip->statIndex($i); + if (substr($stat['name'], -3) != "dll") { continue; } $dlls[] = basename($stat['name']); } - + $zip->close(); unset($zip); @@ -100,5 +105,13 @@ } } -echo json_encode($out); +echo json_encode($out, $flags); +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/bin/phpsdk_dumpenv.bat b/bin/phpsdk_dumpenv.bat new file mode 100755 index 0000000..7d44df5 --- /dev/null +++ b/bin/phpsdk_dumpenv.bat @@ -0,0 +1,22 @@ +@echo off + +if "%PHP_SDK_OS_ARCH%"=="" ( + echo PHP SDK is not setup + exit /b 3 +) + +cmd /c "exit /b 0" + +echo. + +call %PHP_SDK_BIN_PATH%\phpsdk_version.bat +echo. + +echo OS architecture: %PHP_SDK_OS_ARCH% +echo Build architecture: %PHP_SDK_ARCH% +echo Visual C++: %PHP_SDK_VC_TOOLSET_VER% +echo PHP-SDK path: %PHP_SDK_ROOT_PATH% + + +exit /b %errorlevel% + diff --git a/bin/phpsdk_pgo.bat b/bin/phpsdk_pgo.bat new file mode 100755 index 0000000..526fa76 --- /dev/null +++ b/bin/phpsdk_pgo.bat @@ -0,0 +1,14 @@ +@echo off + +if "%PHP_SDK_PHP_CMD%"=="" ( + call %~dp0phpsdk_setvars.bat + if "!PHP_SDK_PHP_CMD!"=="" ( + echo PHP SDK is not setup + exit /b 3 + ) +) + +cmd /c %PHP_SDK_PHP_CMD% %PHP_SDK_BIN_PATH%\phpsdk_pgo.php %* + +exit /b %errorlevel% + diff --git a/bin/phpsdk_pgo.php b/bin/phpsdk_pgo.php new file mode 100644 index 0000000..2d5b0ac --- /dev/null +++ b/bin/phpsdk_pgo.php @@ -0,0 +1,134 @@ + $val) { + switch ($name) { + case "i": + case "init": + $cmd = "init"; + break; + case "ready": + $cmd = "check_init"; + break; + case "t": + case "train": + $cmd = "train"; + break; + case "u": + case "up": + $cmd = "up"; + break; + case "d": + case "down": + $cmd = "down"; + break; + case "s": + case "scenario": + $scenario = $val; + break; + case "f": + case "force": + $force = true; + break; + /* XXX This option is for now only integrated for training. It + would make sense to integrate it also with init. */ + case "c": + case "cases": + $cases = explode(",", $val); + break; + case "h": case "help": + usage(0); + break; + } + } + + if (NULL === $cmd) { + usage(); + } + + $deps_root = Config::getDepsLocalPath(); + + if ("check_init" != $cmd) { + /* XXX Need these checks for more safety, as long as the dist zipballs are not supported. */ + if (!file_exists("Makefile")) { + throw new Exception("Makefile not found. Arbitrary php snapshots are not supported yet, switch to the php source dir."); + } + if (preg_match(",BUILD_DIR=(.+),", file_get_contents("Makefile"), $m)) { + $php_root = trim($m[1]); + } + if (!$php_root || !file_exists($php_root)) { + throw new Exception("Invalid php root dir encountered '$php_root'."); + } + } + + $controller = new Controller($cmd, $scenario, $cases); + $controller->handle($force); + + if ("check_init" == $cmd) { + /* 0 for success, fail otherwise. */ + $ret = ($controller->isInitialized() === false); + exit((int)$ret); + } + + /*$env = getenv(); + $env["PATH"] = $deps_root . DIRECTORY_SEPARATOR . "bin;" . $env["PATH"]; + + $php = $php_root . DIRECTORY_SEPARATOR . "php.exe"; + $php = $php_root . DIRECTORY_SEPARATOR . "php.exe";*/ + +} catch (Throwable $e) { + throw $e; + exit(3); +} + + +function usage(int $code = -1) +{ + echo "PHP SDK PGO training tool.", PHP_EOL; + echo "Usage: ", PHP_EOL, PHP_EOL; + echo "Commands:", PHP_EOL; + echo " -i --init Initialize training environment.", PHP_EOL; + echo " -t --train Run training. This involves startup, training and shutdown.", PHP_EOL; + echo " -u --up Startup training environment.", PHP_EOL; + echo " -d --down Shutdown training environment.", PHP_EOL; + echo " -f --force Force requested operation. Not every option can be forced.", PHP_EOL; + echo " -s --scenario Run training with a specified scenario.", PHP_EOL; + echo " -c --cases Run training with specified cases only. If omited, all the active cases will be used.", PHP_EOL; + + /*echo " -p --php-root PHP binary to train.", PHP_EOL;*/ + + $code = -1 == $code ? 0 : $code; + exit($code); +} + +function msg(string $s, int $code = 0) { + echo $s, PHP_EOL; + exit($code); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/bin/phpsdk_rebase_msys2.cmd b/bin/phpsdk_rebase_msys2.cmd new file mode 100644 index 0000000..6d009d8 --- /dev/null +++ b/bin/phpsdk_rebase_msys2.cmd @@ -0,0 +1,40 @@ +@echo off + +setlocal enableextensions enabledelayedexpansion + +set PHPSDK_MSYS2_BASE_ADDR=0x100400000 +set PHPSDK_MSYS2_BASE_DYNAMIC=0 + +:getopt +if /i "%1" equ "--help" goto help +if /i "%1" equ "--addr" ( + set PHPSDK_MSYS2_BASE_ADDR=%2 & shift + for /l %%a in (1,1,100) do if "!PHPSDK_MSYS2_BASE_ADDR:~-1!"==" " set PHPSDK_MSYS2_BASE_ADDR=!PHPSDK_MSYS2_BASE_ADDR:~0,-1! +) +shift +if /i "%1" equ "--dynamic" ( + set PHPSDK_MSYS2_BASE_DYNAMIC=1 + shift +) +if not (%1)==() goto getopt + +IF "1" EQU "%PHPSDK_MSYS2_BASE_DYNAMIC%" ( + echo Rebasing MSYS2 DLLs to load at a dynamic address + editbin /NOLOGO /DYNAMICBASE %PHP_SDK_ROOT_PATH%\msys2\usr\bin\*.dll +) else ( + echo Rebasing MSYS2 DLLs to load at %PHPSDK_MSYS2_BASE_ADDR% + editbin /NOLOGO /REBASE:BASE=%PHPSDK_MSYS2_BASE_ADDR%,DOWN %PHP_SDK_ROOT_PATH%\msys2\usr\bin\*.dll +) + +set PHPSDK_MSYS2_BASE_ADDR= +set PHPSDK_MSYS2_BASE_DYNAMIC= + +GOTO EXIT + +:help +echo phpsdk_rebase_msys2 ^ +echo Rebase MSYS2 DLLs to the given address. If ommited, default is 0x100400000. + +:EXIT +exit /b %errorlevel% + diff --git a/bin/phpsdk_setshell.bat b/bin/phpsdk_setshell.bat new file mode 100755 index 0000000..224c7f5 --- /dev/null +++ b/bin/phpsdk_setshell.bat @@ -0,0 +1,240 @@ +@echo off + +if not defined PHP_SDK_RUN_FROM_ROOT ( + echo This script should not be run directly. + echo Use starter scripts looking like phpsdk-^-^.bat in the PHP SDK root instead. + goto out_error +) + + +if "%1"=="" goto :help +if "%1"=="/?" goto :help +if "%1"=="-h" goto :help +if "%1"=="--help" goto :help +if "%2"=="" goto :help + +cmd /c "exit /b 0" + +set PHP_SDK_VS=%1 +if /i not "%PHP_SDK_VS:~0,2%"=="vc" ( + if /i not "%PHP_SDK_VS:~0,2%"=="vs" ( +:malformed_vc_string + echo Malformed CRT string "%1" + set PHP_SDK_VS= + goto out_error + ) +) +if ""=="%PHP_SDK_VS:~2%" ( + goto malformed_vc_string +) +set /a TMP_CHK=%PHP_SDK_VS:~2% +if 14 gtr %TMP_CHK% ( + if "0"=="%TMP_CHK%" ( + if not "0"=="%PHP_SDK_VS:~2%" ( + set TMP_CHK= + goto malformed_vc_string + ) + ) + + echo At least vc14 is required + set PHP_SDK_VS= + set TMP_CHK= + goto out_error +) +set PHP_SDK_VS_NUM=%TMP_CHK% +set TMP_CHK= + +rem check target arch +if "%2"=="x86" set PHP_SDK_ARCH=%2 +if "%2"=="x64" set PHP_SDK_ARCH=%2 +if "%2"=="x86_64" set PHP_SDK_ARCH=x64 +if "%2"=="amd64" set PHP_SDK_ARCH=x64 +if "%2"=="arm64" set PHP_SDK_ARCH=%2 +if "%PHP_SDK_ARCH%"=="" ( + echo Unsupported target arch %2 >&2 + goto out_error +) + +set TOOLSET= +if NOT "%3"=="" SET TOOLSET=%3 + +rem check OS arch +rem todo: allow user choose host sdk arch (i.e. x64 target can be compiled at x64(native) or x86(cross)) +for /f "usebackq tokens=*" %%i in (`powershell -NoProfile -Command "Get-CimInstance -ClassName Win32_Processor | Select-Object -ExpandProperty Architecture"`) do ( + set PHP_SDK_OS_ARCH_NUM=%%i +) + +goto os_arch_cases +:os_arch_error +echo Unsupported OS arch %PHP_SDK_OS_ARCH% >&2 +goto out_error + +:os_arch_cases +if "%PHP_SDK_OS_ARCH_NUM%"=="0" set PHP_SDK_OS_ARCH=x86 +if "%PHP_SDK_OS_ARCH_NUM%"=="1" (set PHP_SDK_OS_ARCH=mips && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="2" (set PHP_SDK_OS_ARCH=alpha && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="3" (set PHP_SDK_OS_ARCH=ppc && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="4" (set PHP_SDK_OS_ARCH=shx && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="5" (set PHP_SDK_OS_ARCH=arm32 && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="6" (set PHP_SDK_OS_ARCH=ia64 && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="7" (set PHP_SDK_OS_ARCH=alpha64 && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="8" (set PHP_SDK_OS_ARCH=msil && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="9" set PHP_SDK_OS_ARCH=x64 +rem wow64 +if "%PHP_SDK_OS_ARCH_NUM%"=="10" set PHP_SDK_OS_ARCH=x86 +if "%PHP_SDK_OS_ARCH_NUM%"=="11" (set PHP_SDK_OS_ARCH=neutral && goto os_arch_error) +if "%PHP_SDK_OS_ARCH_NUM%"=="12" set PHP_SDK_OS_ARCH=arm64 +if "%PHP_SDK_OS_ARCH_NUM%"=="13" (set PHP_SDK_OS_ARCH=arm32 && goto os_arch_error) +rem woa64 +if "%PHP_SDK_OS_ARCH_NUM%"=="14" set PHP_SDK_OS_ARCH=x86 +if "%PHP_SDK_OS_ARCH%"=="" ( + goto os_arch_error +) + +set PHP_SDK_OS_ARCH_NUM= + +rem cross compile is ok, so we donot need this +rem if not /i "%PHP_SDK_ARCH%"=="PHP_SDK_OS_ARCH" ( +rem echo 32-bit OS detected, native 64-bit toolchain is unavailable. +rem goto out_error +rem ) + +rem get vc base dir +if 15 gtr %PHP_SDK_VS_NUM% ( + rem for arch other than x86, use WOW6432 + if /i not "%PHP_SDK_OS_ARCH%"=="x86" ( + set TMPKEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%PHP_SDK_VS:~2%.0\Setup\VC + ) else ( + set TMPKEY=HKLM\SOFTWARE\Microsoft\VisualStudio\%PHP_SDK_VS:~2%.0\Setup\VC + ) + reg query !TMPKEY! /v ProductDir >nul 2>&1 + if errorlevel 1 ( + echo Couldn't determine VC%PHP_SDK_VS:~2% directory + goto out_error; + ) + for /f "tokens=2*" %%a in ('reg query !TMPKEY! /v ProductDir') do set PHP_SDK_VC_DIR=%%b +) else ( + rem build the version range, e.g. "[15,16)" + set /a PHP_SDK_VS_RANGE=PHP_SDK_VS_NUM + 1 + set PHP_SDK_VS_RANGE="[%PHP_SDK_VS_NUM%,!PHP_SDK_VS_RANGE%!)" + + set APPEND=x86.x64 + if /i "%PHP_SDK_OS_ARCH%"=="arm64" ( + set APPEND=ARM64 + ) + set VS_VERSION_ARGS="-latest" + if "%TOOLSET%"=="" set VS_VERSION_ARGS=-version !PHP_SDK_VS_RANGE! + for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo !VS_VERSION_ARGS! -requires Microsoft.VisualStudio.Component.VC.Tools.!APPEND! -property installationPath -format text') do ( + set PHP_SDK_VC_DIR=%%b\VC + ) + if not exist "!PHP_SDK_VC_DIR!" ( + for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo !VS_VERSION_ARGS! -products Microsoft.VisualStudio.Product.BuildTools -requires Microsoft.VisualStudio.Component.VC.Tools.!APPEND! -property installationPath -format text') do ( + set PHP_SDK_VC_DIR=%%b\VC + ) + if not exist "!PHP_SDK_VC_DIR!" ( + rem check for a preview release + for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo !VS_VERSION_ARGS! -prerelease -requires Microsoft.VisualStudio.Component.VC.Tools.!APPEND! -property installationPath -format text') do ( + set PHP_SDK_VC_DIR=%%b\VC + ) + if not exist "!PHP_SDK_VC_DIR!" ( + echo Could not determine '%PHP_SDK_VS%' directory + goto out_error; + ) + ) + ) + set VSCMD_ARG_no_logo=nologo +) +set APPEND= +set TMPKEY= +set PHP_SDK_VS_RANGE= + +if 15 gtr %PHP_SDK_VS_NUM% ( + rem get sdk dir + rem if 10.0 is available, it's ok + rem for arch other than x86, use WOW6432 + if /i not "%PHP_SDK_OS_ARCH%"=="x86" ( + set TMPKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0 + ) else ( + set TMPKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0 + ) + for /f "tokens=2*" %%a in ('reg query "!TMPKEY!" /v InstallationFolder') do ( + for /f "tokens=2*" %%c in ('reg query "!TMPKEY!" /v ProductVersion') do ( + if exist "%%bInclude\%%d.0\um\Windows.h" ( + goto got_sdk + ) + ) + ) + + rem Otherwise 8.1 should be available anyway + rem for arch other than x86, use WOW6432 + if /i not "%PHP_SDK_OS_ARCH%"=="x86" ( + set TMPKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v8.1 + ) else ( + set TMPKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1 + ) + for /f "tokens=2*" %%a in ('reg query "!TMPKEY!" /v InstallationFolder') do ( + if exist "%%b\Include\um\Windows.h" ( + goto got_sdk + ) + ) + + echo Windows SDK not found. + goto out_error; +:got_sdk + set TMPKEY= +) + +if /i "%PHP_SDK_ARCH%"=="x64" ( + set TARGET_ARCH_NAME=amd64 +) else ( + set TARGET_ARCH_NAME=%PHP_SDK_ARCH% +) + +if /i "%PHP_SDK_OS_ARCH%"=="x64" ( + set HOST_ARCH_NAME=amd64 +) else ( + set HOST_ARCH_NAME=%PHP_SDK_ARCH% +) + +if "%HOST_ARCH_NAME%"=="%TARGET_ARCH_NAME%" ( + set VCVARSALL_ARCH_NAME=%HOST_ARCH_NAME% +) else if "%HOST_ARCH_NAME%_%TARGET_ARCH_NAME%"=="amd64_x86" ( + set VCVARSALL_ARCH_NAME=%TARGET_ARCH_NAME% +) else ( + set VCVARSALL_ARCH_NAME=%HOST_ARCH_NAME%_%TARGET_ARCH_NAME% +) +if 15 gtr %PHP_SDK_VS_NUM% ( + if NOT "%TOOLSET%"=="" ( + set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" !VCVARSALL_ARCH_NAME! -vcvars_ver=%TOOLSET% + ) else ( + set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" !VCVARSALL_ARCH_NAME! + ) +) else ( + if NOT "%TOOLSET%"=="" ( + set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" !VCVARSALL_ARCH_NAME! -vcvars_ver=%TOOLSET% + ) else ( + set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" !VCVARSALL_ARCH_NAME! + ) +) +set VCVARSALL_ARCH_NAME= + +rem echo Visual Studio VC path %PHP_SDK_VC_DIR% +rem echo Windows SDK path %PHP_SDK_WIN_SDK_DIR% + + +goto out + +:help + echo "Start Visual Studio command line for PHP SDK" + echo "Usage: %0 vc arch" + echo nul + +:out_error + exit /b 3 + +:out +rem echo Shell configuration complete + exit /b 0 + +goto :eof + diff --git a/bin/phpsdk_setvars.bat b/bin/phpsdk_setvars.bat old mode 100644 new mode 100755 index 98efafc..59ce297 --- a/bin/phpsdk_setvars.bat +++ b/bin/phpsdk_setvars.bat @@ -1,13 +1,28 @@ -REM phpsdk.bat -@ECHO OFF - -REM Add skd\bin directory to the path -SET PHP_SDK_SCRIPT_PATH=%~dp0 -SET PHP_SDK_BIN_PATH=%PHP_SDK_SCRIPT_PATH%\..\bin -SET PHP_SDK_PATH=%PHP_SDK_SCRIPT_PATH%\.. - -SET PATH=%PATH%;%PHP_SDK_BIN_PATH%;%PHP_SDK_SCRIPT_PATH%;D:\apps\svn\bin - -REM Set BISON_SIMPLE -SET BISON_SIMPLE=%PHP_SDK_BIN_PATH%\bison.simple - +@echo off + +cmd /c "exit /b 0" + +rem Add necessary dirs to the path + +set PHP_SDK_BIN_PATH=%~dp0 +rem remove trailing slash +set PHP_SDK_BIN_PATH=%PHP_SDK_BIN_PATH:~0,-1% + +for %%a in ("%PHP_SDK_BIN_PATH%") do set PHP_SDK_ROOT_PATH=%%~dpa +rem remove trailing slash +set PHP_SDK_ROOT_PATH=%PHP_SDK_ROOT_PATH:~0,-1% + +set PHP_SDK_MSYS2_PATH=%PHP_SDK_ROOT_PATH%\msys2\usr\bin +set PHP_SDK_PHP_CMD=%PHP_SDK_BIN_PATH%\php\do_php.bat + +set PATH=%PHP_SDK_BIN_PATH%;%PHP_SDK_MSYS2_PATH%;%PATH% + +for /f "tokens=1* delims=: " %%a in ('link /?') do ( + set PHP_SDK_VC_TOOLSET_VER=%%b + goto break0 +) +:break0 +set PHP_SDK_VC_TOOLSET_VER=%PHP_SDK_VC_TOOLSET_VER:~-13% + +exit /b %errorlevel% + diff --git a/bin/phpsdk_version.bat b/bin/phpsdk_version.bat new file mode 100755 index 0000000..d388912 --- /dev/null +++ b/bin/phpsdk_version.bat @@ -0,0 +1,16 @@ +@echo off + +cmd /c "exit /b 0" + +if "%PHP_SDK_PHP_CMD%"=="" ( + call %~dp0phpsdk_setvars.bat + if "!PHP_SDK_PHP_CMD!"=="" ( + echo PHP SDK is not setup + exit /b 3 + ) +) + +%PHP_SDK_PHP_CMD% -r "echo 'PHP SDK ' . file_get_contents(getenv('PHP_SDK_ROOT_PATH') . '\\VERSION');" + +exit /b %errorlevel% + diff --git a/bin/phpsdkvars.bat b/bin/phpsdkvars.bat deleted file mode 100644 index 0b42b0d..0000000 --- a/bin/phpsdkvars.bat +++ /dev/null @@ -1,10 +0,0 @@ -::phpsdk.bat -@ECHO OFF -:: Add skd\bin directory to the path - -SET PHP_SDK_BIN_PATH=%~dp0 - -SET PATH=%PATH%;%PHP_SDK_BIN_PATH% - -:: Set BISON_SIMPLE -SET BISON_SIMPLE=%PHP_SDK_BIN_PATH%bison.simple diff --git a/bin/re2c.exe b/bin/re2c.exe deleted file mode 100644 index 8cd0747..0000000 Binary files a/bin/re2c.exe and /dev/null differ diff --git a/bin/regex2.dll b/bin/regex2.dll deleted file mode 100644 index f84a847..0000000 Binary files a/bin/regex2.dll and /dev/null differ diff --git a/bin/sed.exe b/bin/sed.exe deleted file mode 100644 index 3190377..0000000 Binary files a/bin/sed.exe and /dev/null differ diff --git a/bin/sha1sum.exe b/bin/sha1sum.exe deleted file mode 100644 index aef88c5..0000000 Binary files a/bin/sha1sum.exe and /dev/null differ diff --git a/bin/snapshot.bat b/bin/snapshot.bat deleted file mode 100644 index bb9c795..0000000 --- a/bin/snapshot.bat +++ /dev/null @@ -1,272 +0,0 @@ -@ECHO off -REM Configuration -CALL %PHP_SDK_PATH%\script\conf_tools.bat - -IF EXIST %PHP_SDK_PATH%\snaps.lock ( - ECHO Snapshot script is already running - GOTO EXIT_LOCKED -) - -SET LOG_DIR=%PHP_SDK_PATH%\log -SET START=%CD% -echo "LOCKED" > %PHP_SDK_PATH%\snaps.lock - -IF "%1"=="" GOTO HELP -IF "%2"=="" GOTO HELP -IF "%3"=="" GOTO HELP -IF "%4"=="" SET USE_CVS=Yes -IF "%5"=="msi" SET USE_INSTALLER=Yes - -SET SRC_ARCHIVE=%4 -SET VC=%1 -SET BRANCH=%2 -SET DEST=%3 -FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CALL_DATE=%%B -FOR /F "TOKENS=*" %%A IN ('TIME/T') DO SET CALL_TIME=%%A -SET CALL_DATETIME=%CALL_DATE% %CALL_TIME% - -IF "%2"=="5.2" ( - SET BRANCH=PHP_5_2 - SET PHP_VERSION=5.2 - GOTO START -) -IF "%2"=="5.3" ( - SET BRANCH=PHP_5_3 - SET PHP_VERSION=5.3 - GOTO START -) -IF "%2"=="6.0" ( - SET BRANCH=HEAD - SET PHP_VERSION=6.0 - GOTO START -) -echo Invalid branch name -GOTO EXIT - -:START -for /F "tokens=1-4 delims=:., " %%a in ('time/T') do set _TIME=%%a%%b%%c -for /F "tokens=2-5 delims=:.,/ " %%a in ('date/T') do set _DATE=%%a%%b%%c -SET SNAPDATETIME=%_DATE%%_TIME% - -REM IF EXIST %3 rmdir /s /q %3 -SET OLD_INCLUDE=%INCLUDE% -SET OLD_LIB=%LIB% -SET OLD_PATH=%PATH% - -IF "%VC%"=="6" GOTO CONFIG_VC6 -IF "%VC%"=="9" GOTO CONFIG_VC9 -IF "%VC%"=="9x64" GOTO CONFIG_VC9_X64 -echo Invalid VC Version -GOTO EXIT - -:CONFIG_VC6 -ECHO Setting environment for VC6-x86 -SET INCLUDE=%VC6_INCLUDE% -SET LIB=%VC6_LIB% -SET PATH=%VC6_PATH%;%PATH% -SET ARCH=x86 -SET VC_VERS=VC6 -GOTO CVS - -:CONFIG_VC9 -ECHO Setting environment for VC9-x86 -SET INCLUDE=%VC9_INCLUDE% -SET LIB=%VC9_LIB% -SET PATH=%VC9_PATH%;%PATH% -SET VC_VERS=VC9 -SET ARCH=x86 -GOTO CVS - -:CONFIG_VC9_X64 -ECHO Setting environment for VC9-x64 -SET INCLUDE=%VC9_X64_INCLUDE% -SET LIB=%VC9_LIB% -SET PATH=%VC9_X64_PATH%;%PATH% -SET VC_VERS=VC9 -SET ARCH=x64 - -:CVS -IF NOT "%USE_CVS%"=="Yes" GOTO USE_LAST_ARCHIVE -IF EXIST %DEST% RD /Q /S %DEST% -echo checkout from cvs %PHP_CVSROOT% -z3 checkout -r %BRANCH% -d %DEST% %PHP_MODULE% -cvs %PHP_CVSROOT% -z3 export -r %BRANCH% -d %DEST% %PHP_MODULE% > %START%\cvs.log 2<&1 - -GOTO TEST_DEST - -:USE_LAST_ARCHIVE -ECHO Using archive %SRC_ARCHIVE% ... -unzip -o -qq %SRC_ARCHIVE% -FOR /D %%A IN (php-?.?-src-*) DO ( - SET DIRNAME=%%A -) -ECHO Using %DIRNAME% ... -IF EXIST %DIRNAME%.last GOTO ALREADY_DONE -IF EXIST %DEST% RD /Q /S %DEST% -REN %DIRNAME% %DEST% - -REM Clean old directories and .last file -FOR /D %%A IN (php-?.?-src-*) DO ( - RD /Q /S %%A -) -FOR /F "tokens=4 delims=-" %%A IN ("%DIRNAME%") DO SET SNAPDATETIME=%%A - -:TEST_DEST -echo Testing %DEST%... -IF EXIST %DEST% GOTO DEST_EXISTS -ECHO CVS or Archive ERROR %DEST% cannot be found -GOTO EXIT - -:DEST_EXISTS -echo Compiling... -cd %DEST% - -echo Buildconf log for %SNAPDATETIME% called at %CALL_DATETIME% >> %START%\buildconf.log -call buildconf.bat > %START%\buildconf.log 2<&1 - -echo Configure log for %SNAPDATETIME% called at %CALL_DATETIME% > %START%\configure.log 2<&1 -cscript /nologo configure.js %CONFIGURE_ARGS% >> %START%\configure.log 2<&1 - -echo Compile log for %SNAPDATETIME% called at %CALL_DATETIME% > %START%\compile.log -nmake snap >> %START%\compile.log 2<&1 - -:TRANSFERT -echo Transfert files to %SSH_HOST% -cd %DEST% -IF EXIST Release_TS GOTO RELEASE_TS -IF EXIST Release GOTO RELEASE_NTS - -:RELEASE_TS -SET PHP_BUILD_DIR=Release_TS -SET PHP_EXE=Release_TS\php.exe -SET NTS_POSTFIX= -SET NTS=ts -IF NOT EXIST %PHP_EXE% ( - ECHO Build error. - GOTO EXIT -) -GOTO REMOTE_COPY - -:RELEASE_NTS -SET PHP_BUILD_DIR=Release -SET PHP_EXE=Release\php.exe -SET NTS_POSTFIX=-nts -SET NTS=nts -IF NOT EXIST %PHP_EXE% ( - ECHO Build error. - GOTO EXIT -) -:REMOTE_COPY -FOR /F "tokens=*" %%A IN ('%PHP_EXE% -r "echo substr(phpversion(),0,3);"') DO SET _PHPVERSION_SHORT=%%A -FOR /F "tokens=*" %%A IN ('%PHP_EXE% -r "echo phpversion();"') DO SET _PHPVERSION_STRING=%%A -IF "%USE_CVS%"=="Yes" FOR /F "tokens=*" %%A IN ('%PHP_EXE% -r "echo date('YmdHi');"') DO SET SNAPDATETIME=%%A - -SET SSH_URL=%SSH_USER%@%SSH_HOST% -echo %SSH_KEY% -FOR %%A IN (%START%\*.log) DO ( - ECHO copying %LOG_DIR%\%%~nA-%_PHPVERSION_SHORT%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log ... - COPY %START%\%%~nA.log %LOG_DIR%\%%~nA-%_PHPVERSION_SHORT%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log - "%PUTTYBASE%pscp.exe" -batch -q -i %SSH_KEY% -l %SSH_USER% %LOG_DIR%\%%~nA-%_PHPVERSION_SHORT%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log %SSH_URL%:%REMOTE_PATH% >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -) - -FOR %%A IN (%PHP_BUILD_DIR%\*.zip) DO ( - echo Copying %%~nA-%SNAPDATETIME%.zip ... - "%PUTTYBASE%pscp.exe" -batch -q -i %SSH_KEY% -l %SSH_USER% %PHP_BUILD_DIR%\%%~nA.zip %SSH_URL%:%REMOTE_PATH%/%%~nA-%SNAPDATETIME%.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 - copy %PHP_BUILD_DIR%\%%~nA.zip %PHP_BUILD_DIR%\%%~nA-%SNAPDATETIME%.zip -) - - -REM Remove old links and create the "-latest links" -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/php-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/php-debug-pack-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/php-test-pack-%_PHPVERSION_SHORT%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/compile-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/buildconf-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/configure-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "rm -f" %REMOTE_PATH%/cache.info >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 - -SET VERSION_INFO=%_PHPVERSION_STRING%%NTS_POSTFIX%-Win32 - -IF "%PHP_VERSION%"=="5.2" GOTO OLD_NAMING - -:CLEAN_NAMING -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/php-%VERSION_INFO%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.zip %REMOTE_PATH%/php-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/php-debug-pack-%VERSION_INFO%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.zip %REMOTE_PATH%/php-debug-pack-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/php-test-pack-%_PHPVERSION_STRING%-%SNAPDATETIME%.zip %REMOTE_PATH%/php-test-pack-%_PHPVERSION_SHORT%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/compile-%PHP_VERSION%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log %REMOTE_PATH%/compile-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/buildconf-%PHP_VERSION%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log %REMOTE_PATH%/buildconf-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/configure-%PHP_VERSION%-%VC_VERS%-%ARCH%%NTS_POSTFIX%-%SNAPDATETIME%.log %REMOTE_PATH%/configure-%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 - -SET PHP_ZIP_FILE=%PHP_BUILD_DIR%\php-%VERSION_INFO%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.zip -GOTO INSTALLER - -:OLD_NAMING -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/php-%VERSION_INFO%-%SNAPDATETIME%.zip %REMOTE_PATH%/php-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/php-debug-pack-%VERSION_INFO%-%SNAPDATETIME%.zip %REMOTE_PATH%/php-debug-pack-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.zip >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/compile-%PHP_VERSION%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log %REMOTE_PATH%/compile-%PHP_VERSION%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/buildconf-%PHP_VERSION%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log %REMOTE_PATH%/buildconf-%PHP_VERSION%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/configure-%PHP_VERSION%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log %REMOTE_PATH%/configure-%PHP_VERSION%-%VC_VERS%-%ARCH%-latest.log >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 - -SET PHP_ZIP_FILE=%PHP_BUILD_DIR%\php-%VERSION_INFO%-%SNAPDATETIME%.zip -GOTO INSTALLER - - -:INSTALLER -echo ************************ 3 -IF "%USE_INSTALLER%"=="Yes" ( - echo ************************ 3.1 installer - FOR %%A IN (%PHP_ZIP_FILE%) DO ( - echo snapshot_installer.bat %PHP_VERSION%.0 %NTS% %VC_VERS% %ARCH% %%~fA - CALL snapshot_installer.bat %PHP_VERSION%.0 %NTS% %VC_VERS% %ARCH% %%~fA >> %LOG_DIR%\msi_%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log 2<&1 - ) -) - -FOR %%A IN (%PHP_BUILD_DIR%\*.msi) DO ( - echo Copying %%~nA.msi ... - "%PUTTYBASE%pscp.exe" -batch -q -i %SSH_KEY% -l %SSH_USER% %PHP_BUILD_DIR%\%%~nA.msi %SSH_URL%:%REMOTE_PATH%/%%~nA.msi >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log 2<&1 - "%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% rm %REMOTE_PATH%/php-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.msi >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log 2<&1 - "%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% ln -s %REMOTE_PATH%/%%~nA.msi %REMOTE_PATH%/php-%PHP_VERSION%%NTS_POSTFIX%-win32-%VC_VERS%-%ARCH%-latest.msi >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%VC_VERS%-%ARCH%-%SNAPDATETIME%.log 2<&1 -) - -"%PUTTYBASE%plink.exe" -i %SSH_KEY% -l %SSH_USER% %SSH_HOST% "sha1sum %REMOTE_PATH%/*-latest.zip %REMOTE_PATH%/*-latest.msi > %REMOTE_PATH%/sha1sum.txt" >> %LOG_DIR%\scp_%PHP_VERSION%%NTS_POSTFIX%-%SNAPDATETIME%.log 2<&1 - -echo ************************ 4 -GOTO EXIT - -:HELP -ECHO snapshot ^ ^ ^ -GOTO EXIT - -:ALREADY_DONE -ECHO Snapshot for %DIRNAME% already done - - -:EXIT -del %PHP_SDK_PATH%\snaps.lock - -FOR /D %%A IN (*.last) DO ( - DEL %%A -) - -REM Set the last "snap" -echo %DIRNAME% > %DIRNAME%.last - -:EXIT_LOCKED -cd %START% - -SET LIB=%OLD_LIB% -SET INCLUDE=%OLD_INCLUDE% -SET PATH=%OLD_PATH% - -SET BRANCH= -SET DEST= -SET DIRNAME= -SET USE_CVS= -SET LOG_DIR= -SET NTS_POSTFIX= -SET PHP_BUILD_DIR= -SET PHP_EXE= -SET PHP_VERSION= -SET SSH_URL= -SET START= -SET VC= -SET ZIP_PATH= \ No newline at end of file diff --git a/bin/snapshot_5_2.bat b/bin/snapshot_5_2.bat deleted file mode 100644 index 60f3593..0000000 --- a/bin/snapshot_5_2.bat +++ /dev/null @@ -1,30 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - - -IF "%1" == "" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --with-snapshot-template=%PHP_SDK_PATH%\snap_5_2\vc6\x86\template --with-php-build=%PHP_SDK_PATH%\snap_5_2\vc6\x86\php_build --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared -) - -IF "%1" == "ts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --with-snapshot-template=%PHP_SDK_PATH%\snap_5_2\vc6\x86\template --with-php-build=%PHP_SDK_PATH%\snap_5_2\vc6\x86\php_build --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared -) - -IF "%1" == "nts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --disable-zts --disable-isapi --with-snapshot-template=%PHP_SDK_PATH%\snap_5_2\vc6\x86\template --with-php-build=%PHP_SDK_PATH%\snap_5_2\vc6\x86\php_build --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared -) - -SET PHP_MODULE=php5 - -IF "%2" == "" ( - CD %PHP_SDK_PATH%\snap_5_2\sources - CALL snapshot_src_download.bat 5.2 -) - -CD %PHP_SDK_PATH%\snap_5_2\vc6\x86 -CALL snapshot.bat 6 5.2 snap52_vc6 %PHP_SDK_PATH%\snap_5_2\sources\php-5.2-src-latest.zip %4 diff --git a/bin/snapshot_5_2_all.bat b/bin/snapshot_5_2_all.bat deleted file mode 100644 index d618c10..0000000 --- a/bin/snapshot_5_2_all.bat +++ /dev/null @@ -1,13 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -CD %PHP_SDK_PATH%\snap_5_2\sources -CALL snapshot_src_download.bat 5.2 - -CMD /C snapshot_5_2.bat ts nodownload no msi -CMD /C snapshot_5_2.bat nts nodownload no msi diff --git a/bin/snapshot_5_3.bat b/bin/snapshot_5_3.bat deleted file mode 100644 index 4f0f0cd..0000000 --- a/bin/snapshot_5_3.bat +++ /dev/null @@ -1,28 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -SET PHP_MODULE=php5 - -IF "%1" == "" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --disable-isapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) -IF "%1" == "ts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --disable-isapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -IF "%1" == "nts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --disable-zts --disable-isapi --disable-nsapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -IF "%2" == "" ( - CD %PHP_SDK_PATH%\snap_5_3\sources - CALL snapshot_src_download.bat 5.3 -) - -CD %PHP_SDK_PATH%\snap_5_3\vc6\x86 -CALL snapshot.bat 6 5.3 snap53_vc6 %PHP_SDK_PATH%\snap_5_3\sources\php-5.3-src-latest.zip %4 diff --git a/bin/snapshot_5_3_all.bat b/bin/snapshot_5_3_all.bat deleted file mode 100644 index 15a8f9b..0000000 --- a/bin/snapshot_5_3_all.bat +++ /dev/null @@ -1,14 +0,0 @@ -@ECHO OFF - -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\php53vc9x86.ini -SET PATH=%OLDPATH% -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\php53ntsvc9x86.ini -SET PATH=%OLDPATH% -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\php53vc6x86.ini -SET PATH=%OLDPATH% -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\php53ntsvc6x86.ini -SET PATH=%OLDPATH% \ No newline at end of file diff --git a/bin/snapshot_5_3_all.bat.oldsnap b/bin/snapshot_5_3_all.bat.oldsnap deleted file mode 100644 index 16edca7..0000000 --- a/bin/snapshot_5_3_all.bat.oldsnap +++ /dev/null @@ -1,15 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -CD %PHP_SDK_PATH%\snap_5_3\sources -CALL snapshot_src_download.bat 5.3 - -CMD /C snapshot_5_3_vc9.bat ts nodownload no msi -CMD /C snapshot_5_3_vc9.bat nts nodownload no msi -CMD /C snapshot_5_3.bat ts nodownload no msi -CMD /C snapshot_5_3.bat nts nodownload no msi diff --git a/bin/snapshot_5_3_vc9.bat b/bin/snapshot_5_3_vc9.bat deleted file mode 100644 index 47ecd96..0000000 --- a/bin/snapshot_5_3_vc9.bat +++ /dev/null @@ -1,30 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -CD %PHP_SDK_PATH%\php_5_3\vc9\x86 - -IF "%1" == "" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --disable-isapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared --with-enchant=shared -) -IF "%1" == "ts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --disable-isapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared --with-enchant=shared -) - -IF "%1" == "nts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --disable-zts --disable-isapi --disable-nsapi --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared --with-enchant=shared -) - -SET PHP_MODULE=php5 - -IF "%2" == "" ( - CD %PHP_SDK_PATH%\snap_5_3\sources - CALL snapshot_src_download.bat 5.3 -) - -CD %PHP_SDK_PATH%\snap_5_3\vc9\x86 -CALL snapshot.bat 9 5.3 snap53_vc9 %PHP_SDK_PATH%\snap_5_3\sources\php-5.3-src-latest.zip %4 diff --git a/bin/snapshot_5_3_vc9x64.bat b/bin/snapshot_5_3_vc9x64.bat deleted file mode 100644 index 9d5fe90..0000000 --- a/bin/snapshot_5_3_vc9x64.bat +++ /dev/null @@ -1,25 +0,0 @@ -@ECHO OFF -REM %VC9_SHELL% - -REM CD "C:\Program Files\Microsoft SDKs\Windows\v6.1\" -REM CALL "C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\SetEnv.Cmd" /x86 /xp /release - -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -SET CONFIGURE_ARGS=--enable-snapshot-build --enable-debug-pack --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared --with-enchant=shared -SET PHP_MODULE=php5 - -CD %PHP_SDK_PATH%\snap_5_3\sources -CALL snapshot_src_download.bat 5.3 - -REM XP is the minimum version we support -REM setenv /x86 /xp /release - -CD %PHP_SDK_PATH%\snap_5_3\vc9\x64 -CALL snapshot.bat 9x64 PHP_5_3 snap53_vc9x64 %PHP_SDK_PATH%\snap_5_3\sources\php-5.3-src-latest.zip - diff --git a/bin/snapshot_6_0.bat b/bin/snapshot_6_0.bat deleted file mode 100644 index 777b3da..0000000 --- a/bin/snapshot_6_0.bat +++ /dev/null @@ -1,31 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -SET PHP_MODULE=HEAD - -IF "%1" == "" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --without-sqlite --without-apache-hooks --without-static-icu --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) -IF "%1" == "ts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --without-sqlite --without-apache-hooks --without-static-icu --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -IF "%1" == "nts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-zts --without-sqlite --disable-isapi --without-apache-hooks --enable-debug-pack --without-static-icu --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -SET OLD_PATH=%PATH% -SET PATH=%PATH%;%PHP_SDK_PATH%\snap_6_0\vc6\x86\deps\bin - -IF "%2" == "" ( - CD %PHP_SDK_PATH%\snap_6_0\sources - CALL snapshot_src_download.bat 6.0 -) - -CD %PHP_SDK_PATH%\snap_6_0\vc6\x86 -CALL snapshot.bat 6 6.0 snap60_vc6 %PHP_SDK_PATH%\snap_6_0\sources\php-6.0-src-latest.zip %4 diff --git a/bin/snapshot_6_0_all.bat b/bin/snapshot_6_0_all.bat deleted file mode 100644 index 4576b79..0000000 --- a/bin/snapshot_6_0_all.bat +++ /dev/null @@ -1,15 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -CD %PHP_SDK_PATH%\snap_6_0\sources -CALL snapshot_src_download.bat 6.0 - -CMD /C snapshot_6_0_vc9.bat ts nodownload no msi -CMD /C snapshot_6_0_vc9.bat nts nodownload no msi -REM CMD /C snapshot_6_0.bat ts nodownload no msi -REM CMD /C snapshot_6_0.bat nts nodownload no msi \ No newline at end of file diff --git a/bin/snapshot_6_0_vc9.bat b/bin/snapshot_6_0_vc9.bat deleted file mode 100644 index 35123af..0000000 --- a/bin/snapshot_6_0_vc9.bat +++ /dev/null @@ -1,32 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 - -REM change the drive -%~d0 - -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -SET PHP_MODULE=HEAD - -IF "%1" == "" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --without-static-icu --without-sqlite --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -IF "%1" == "ts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-isapi --enable-debug-pack --without-static-icu --without-sqlite --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -IF "%1" == "nts" ( - SET CONFIGURE_ARGS=--enable-snapshot-build --disable-zts --disable-isapi --enable-debug-pack --without-static-icu --without-sqlite --with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared --with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared -) - -SET OLD_PATH=%PATH% -SET PATH=%PATH%;%PHP_SDK_PATH%\snap_6_0\vc9\x86\deps\bin - -IF "%2" == "" ( - CD %PHP_SDK_PATH%\snap_6_0\sources - CALL snapshot_src_download.bat 6.0 -) - -CD %PHP_SDK_PATH%\snap_6_0\vc9\x86 -CALL snapshot.bat 9 6.0 snap60_vc9 %PHP_SDK_PATH%\snap_6_0\sources\php-6.0-src-latest.zip %4 diff --git a/bin/snapshot_installer.bat b/bin/snapshot_installer.bat deleted file mode 100644 index bb194bf..0000000 --- a/bin/snapshot_installer.bat +++ /dev/null @@ -1,124 +0,0 @@ -@echo off -goto old -IF "%1"=="" GOTO HELP -IF "%2"=="" GOTO HELP - -IF NOT EXIST %1% ( - echo ^<%1^> does not exist - GOTO EXIT -) - -IF NOT EXIST %2% ( - echo ^<%2^> does not exist - GOTO EXIT -) - -IF "%3%"=="VC9" ( - if "%4%"== "x64" set includevc9msm="x86_x64" - if "%4%"=="x86" set includevc9msm="x86" - if "%4%"=="" set includevc9msm="x86" -) -:old -SET PHP_SDK_SCRIPT_PATH=%~dp0 -SET START=%CD% -REM change the drive -%~d0 -echo %PHP_SDK_SCRIPT_PATH% -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -SET PHP_INSTALLER_PATH=%PHP_SDK_SCRIPT_PATH%..\win-installer -SET A=%~n5 -SET MSI_PATH=%A%.msi -cd %PHP_INSTALLER_PATH% -IF EXIST Files RD /Q /S Files -echo %5 -unzip -o -qq -d Files %5 - -SET php_exe=Files\php.exe - -copy %PHP_SDK_SCRIPT_PATH%..\template\php_manual_en.chm Files\ - -echo generating ... %MSI_PATH% - -set phpver=%1 -set phpver=%phpver:~0,3% -set phpver=%phpver:.=% - -echo Building ExtensionsFeatures.wxs -copy ExtensionsFeatures%phpver%.wxs ExtensionsFeatures.wxs - -set suffix= -set extrants= -set extrasnaps= -set buildtype="VC6-x86" -set includevc9msm= - -if (%2)==() goto build -if %2==nts set extrants="nts-" -if %2==nts set suffix=NTS -if %2==VC9 set buildtype="VC9-x86" -if %2==VC9 set includeVC9msm="x86" -if %2==x64 set buildtype="VC9-x64" -if %2==x64 set includeVC9msm="x86_x64" -if %2==snapshot set extrasnaps="-latest" - -if (%3)==() goto build -if %3==nts set extrants="nts-" -if %3==nts set suffix=NTS -if %3==VC9 set buildtype="VC9-x86" -if %3==VC9 set includeVC9msm="x86" -if %3==x64 set buildtype="VC9-x64" -if %3==x64 set includeVC9msm="x86_x64" -if %3==snapshot set extrasnaps="-latest" - -if (%4)==() goto build -if %4==nts set extrants="nts-" -if %4==nts set suffix="NTS" -if %4==VC9 set buildtype="VC9-x86" -if %4==VC9 set includeVC9msm="x86" -if %4==x64 set buildtype="VC9-x64" -if %4==x64 set includeVC9msm="x86_x64" -if %4==snapshot set extrasnaps="-latest" -echo WebServerConfig%phpver%%suffix%.wxs **** -echo %phpver% %suffix% - -:build -set msiname="%MSI_PATH%" - -echo Building ExtensionsFeatures.wxs -copy ExtensionsFeatures%phpver%.wxs ExtensionsFeatures.wxs - -echo Building ExtensionsComponents.wxs -%php_exe% GenExtensionsComponents.wxs.php "%phpver%" - -echo Building PHPInstaller%1.wxs -%php_exe% GenPHPInstaller.wxs.php "PHPInstallerBase%phpver%%suffix%.wxs" "%1" "%includevc9msm%" - -echo Building WebServerConfig%1.wxs -copy WebServerConfig%phpver%%suffix%.wxs WebServerConfig%1.wxs - -echo Compiling UI.... -Wix\candle.exe -out PHPInstallerCommon.wixobj PHPInstallerCommon%suffix%%phpver%.wxs - -echo Building UI.... -Wix\lit.exe -out PHPInstallerCommon.wixlib PHPInstallerCommon.wixobj - -echo Compiling Installer.... -Wix\candle.exe ExtensionsComponents.wxs ExtensionsFeaturesBuild.wxs WebServerConfig%1.wxs PHPInstaller%1.wxs - -echo Linking Installer.... -Wix\light.exe -out "%msiname%" ExtensionsComponents.wixobj ExtensionsFeaturesBuild.wixobj WebServerConfig%1.wixobj PHPInstaller%1.wixobj PHPInstallerCommon.wixlib -loc WixUI_en-us.wxl - - - -copy %msiname% %~dp5 -del %msiname% - -GOTO EXIT -:help -ECHO snapshot_installer ^ ^ -echo create the MSI file using the php version, architecture and compiler information -GOTO EXIT - -:EXIT -CD %START% \ No newline at end of file diff --git a/bin/snapshot_src_download.bat b/bin/snapshot_src_download.bat deleted file mode 100644 index d4be38e..0000000 --- a/bin/snapshot_src_download.bat +++ /dev/null @@ -1,41 +0,0 @@ -@ECHO OFF -SET PHP_SDK_SCRIPT_PATH=%~dp0 -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat -ECHO %PHP_SDK_SCRIPT_PATH% - -REM change the drive -%~d0 - -IF "%1"=="5.2" GOTO DOWNLOAD -IF "%1"=="5.3" GOTO DOWNLOAD -IF "%1"=="6.0" GOTO DOWNLOAD - -GOTO USAGE - -:DOWNLOAD -SET BRANCH=%1 -SET PHP_ARCHIVE_FILENAME=php-%BRANCH%-src-latest.zip - -IF EXIST %PHP_ARCHIVE_FILENAME% DEL %PHP_ARCHIVE_FILENAME% -wget http://windows.php.net/downloads/snaps/php-%BRANCH%/%PHP_ARCHIVE_FILENAME% -REM unzip -o -qq %PHP_ARCHIVE_FILENAME% - -REM Take the last one -FOR /D %%A IN (php-%BRANCH%-src-*) DO ( - SET DIRNAME=%%A -) -ECHO Downloaded: %DIRNAME% - -:DONE -GOTO EXIT - -:USAGE -echo Usage %~n0 ^ (5.2 5.3 or 6.0) - -:EXIT -SET A= -SET N= -SET BRANCH= -SET PHP_ARCHIVE_FILENAME= -SET DIRNAME= -SET cnt= \ No newline at end of file diff --git a/bin/snapshot_trunk_all.bat b/bin/snapshot_trunk_all.bat deleted file mode 100644 index afc8219..0000000 --- a/bin/snapshot_trunk_all.bat +++ /dev/null @@ -1,8 +0,0 @@ -@ECHO OFF - -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\phptrunkvc9x86.ini -SET PATH=%OLDPATH% -SET OLDPATH=%PATH% -CALL d:\php-sdk\rmtools\bin\snap.bat d:\php-sdk\rmtools\config\phptrunkntsvc9x86.ini -SET PATH=%OLDPATH% diff --git a/bin/sqlite3.exe b/bin/sqlite3.exe new file mode 100755 index 0000000..b5d5ae3 Binary files /dev/null and b/bin/sqlite3.exe differ diff --git a/bin/task.exe b/bin/task.exe new file mode 100755 index 0000000..7e9cdf1 Binary files /dev/null and b/bin/task.exe differ diff --git a/bin/test.bat b/bin/test.bat deleted file mode 100644 index 7bb3a87..0000000 --- a/bin/test.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off -set MY=Release\php-5.3.0alpha3-dev-nts-Win32-VC9-x86.zip - -FOR %%A IN (%MY%) DO echo %%~dpA -set USE_INSTALLER=Yes -IF %USE_INSTALLER%==Yes ( - FOR %%A IN (%MY%) DO ( - echo snapshot_installer.bat %PHP_VERSION%.0 %NTS% %VC_VERS% %ARCH% %%~fA - REM CALL snapshot_installer.bat %PHP_VERSION%.0 %NTS% %VC_VERS% %ARCH% %%~dpA - ) -) \ No newline at end of file diff --git a/bin/testsnap53all.bat b/bin/testsnap53all.bat deleted file mode 100644 index d3053ac..0000000 --- a/bin/testsnap53all.bat +++ /dev/null @@ -1,27 +0,0 @@ -@ECHO OFF -REM Run 5.3 Snapshots builds with VC9/VC6 - -SET PHP_SDK_SCRIPT_PATH=%~dp0 -CALL %PHP_SDK_SCRIPT_PATH%\phpsdk_setvars.bat - -%~d0 - -CD %PHP_SDK_PATH%\php_5_3\sources - - -REM unzip -o -qq %PHP_SDK_PATH%\php_5_3\sources\php-5.3-src-latest.zip - -FOR /D %%A IN (php-?.?-src-*) DO ( - SET DIRNAME=%%A -) -ECHO Using %DIRNAME% ... - -FOR /D %%A IN (php-?.?-src-*) DO ( - SET DIRNAME=%%A -) -FOR /D %%A IN (php-?.?-src-*) DO ( - SET DIRNAME=%%A -) - -FOR /F "tokens=4 delims=-" %%A IN ("%DIRNAME%") DO ECHO %%A -REM snapshot_src_download.bat 5.3 \ No newline at end of file diff --git a/bin/unzip.exe b/bin/unzip.exe deleted file mode 100644 index b103877..0000000 Binary files a/bin/unzip.exe and /dev/null differ diff --git a/bin/unzip32.dll b/bin/unzip32.dll deleted file mode 100644 index 4a7d523..0000000 Binary files a/bin/unzip32.dll and /dev/null differ diff --git a/bin/unzipsfx.exe b/bin/unzipsfx.exe deleted file mode 100644 index edc2a80..0000000 Binary files a/bin/unzipsfx.exe and /dev/null differ diff --git a/bin/uzexampl.exe b/bin/uzexampl.exe deleted file mode 100644 index a3f1e3c..0000000 Binary files a/bin/uzexampl.exe and /dev/null differ diff --git a/bin/vswhere.exe b/bin/vswhere.exe new file mode 100755 index 0000000..2603826 Binary files /dev/null and b/bin/vswhere.exe differ diff --git a/bin/wget.exe b/bin/wget.exe deleted file mode 100644 index ad974bf..0000000 Binary files a/bin/wget.exe and /dev/null differ diff --git a/bin/yacc b/bin/yacc deleted file mode 100644 index 0d8549e..0000000 --- a/bin/yacc +++ /dev/null @@ -1,2 +0,0 @@ -#! /bin/sh -exec 'c:/progra~1/bison/bin/bison' -y "$@" diff --git a/bin/zip.exe b/bin/zip.exe deleted file mode 100644 index 55be81d..0000000 Binary files a/bin/zip.exe and /dev/null differ diff --git a/bin/zipinfo.exe b/bin/zipinfo.exe deleted file mode 100644 index 0be6e5e..0000000 Binary files a/bin/zipinfo.exe and /dev/null differ diff --git a/doc/phpsdk-local.bat.example b/doc/phpsdk-local.bat.example new file mode 100644 index 0000000..22d2c87 --- /dev/null +++ b/doc/phpsdk-local.bat.example @@ -0,0 +1,20 @@ +@echo off + +set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=test password=test +set PDO_PGSQL_TEST_DSN=pgsql:host=127.0.0.1 port=5432 dbname=test user=test password=test + +set PHP_SDK_FIREBIRD_PATH= +if "%PHP_SDK_ARCH%"=="x64" ( + set PHP_SDK_FIREBIRD_PATH=E:\local_programs\Firebird-2.5.5.26952-0_x64\bin; + set PDO_FIREBIRD_TEST_DSN=firebird:dbname=127.0.0.1:E:\local_programs\Firebird-2.5.5.26952-0_x64\examples\empbuild\EMPLOYEE.FDB + set PDO_FIREBIRD_TEST_USER=SYSDBA + set PDO_FIREBIRD_TEST_PASS=masterkey +) +set PATH=%PHP_SDK_FIREBIRD_PATH%%PATH% + +set ODBC_TEST_USER=php_test2 +set ODBC_TEST_PASS=php_test2 +set ODBC_TEST_DSN=Driver={SQL Server};Server={W530-PHP-DEV\TEST2014};Database={php_test2};uid=%ODBC_TEST_USER%;pwd=%ODBC_TEST_PASS% + +set PDOTEST_DSN=odbc:%ODBC_TEST_DSN% + diff --git a/doc/phpsdk_pgo_prep_elevated.bat.example b/doc/phpsdk_pgo_prep_elevated.bat.example new file mode 100644 index 0000000..6316cba --- /dev/null +++ b/doc/phpsdk_pgo_prep_elevated.bat.example @@ -0,0 +1,47 @@ + + +@echo off +rem These are default ports for the servers used for the training. If these +rem ports are changed in the config templates, the commands have to be +rem adjusted as well. New servers have to be added here as well. Run this +rem file on the elevated shell before starting the PGO environment setup +rem using the relevant port numbers, especially for unattended PGO builds. +rem We add opens inbound ports from the default PGO config templates and +rem and the one increment by 1, just co cover a simple case the port number +rem was incremented by the auto configuration. +rem +rem Alternatively, the firewall can be disabled on the build host. +rem The commands to disable\enable firewall are +rem netsh advfirewall set allprofiles state on +rem netsh advfirewall set allprofiles state off +@echo on + +rem NGINX +netsh advfirewall firewall add rule name="NGINX for PGO" dir=in action=allow program="C:\php-snap-build\php-sdk\pgo\work\server\nginx\nginx.exe" profile=private +for /l %%p in (8081, 1, 8091) do ( + netsh advfirewall firewall add rule name="Open Port %%p for PHP PGO" dir=in action=allow protocol=TCP localport=%%p profile=private + netsh advfirewall firewall add rule name="Open Port %%p for PHP PGO" dir=in action=allow protocol=UDP localport=%%p profile=private +) +netsh advfirewall firewall add rule name="Open Port 80 for PHP PGO" dir=in action=allow protocol=TCP localport=80 profile=private +netsh advfirewall firewall add rule name="Open Port 80 for PHP PGO" dir=in action=allow protocol=UDP localport=80 profile=private + +rem MariaDB +netsh advfirewall firewall add rule name="MariaDB for PGO" dir=in action=allow program="c:\php-snap-build\php-sdk\pgo\work\server\mariadb\bin\mysqld.exe" profile=private +netsh advfirewall firewall add rule name="Open Port 3307 for PHP PGO" dir=in action=allow protocol=TCP localport=3307 profile=private +netsh advfirewall firewall add rule name="Open Port 3307 for PHP PGO" dir=in action=allow protocol=UDP localport=3307 profile=private +netsh advfirewall firewall add rule name="Open Port 3308 for PHP PGO" dir=in action=allow protocol=TCP localport=3308 profile=private +netsh advfirewall firewall add rule name="Open Port 3308 for PHP PGO" dir=in action=allow protocol=UDP localport=3308 profile=private + +rem Postgres +netsh advfirewall firewall add rule name="Open Port 5434 for PHP PGO" dir=in action=allow protocol=TCP localport=5434 profile=private +netsh advfirewall firewall add rule name="Open Port 5434 for PHP PGO" dir=in action=allow protocol=UDP localport=5434 profile=private +netsh advfirewall firewall add rule name="Open Port 5435 for PHP PGO" dir=in action=allow protocol=TCP localport=5435 profile=private +netsh advfirewall firewall add rule name="Open Port 5435 for PHP PGO" dir=in action=allow protocol=UDP localport=5435 profile=private + +rem PHP +netsh advfirewall firewall add rule name="Open Port 9001 for PHP PGO" dir=in action=allow protocol=TCP localport=9001 profile=private +netsh advfirewall firewall add rule name="Open Port 9001 for PHP PGO" dir=in action=allow protocol=UDP localport=9001 profile=private +netsh advfirewall firewall add rule name="Open Port 9002 for PHP PGO" dir=in action=allow protocol=TCP localport=9002 profile=private +netsh advfirewall firewall add rule name="Open Port 9002 for PHP PGO" dir=in action=allow protocol=UDP localport=9002 profile=private + + diff --git a/doc/task.c b/doc/task.c new file mode 100644 index 0000000..4406c8c --- /dev/null +++ b/doc/task.c @@ -0,0 +1,72 @@ +/** + * Run the passed command line hidden, suitable for a scheduled task. + * Author: Anatol Belski + * License: BSD 2-Clause + */ + +#include +#include +#include + +#define CMD_PRE "cmd.exe /c " +#define CMD_PRE_LEN (sizeof(CMD_PRE)-1) + +#ifdef DEBUG +int +main(int argc, char **argv) +#else +int +APIENTRY WinMain(HINSTANCE inst, HINSTANCE prev_inst, LPTSTR in_cmd, int show) +#endif +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD exit_code; + + char *cmd = NULL; + size_t cmd_len = 0, arg_len = 0; + char *arg = strchr(GetCommandLine(), ' '); + + if (!arg) { + return 3; + } +#ifdef DEBUG + printf("passed cmd: '%s'\n", arg); +#endif + + arg_len = strlen(arg); + cmd_len = CMD_PRE_LEN + arg_len + 1; + + cmd = malloc(cmd_len * sizeof(char)); + memmove(cmd, CMD_PRE, CMD_PRE_LEN); + memmove(cmd + CMD_PRE_LEN, arg, arg_len); + cmd[cmd_len-1] = '\0'; +#ifdef DEBUG + printf("constructed cmd: '%s'\n", cmd); +#endif + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + ZeroMemory( &pi, sizeof(pi) ); + + if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { + CloseHandle( pi.hThread ); + } else { + free(cmd); + printf( "Error: CreatePracess 0x%08lx \n", GetLastError() ); + return 3; + } + + WaitForSingleObject( pi.hProcess, INFINITE ); + + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle( pi.hProcess ); + + free(cmd); + + return exit_code; +} + diff --git a/doc/unattended-build-task.bat.example b/doc/unattended-build-task.bat.example new file mode 100644 index 0000000..5372784 --- /dev/null +++ b/doc/unattended-build-task.bat.example @@ -0,0 +1,26 @@ + +rem Task batch example. +rem Create a task, put an action with the following data: +rem Action: start a program +rem Program/script: C:\php-sdk\bin\task.exe +rem Add arguments: "C:\php-sdk\phpsdk-starter.bat -c vc15 -a x64 -t C:\php-sdk\unattended-build-task.bat" +rem Run the task + +set LOG_NAME=%PHP_SDK_VC%-%PHP_SDK_ARCH%-task.log + +pushd C:\php-sdk\php72\vc14\x64\php-src + +git pull --rebase > %LOG_NAME% 2>&1 + +call phpsdk_deps -u -s staging >> %LOG_NAME% 2>&1 + +call buildconf >> %LOG_NAME% 2>&1 +call configure --enable-snapshot-build --enable-debug-pack >> %LOG_NAME% 2>&1 + +nmake clean >> %LOG_NAME% 2>&1 +nmake >> %LOG_NAME% 2>&1 + +popd + +exit + diff --git a/lib/php/autoload.php b/lib/php/autoload.php new file mode 100644 index 0000000..7fc3ec9 --- /dev/null +++ b/lib/php/autoload.php @@ -0,0 +1,26 @@ +stability = $stability; + $this->arch = $arch; + $this->host = $host; + $this->port = $port; + $this->scheme = $scheme; + $this->series = $series; + }/*}}}*/ + + public function getSeries() : Series + {/*{{{*/ + return $this->series; + }/*}}}*/ + + public function setSeries(Series $series) : void + {/*{{{*/ + $this->series = $series; + }/*}}}*/ + + /* TODO more robust implementation. */ + /* TODO implement indicator. */ + public function getByUri(string $uri, int $retries = 3) : string + {/*{{{*/ + $url = "{$this->scheme}://{$this->host}:{$this->port}$uri"; + $ret = false; + +retry: + try { + $ret = $this->download($url); + } catch (Exception $e) { + if ($retries > 0) { + sleep(1); + $retries--; + goto retry; + } + } + + return $ret; + }/*}}}*/ + + /*protected function fetch($uri) : string + { + $fp = @fsockopen($this->host, $this->port); + if (!$fp) { + throw new Exception("Couldn't connect to windows.php.net"); + } + + $hdrs = "GET $uri HTTP/1.0\r\nHost: {$this->host}\r\nConnection: close\r\n\r\n"; + $r = fwrite($fp, $hdrs); + if (false === $r || $r != strlen($hdrs)) { + fclose($fp); + throw new Exception("Request to windows.php.net failed"); + } + + $r = ''; + while (!feof($fp)) { + $r .= fread($fp, 32768); + } + + if (preg_match(',HTTP/\d\.\d 200 .*,', $r) < 1) { + var_dump($r); + fclose($fp); + throw new Exception("Invalid response from {$this->host}:{$this->port} while fetching '$uri'"); + } + + fclose($fp); + + $ret = substr($r, strpos($r, "\r\n")); + + return trim($ret); + }*/ + +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Build/Dependency/Manager.php b/lib/php/libsdk/SDK/Build/Dependency/Manager.php new file mode 100644 index 0000000..1db68cd --- /dev/null +++ b/lib/php/libsdk/SDK/Build/Dependency/Manager.php @@ -0,0 +1,174 @@ +stability = $stability; + $this->arch = $arch; + $this->path = $path; + $this->cache = new Cache($path); + + $host = Config::getDepsHost(); + $port = Config::getDepsPort(); + $scheme = Config::getDepsUriScheme(); + $fetcher = new Fetcher($host, $port, $scheme, $this->arch, $this->stability); + $series = new Series($this->stability, $this->arch, $this->cache, NULL); + $fetcher->setSeries($series); + $series->setFetcher($fetcher); + + $this->fetcher = $fetcher; + $this->series = $series; + }/*}}}*/ + + protected function getTmpSeriesPath() : string + {/*{{{*/ + return Config::getTmpDir() . DIRECTORY_SEPARATOR . $this->series->getname(); + }/*}}}*/ + + public function updatesAvailable() : bool + {/*{{{*/ + if (NULL !== $this->updatesFlag) { + return $this->updatesFlag; + } + + $this->updatesFlag = $this->series->updatesAvailable() || !file_exists(Config::getDepsLocalPath()); + return $this->updatesFlag; + }/*}}}*/ + + /* FIXME implement rollback */ + public function performUpdate(string &$msg = NULL, bool $force = false, bool $backup = true) : void + {/*{{{*/ + if (!$force) { + if (!$this->updatesAvailable()) { + $msg .= "No updates are available"; + return; + } + + $lock = new Lock(Config::getDepsLocalPath()); + if (!$lock->locked()) { + $msg .= "Dependencies was updated by another process."; + echo "Another process is updating same dependency path. I'm just going to wait for it to finish and then exit.", PHP_EOL; + $lock->exclusive(true); + unset($lock); + return; + } + } + + $series_data = $this->series->getData(); + + $tmp_dir = $this->md("", true); + $tmp_dir_packs = $this->md($tmp_dir . DIRECTORY_SEPARATOR . "packs"); + $tmp_dir_deps = $this->md($tmp_dir . DIRECTORY_SEPARATOR . "deps"); + + foreach ($series_data as $item) { + echo "Processing package $item", PHP_EOL; + $pkg = new Package($item, $this->series, $this->fetcher); + + $pkg->retrieve($tmp_dir_packs); + $pkg->unpack($tmp_dir_deps); + $pkg->cleanup(); + + unset($pkg); + } + + /* Clear, it is an extra handling. So far it's the only case, doing it this way. And, we have + no package definitions ATM to handle it otherwise. */ + $extra = $tmp_dir_deps . DIRECTORY_SEPARATOR . "openssl.cnf"; + if (file_exists($extra)) { + $tdir = $tmp_dir_deps . DIRECTORY_SEPARATOR . "template" . DIRECTORY_SEPARATOR . "ssl"; + + $this->md($tdir); + $this->mv($extra, $tdir . DIRECTORY_SEPARATOR . "openssl.cnf"); + } + + if (file_exists($this->path)) { + if ($backup) { + $suffix = date("YmdHi"); + $new_path = "{$this->path}.$suffix"; + + /* This is fine, it's gonna be on the same drive. */ + if (!$this->mv($this->path, $new_path)) { + if (!$force) { + unset($lock); + } + throw new Exception("Unable to rename '{$this->path}' to '$new_path'"); + } + } else { + if (!$this->rm($this->path)) { + if (!$force) { + unset($lock); + } + throw new Exception("Unable to remove the current dependency dir at '{$this->path}'"); + } + } + } else { + $up = dirname($this->path); + if (!file_exists($up)) { + if (!$this->md($up)) { + if (!$force) { + unset($lock); + } + throw new Exception("Unable to create '{$this->path}'"); + } + } + } + + $this->mv($tmp_dir_deps, $this->path); + + $this->rm($tmp_dir_packs); + $this->rm($tmp_dir); + + $this->series->cache(); + + /* save new series file, move the updated deps and backup the old ones, cleanup.*/ + $msg .= "Updates performed successfully. " . PHP_EOL; + if ($backup) { + if (isset($new_path)) { + $msg .= "Old dependencies backed up into '$new_path'."; + } + } else { + $msg .= "No backup was created."; + } + + if (!$force) { + unset($lock); + } + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Build/Dependency/Package.php b/lib/php/libsdk/SDK/Build/Dependency/Package.php new file mode 100644 index 0000000..3e5703c --- /dev/null +++ b/lib/php/libsdk/SDK/Build/Dependency/Package.php @@ -0,0 +1,72 @@ +name = $name; + $this->series = $series; + $this->fetcher = $fetcher; + }/*}}}*/ + + public function getUri() : string + {/*{{{*/ + $base = Config::getDepsBaseUri(); + $branch_data = Config::getCurrentBranchData(); + $arch = $this->series->getArch(); + + return "$base/{$branch_data['crt']}/$arch/{$this->name}"; + }/*}}}*/ + + public function retrieve(string $path) : void + {/*{{{*/ + $this->filepath = $path . DIRECTORY_SEPARATOR . $this->name; + + $cont = $this->fetcher->getByUri($this->getUri()); + + $fd = fopen($this->filepath, "wb"); + fwrite($fd, $cont); + fclose($fd); + }/*}}}*/ + + public function unpack(string $path) : void + {/*{{{*/ + if (!$this->filepath || !file_exists($this->filepath)) { + throw new Exception("Invalid filepath '{$this->filepath}'"); + } + + $this->unzip($this->filepath, $path); + }/*}}}*/ + + public function cleanup() : void + {/*{{{*/ + unlink($this->filepath); + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Build/Dependency/Series.php b/lib/php/libsdk/SDK/Build/Dependency/Series.php new file mode 100644 index 0000000..958f195 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/Dependency/Series.php @@ -0,0 +1,121 @@ +fetcher = $fetcher; + $this->stability = $stability; + $this->arch = $arch; + $this->cache = $cache; + }/*}}}*/ + + public function getFetcher() : Fetcher + {/*{{{*/ + return $this->fetcher; + }/*}}}*/ + + public function setFetcher(Fetcher $fetcher) : void + {/*{{{*/ + $this->fetcher = $fetcher; + }/*}}}*/ + + public function getArch() : string + {/*{{{*/ + return $this->arch; + }/*}}}*/ + + public function setArch(string $arch) : void + {/*{{{*/ + $this->arch = $arch; + }/*}}}*/ + + public function getName() : string + {/*{{{*/ + $branch_data = Config::getCurrentBranchData(); + + $file = "packages-" . Config::getCurrentBranchName() . "-{$branch_data['crt']}-{$this->arch}-{$this->stability}.txt"; + + return $file; + }/*}}}*/ + + protected function getUri() : string + {/*{{{*/ + $base = Config::getDepsBaseUri(); + $file = $this->getName(); + + return "$base/series/$file"; + }/*}}}*/ + + /** @return array|string */ + public function getData(bool $raw = false, bool $cache = true) + {/*{{{*/ + if ($cache && $this->rawData) { + $ret = $this->rawData; + } else { + if (!$this->fetcher) { + throw new Exception("Fetcher is not set"); + } + + $ret = $this->fetcher->getByUri($this->getUri()); + } + + if (!$raw) { + $ret = explode(" ", preg_replace(",[\r\n ]+,", " ", trim($ret))); + } + + return $ret; + }/*}}}*/ + + public function getSavePath() : string + {/*{{{*/ + return Config::getCacheDir() . DIRECTORY_SEPARATOR . $this->getname(); + }/*}}}*/ + + public function updatesAvailable() : bool + {/*{{{*/ + $series_data = $this->getData(true); + $series_file = $this->getSavePath(); + + return $this->cache->cachedContentDiffers($series_file, $series_data); + }/*}}}*/ + + public function cache(string $path = NULL) : void + {/*{{{*/ + if (!$path) { + $path = $this->getSavePath(); + } + + $this->cache->cacheContent($path, $this->getData(true)); + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Build/PGO/Abstracts/PHP.php b/lib/php/libsdk/SDK/Build/PGO/Abstracts/PHP.php new file mode 100644 index 0000000..cfeb007 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Abstracts/PHP.php @@ -0,0 +1,251 @@ +php_root = $this->getRootDir(); + if ($this->isDist()) { + $this->php_ext_root = $this->php_root . DIRECTORY_SEPARATOR . "ext"; + if (!file_exists($this->php_ext_root)) { + throw new Exception("Extension dir '{$this->php_ext_root}' doesn't exist."); + } + } else { + $this->php_ext_root = $this->php_root; + } + if ("cache" == $this->scenario) { + $this->opcache_file_cache = SDKConfig::getTmpDir() . DIRECTORY_SEPARATOR . $this->id; + } + } + + abstract public function getExeFilename() : string; + + /* TODO Might be improved. */ + public function isDist() : bool + { + return !file_exists("Makefile") && file_exists("php.exe"); + } + + /** @return array */ + protected function createEnv() : array + { + $env = getenv(); + + if (!$this->isDist()) { + $deps_root = SDKConfig::getDepsLocalPath(); + foreach ($env as $k => $v) { + if (strtoupper($k) == "PATH") { + $env[$k] = $deps_root . DIRECTORY_SEPARATOR . "bin;" . $env[$k]; + break; + } + } + } + + $drive = getenv("HOMEDRIVE"); + $path = getenv("HOMEPATH"); + if (!$drive || !$path) { + $p = SDKConfig::getTmpDir(); + $drive = substr($p, 0, 2); + $path = substr($p, 2); + putenv("HOMEDRIVE=$drive"); + putenv("HOMEPATH=$path"); + } + + return $env; + } + + public function getExtRootDir() : string + { + return $this->php_ext_root; + } + + public function getRootDir() : string + { + if ($this->php_root) { + return $this->php_root; + } + + /* XXX adapt for any possible PHP variants. */ + $root = getenv("PHP_SDK_PGO_TEST_PHP_ROOT"); + if (!$root) { + if (!$this->isDist()) { + $s = file_get_contents("Makefile"); + if (preg_match(",BUILD_DIR=(.+),", $s, $m) > 0) { + $root = trim($m[1]); + } + } + } + + if (!file_exists($root)) { + throw new Exception("'$root' doesn't exist."); + } + + return $root; + } + + + public function getVersion(bool $short = false) : string + { + $ret = NULL; + $cli = new CLI($this->conf); + + $out = shell_exec($cli->getExeFilename() . " -n -v"); + + if ($short) { + if (preg_match(",PHP (\d+\.\d+),", $out, $m)) { + $ret = $m[1]; + } + } else { + if (preg_match(",PHP ([^ ]+),", $out, $m)) { + $ret = $m[1]; + } + } + + if (NULL === $ret) { + throw new Exception("Failed to determine the test PHP version."); + } + + return $ret; + } + + public function isThreadSafe() : bool + { + $cli = new CLI($this->conf); + + $out = shell_exec($cli->getExeFilename() . " -n -v"); + + if (preg_match(",NTS,", $out, $m) > 0) { + return false; + } + + return true; + } + + /* Need to cleanup it somewhere. */ + /** @return string */ + public function getIniFilename() + { + $ret = tempnam(sys_get_temp_dir(), "ini"); + + $tpl_vars = array( + $this->conf->buildTplVarName("php", "extension_dir") => $this->php_ext_root, + $this->conf->buildTplVarName("php", "error_log") => $this->getRootDir() . DIRECTORY_SEPARATOR . "pgo_run_error.log", + ); + + $k = SDKConfig::getCurrentArchName(); + $scenario_vars = (array)$this->conf->getSectionItem("php", "scenario", $this->scenario, "ini", $k); + if ($scenario_vars) { + foreach ($scenario_vars as $k => $v) { + //$tpl_vars[$this->conf->buildTplVarName("php", "scenario", $this->scenario, str_replace(array(".", "-"), "_", $k))] = $v; + $tpl_vars[$this->conf->buildTplVarName("php", str_replace(array(".", "-"), "_", $k))] = $v; + } + } + + /* Special handling, otherwise it'll need functionality to extrapolate ini values. */ + if ("cache" == $this->scenario) { + $tpl_vars[$this->conf->buildTplVarName("php", "opcache", "file_cache")] = $this->opcache_file_cache; + } + + $this->conf->processTplFile( + $this->getIniTplFilename(), + $ret, + $tpl_vars + ); + + return $ret; + } + + /** @return string */ + protected function getIniTplFilename() + { + $tpl_path = $this->conf->getTplDir("php"); + $version = $this->getVersion(true); + $ts = $this->isThreadSafe() ? "ts" : "nts"; + + $construct = $tpl_path . DIRECTORY_SEPARATOR . "php-$version-pgo-$ts" . ("default" == $this->scenario ? "" : "-{$this->scenario}") . ".ini"; + + if (!file_exists($construct)) { + throw new Exception("Couldn't locate PHP config under '$construct'."); + } + + return $construct; + } + + /** @param array $extra_env */ + public function exec(string $php_cmd, string $args = NULL, array $extra_env = array()) : int + { + $env = $this->createEnv(); + $exe = $this->getExeFilename(); + $ini = $this->getIniFilename(); + + $cert_path = getenv("PHP_SDK_ROOT_PATH") . "\\msys2\\usr\\ssl\\cert.pem"; + $ini .= " -d curl.cainfo=$cert_path"; + + $spent_key = array(); + foreach ($env as $k0 => &$v0) { + foreach ($extra_env as $k1 => $v1) { + if (strtoupper($k0) == strtoupper($k1)) { + /* XXX some more things could require extra handling. */ + if (strtoupper($k0) == "PATH") { + $v0 = "$v1;$v0"; + } else { + $v0 = $v1; + } + $spent_key[] = $k1; + break; + } + } + } + + foreach ($extra_env as $k => $v) { + if (in_array($k, $spent_key)) { + continue; + } + $env[$k] = $v; + } + + $cmd = "$exe -n -c $ini " . ($args ? "$args " : "") . $php_cmd; + + $desc = array( + 0 => array("file", "php://stdin", "r"), + 1 => array("file", "php://stdout", "w"), + 2 => array("file", "php://stderr", "w") + ); + $p = proc_open($cmd, $desc, $pipes, $this->getRootDir(), $env); + + return proc_close($p); + } + + public function getIdString(): string + { + return $this->getVersion() . "-" + . SDKConfig::getCurrentCrtName() . "-" + . ($this->isThreadSafe() ? "ts" : "nts") . "-" + . SDKConfig::getCurrentArchName() + . "-" . substr(md5(uniqid()), 0, 8); + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Abstracts/Server.php b/lib/php/libsdk/SDK/Build/PGO/Abstracts/Server.php new file mode 100644 index 0000000..bf4c915 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Abstracts/Server.php @@ -0,0 +1,25 @@ +name; + } + + public function getPhp() : Interfaces\PHP + { + return $this->php; + } + +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Abstracts/TrainingCase.php b/lib/php/libsdk/SDK/Build/PGO/Abstracts/TrainingCase.php new file mode 100644 index 0000000..20294b0 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Abstracts/TrainingCase.php @@ -0,0 +1,159 @@ + */ + protected $stat = array(); + + /** @var \SDK\Build\PGO\Config */ + protected $conf; + + /** @var mixed */ + protected $php; + + abstract public function getName() : string; + + public function getType() : string + { + $type = $this->conf->getSectionItem($this->getName(), "type"); + + if (!$type) { + $type = "web"; + } + + return $type; + } + + public function run() : void + { + $training = new Tool\Training($this->conf, $this); + $pgo = new Tool\PGO($this->conf, $this->php); + + echo "Running " . $this->getName() . " training.\n"; + + $max_runs = $this->max_runs ?? 1; + $max_runs = (int)$max_runs > 0 ? $max_runs : 1; + $training->run($max_runs, $stat); + + if ($this->getType() == "web") { + echo "HTTP responses:\n"; + foreach ($stat["http_code"] as $code => $num) { + printf(" %d received %d times\n", $code, $num); + } + if (count($stat["not_ok"]) > 0) { + foreach($stat["not_ok"] as $st) { + echo "Code: $st[http_code], URL: $st[url]", ($st["redirect_url"] ? ", Redirected to: $st[redirect_url]" : ""), "\n"; + } + printf("\033[31m WARNING: Not all HTTP responses have indicated success, the PGO data might be unsuitable!\033[0m\n"); + } + } + + echo $this->getName() . " training complete.\n"; + + echo "Dumping PGO data for " . $this->getName() . ".\n"; + $pgo->dump(); + echo "Finished dumping training data for " . $this->getName() . ".\n"; + } + + public function getHttpPort() : string + { + $port = $this->conf->getSectionItem($this->getName(), "http_port"); + if (!$port) { + $port = $this->conf->getNextPort(); + $this->conf->setSectionItem($this->getName(), "http_port", $port); + } + + return $port; + } + + public function getHttpHost() : string + { + $host = $this->conf->getSectionItem($this->getName(), "http_host"); + if (!$host) { + $srv = $this->conf->getSrv( + $this->conf->getSectionItem($this->getName(), "srv_http") + ); + if ($srv) { + $host = $this->conf->getSectionItem($srv->getName(), "host"); + $this->conf->setSectionItem($this->getName(), "http_host", $host); + } + } + + return $host; + } + + protected function getDbConf(string $item) : string + { + $val = $this->conf->getSectionItem($this->getName(), "db_$item"); + if (!$val) { + $srv = $this->conf->getSrv( + $this->conf->getSectionItem($this->getName(), "srv_db") + ); + if ($srv) { + $val = $this->conf->getSectionItem($srv->getName(), $item); + $this->conf->setSectionItem($this->getName(), "db_$item", $val); + } + } + + return $val; + } + + public function getDbPass() : string + { + return $this->getDbConf("pass"); + } + + public function getDbUser() : string + { + return $this->getDbConf("user"); + } + + public function getDbHost() : string + { + return $this->getDbConf("host"); + } + + public function getDbPort() : string + { + return $this->getDbConf("port"); + } + + public function httpStatusOk(int $status) : bool + { + $ok = array(); + + $ok = array_merge($ok, range(200, 206)); + $ok = array_merge($ok, range(300, 307)); + + return in_array($status, $ok); + } + + public function probeUrl(string $url) : bool + { + $ret = false; + $c = curl_init($url); + + curl_setopt($c, CURLOPT_RETURNTRANSFER, true); + curl_exec($c); + + if (!curl_errno($c)) { + $st = curl_getinfo($c, CURLINFO_HTTP_CODE); + $ret = $this->httpStatusOk((int)$st); + } + + curl_close($c); + + return $ret; + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Config.php b/lib/php/libsdk/SDK/Build/PGO/Config.php new file mode 100644 index 0000000..c21e8da --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Config.php @@ -0,0 +1,397 @@ + */ + protected $sections = array(); + + /** @var string */ + protected $scenario = "default"; + + /** @var array */ + protected $tpl_vars = array(); + + /** @var array */ + protected $srv = array(); + + public function __construct(int $mode = self::MODE_RUN) + { + if (self::MODE_CHECK_INIT == $mode) { + // XXX The check is simple right now, so this is sufficient. + return; + } + + if (!$this->isInitialized()) { + $this->initWorkDir(); + } + + if (self::MODE_REINIT == $mode) { + $fn = $this->getWorkSectionsFilename(); + if (file_exists($fn)) { + unlink($fn); + } + $mode = self::MODE_INIT; + } + + $this->mode = $mode; + + + if (self::MODE_INIT == $mode) { + foreach (array("nginx", "mariadb", "postgresql", "php") as $i) { + $this->importSectionFromDir($i, $this->getTplDir() . DIRECTORY_SEPARATOR . $i); + } + } else if (self::MODE_RUN == $mode) { + $fn = $this->getWorkSectionsFilename(); + if (!file_exists($fn)) { + throw new Exception("Required config doesn't exist under '$fn'."); + } + $s = file_get_contents($fn); + $this->sections = json_decode($s, true); + foreach($this->sections as $k => $v) { + $this->importTplVars($k, $v); + } + + } else { + throw new Exception("Unknown config mode '$mode'."); + } + } + + protected function initWorkDir() : void + { + if (!mkdir($this->getWorkDir())) { + throw new Exception("Failed to create " . $this->getWorkDir()); + } + } + + /** @return bool */ + public function isInitialized() + { + /* XXX Could be some better check. */ + return is_dir($this->getWorkDir()); + } + + + public function getToolsDir() : string + { + $base = $this->getWorkDir(); + + return $base . DIRECTORY_SEPARATOR . "tools"; + } + + public function getWorkDir() : string + { + $base = getenv("PHP_SDK_ROOT_PATH"); + + return $base . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "work"; + } + + public function getPkgCacheDir() : string + { + $base = $this->getWorkDir(); + + return $base . DIRECTORY_SEPARATOR . "package_cache"; + } + + public function getJobDir(string $name = NULL) : string + { + $ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "job"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + public function getSrvDir(string $name = NULL) : string + { + $ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "server"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + public function getHtdocs(string $name = NULL) : string + { + $ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "htdocs"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + public function getTplDir(string $name = NULL) : string + { + $ret = getenv("PHP_SDK_ROOT_PATH") . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "tpl"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + public function getCaseWorkDir(string $name = NULL) : string + { + $ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "htdocs"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + public function getCasesTplDir(string $name = NULL) : string + { + $ret = getenv("PHP_SDK_ROOT_PATH") . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "cases"; + + if ($name) { + $ret .= DIRECTORY_SEPARATOR . $name; + } + + return $ret; + } + + /** @param string ...$args */ + public function sectionItemExists(...$args) : bool + { + $i = 0; + $k = strtolower($args[$i]); + $it = $this->sections; + + while (array_key_exists($k, $it)) { + $it = $it[$k]; + + if (++$i >= count($args)) break; + + $k = strtolower($args[$i]); + } + + return $i == count($args); + } + + /** + * @param string ...$args + * @return mixed + */ + public function getSectionItem(...$args) + { + $i = 0; + $k = strtolower($args[$i]); + $it = $this->sections; + + while (array_key_exists($k, $it)) { + $it = $it[$k]; + + if (++$i >= count($args)) break; + + $k = strtolower($args[$i]); + } + + if ($i != count($args)) { + return NULL; + } + + return $it; + } + + /** @param string|int ...$args */ + public function setSectionItem(...$args) : void + { + $val = array_pop($args); + + $i = 0; + $k = strtolower($args[$i]); + $it = &$this->sections; + + while (true) { + $it = &$it[$k]; + if (++$i >= count($args)) break; + $k = strtolower($args[$i]); + } + + $it = $val; + + $this->syncTplVars(); + $this->dump(); + } + + public function importSectionFromDir(string $name, string $dir) : void + { + $fn = $dir . DIRECTORY_SEPARATOR . "phpsdk_pgo.json"; + if (!file_exists($fn)) { + throw new Exception("Couldn't import section, file '$fn' doesn't exist."); + } + + $s = file_get_contents($fn); + $this->setSectionItem($name, json_decode($s, true)); + } + + protected function syncTplVars() : void + { + $this->tpl_vars = array(); + foreach ($this->sections as $k => $v) { + $this->importTplVars($k, $v); + } + } + + /** @param string ...$args */ + public function buildTplVarName(...$args) : string + { + $tpl_k = array("PHP_SDK_PGO"); + + foreach ($args as $a) { + $tpl_k[] = strtoupper($a); + } + + return implode("_", $tpl_k); + } + + /** @param array $section */ + protected function importTplVars(string $section_name, array $section) : void + { + foreach($section as $k0 => $v0) { + + if (is_array($v0)) { + if (substr($k0, -4) == ":env") { + /* Don't put env vars as tpl vars for now. */ + continue; + } + $this->importTplVars($section_name . "_" . $k0, $v0); + } else { + $tpl_k = $this->buildTplVarName($section_name, $k0); + $this->tpl_vars[$tpl_k] = $v0; + } + } + } + + /** @param array $additional_vars */ + public function processTpl(string $s, array $additional_vars = array()) : string + { + $vars = array_merge($this->tpl_vars, $additional_vars); + + $s = str_replace(array_keys($vars), array_values($vars), $s); + + return $s; + } + + /** @param array $additional_vars */ + public function processTplFile(string $tpl_fn, string $dst_fn, array $additional_vars = array()) : void + { + if (!file_exists($tpl_fn)) { + throw new Exception("Template file '$tpl_fn' doesn't exist."); + } + + $s = file_get_contents($tpl_fn); + if (false === $s) { + throw new Exception("Couldn't read '$tpl_fn'."); + } + + $s = $this->processTpl($s, $additional_vars); + + if (false === file_put_contents($dst_fn, $s)) { + throw new Exception("Failed to write '$dst_fn'."); + } + } + + /** @return string */ + public function getWorkSectionsFilename() + { + return $this->getWorkDir() . DIRECTORY_SEPARATOR . "phpsdk_pgo.json"; + } + + public function dump(string $fn = NULL) : void + { + $fn = $fn ? $fn : $this->getWorkSectionsFilename(); + + $s = json_encode($this->sections, JSON_PRETTY_PRINT); + + $ret = file_put_contents($fn, $s); + if (false === $ret || strlen($s) !== $ret) { + throw new Exception("Errors with writing to '$fn'."); + } + } + + public function setScenario(string $scenario) : void + { + if (!in_array($scenario, array("default", "cache"), true)) { + throw new Exception("Unknown scenario '$scenario'."); + } + $this->scenario = $scenario; + } + + public function getScenario() : string + { + return $this->scenario; + } + + public function getNextPort() : int + { + return ++$this->last_port; + } + + public function setLastPort(int $port) : void + { + $this->last_port = $port; + } + + public function getSdkPhpCmd() : string + { + return getenv("PHP_SDK_PHP_CMD"); + } + + /** + * @param Interfaces\Server $item + * @return void + */ + public function addSrv($item) : void + { + $name = strtolower($item->getName()); + + if (isset($this->srv[$name])) { + throw new Exception("Server '$name' already exists."); + } + + /* XXX Additional checks could not harm. */ + $this->srv[$name] = $item; + } + + /** @return array|Interfaces\Server|null */ + public function getSrv(?string $name = NULL) + { + $ret = NULL; + + $name = strtolower($name); + + if (!$name) { + return NULL; + } else if ("all" == $name) { + return $this->srv; + } else if (isset($this->srv[$name])) { + return $this->srv[$name]; + } + + return $ret; + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Controller.php b/lib/php/libsdk/SDK/Build/PGO/Controller.php new file mode 100644 index 0000000..da21189 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Controller.php @@ -0,0 +1,291 @@ +|null */ + protected $cases; + + /** @param array|null $cases */ + public function __construct(string $cmd, ?string $scenario, ?array $cases) + { + $this->cmd = $cmd; + + if (NULL == $scenario) { + $scenario = "default"; + } + $this->scenario = $scenario; + $this->cases = $cases; + } + + /** @return mixed */ + protected function vitalizeSrv() + { + $all = $this->conf->getSrv("all"); + + if (empty($all)) { + $php_fcgi_tcp = new PHP\FCGI($this->conf, true); + $this->conf->addSrv(new NGINX($this->conf, $php_fcgi_tcp)); + + $this->conf->addSrv(new MariaDB($this->conf)); + /* Uncomment to enable PostgreSQL*/ + /* $this->conf->addSrv(new PostgreSQL($this->conf));*/ + + $all = $this->conf->getSrv("all"); + } + + return $all; + } + + /** + * @param string $cmd + * @return PGOConfig + */ + protected function setupConfig($cmd) + { + switch ($cmd) { + default: + throw new Exception("Unknown action '{$cmd}'."); + case "check_init": + $cnf = new PGOConfig(PGOConfig::MODE_CHECK_INIT); + break; + case "init": + $cnf = new PGOConfig(PGOConfig::MODE_INIT); + break; + case "train": + case "up": + case "down": + $cnf = new PGOConfig(PGOConfig::MODE_RUN); + } + $cnf->setScenario($this->scenario); + + return $cnf; + } + + /** + * @param bool $force + * @return void + */ + public function handle($force) + { + /*$mode = (int)("init" !== $this->cmd); + $mode = (PGOConfig::MODE_INIT == $mode && $force) ? PGOConfig::MODE_REINIT : $mode; + $this->conf = new PGOConfig("init" !== $this->cmd); + $this->conf->setScenario($this->scenario);*/ + $this->conf = $this->setupConfig($this->cmd); + + switch ($this->cmd) { + default: + throw new Exception("Unknown action '{$this->cmd}'."); + case "init": + $lk = new Lock("pgo_init"); + if (!$lk->locked()) { + echo "Another process runs initialization right now, waiting.", PHP_EOL; + $lk->exclusive(true); + echo "Another process finished running initialization, I quit as well.", PHP_EOL; + return; + } + $this->init($force); + break; + case "train": + $lk = new Lock("pgo_train"); + if (!$lk->locked()) { + echo "Another process runs training right now, I have to wait.", PHP_EOL; + $lk->exclusive(true); + echo "Another process finished training, I may continue.", PHP_EOL; + } + $this->train(); + break; + case "up": + $this->up(); + break; + + case "down": + $this->down($force); + break; + case "check_init": + // pass + break; + } + } + + protected function initWorkDirs() : void + { + $dirs = array( + $this->conf->getSrvDir(), + $this->conf->getToolsDir(), + $this->conf->getHtdocs(), + $this->conf->getJobDir(), + $this->conf->getPkgCacheDir(), + ); + + foreach ($dirs as $dir) { + if (!is_dir($dir)) { + if (!mkdir($dir)) { + throw new Exception("Failed to create '$dir'."); + } + } + } + } + + protected function prepareStandaloneTools(PackageWorkman $pw, bool $force = false) : void + { + $php = new PHP\CLI($this->conf); + + $composer = $this->conf->getToolsDir() . DIRECTORY_SEPARATOR . "composer.phar"; + if (!file_exists($composer) || $force) { + /* XXX this needs to go into the config, specifically for composer maybe even separate class. */ + $url = "https://getcomposer.org/installer"; + $tool = $this->conf->getToolsDir() . DIRECTORY_SEPARATOR . "composer-setup.php"; + $pw->fetch($url, $tool, $force); + $php->exec("$tool --install-dir=" . $this->conf->getToolsDir()); + unlink($tool); + } + } + + /** @return void */ + public function init(bool $force = false) + { + echo "\nInitializing PGO training environment.\n\n"; + + $this->initWorkDirs(); + + $pw = new PackageWorkman($this->conf); + + $this->prepareStandaloneTools($pw, $force); + + $srvs = $this->vitalizeSrv(); + foreach ($srvs as $srv) { + $srv->prepareInit($pw, $force); + } + + foreach (new TrainingCaseIterator($this->conf) as $handler) { + $handler->prepareInit($pw, $force); + } + + foreach ($srvs as $srv) { + $srv->init(); + echo "\n"; + } + + echo "\n"; + foreach (new TrainingCaseIterator($this->conf) as $handler) { + $handler->init(); + echo "\n"; + } + + echo "PGO training environment Initialization complete.\n"; + } + + /** @return bool */ + public function isInitialized() + { + return $this->conf->isinitialized(); + } + + /** @return void */ + public function train() + { + if (!$this->isInitialized()) { + throw new Exception("PGO training environment is not initialized."); + } + + echo "\nStarting PGO training using scenario '{$this->scenario}'.\n\n"; + $this->up(); + + /* Clean the PGO db files, only needed once. + Imply also, that any data created during init or + startup is wasted. It is done by dumpbing the data + from the current running processes and subsequently + removing the files. */ + $php = $this->conf->getSrv("nginx")->getPhp(); + $pgo = new PGO($this->conf, $php); + $pgo->waste(); + $pgo->clean(); + unset($pgo); + + $cases = $this->cases; + foreach (new TrainingCaseIterator($this->conf) as $handler) { + $name = $handler->getName(); + /* Just a white list handling for now. */ + if (is_array($cases)) { + if (!in_array($name, $cases)) { + continue; + } + $key = array_search($name, $cases); + unset($cases[$key]); + } + + echo "\n"; + $handler->run(); + } + if (is_array($cases) && !empty($cases)) { + echo "\n\033[31m WARNING: The cases " . implode(",", $cases) . " don't exist and was ignored!\033[0m\n\n"; + } + + /* All the PGC files are merged, simply clean them out. */ + $pgo = new PGO($this->conf, $php); + $pgo->clean(true, false); + unset($pgo); + + $this->down(); + echo "PGO training complete.\n"; + } + + /** @return void */ + public function up() + { + + if (!$this->isInitialized()) { + throw new Exception("PGO training environment is not initialized."); + } + echo "\nStarting up PGO environment.\n\n"; + + foreach ($this->vitalizeSrv() as $srv) { + $srv->up(); + echo "\n"; + } + + sleep(1); + + echo "The PGO environment is up.\n"; + } + + /** @return void */ + public function down(bool $force = false) + { + if (!$this->isInitialized()) { + throw new Exception("PGO training environment is not initialized."); + } + /* XXX check it was started of course. */ + echo "\nShutting down PGO environment.\n\n"; + + foreach ($this->vitalizeSrv() as $srv) { + $srv->down($force); + echo "\n"; + } + + sleep(1); + + echo "The PGO environment has been shut down.\n"; + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Interfaces/PHP.php b/lib/php/libsdk/SDK/Build/PGO/Interfaces/PHP.php new file mode 100644 index 0000000..71da2bc --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Interfaces/PHP.php @@ -0,0 +1,16 @@ + $tpl_vars + * @return void + */ + public function addServer(string $part_tpl_fn, array $tpl_vars = array()); +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Interfaces/TrainingCase.php b/lib/php/libsdk/SDK/Build/PGO/Interfaces/TrainingCase.php new file mode 100644 index 0000000..1137482 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Interfaces/TrainingCase.php @@ -0,0 +1,27 @@ +conf = $conf; + $this->scenario = $conf->getScenario(); + // Don't do that, it'll be a recursive dependency. + // Once we need to train CLI, we'll need to split + // a new class, this one is a utility class. + //$this->id = $this->getIdString(); + + $this->setupPaths(); + } + + public function prepareInit(PackageWorkman $pw, bool $force = false) : void + { + /* pass */ + } + + public function init() : void + { + /* pass */ + } + + public function up() : void + { + /* pass */ + } + + public function down(bool $force = false) : void + { + /* pass */ + } + + public function getExeFilename() : string + { + $exe = $this->getRootDir() . DIRECTORY_SEPARATOR . "php.exe"; + + if (!file_exists($exe)) { + throw new Exception("Path '$exe' doesn't exist."); + } + + return $exe; + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/PHP/FCGI.php b/lib/php/libsdk/SDK/Build/PGO/PHP/FCGI.php new file mode 100644 index 0000000..28c849e --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/PHP/FCGI.php @@ -0,0 +1,129 @@ +conf = $conf; + $this->is_tcp = $is_tcp; + $this->scenario = $conf->getScenario(); + $this->id = $this->getIdString(); + + $this->setupPaths(); + } + + public function getExeFilename() : string + { + $exe = $this->getRootDir() . DIRECTORY_SEPARATOR . "php-cgi.exe"; + + if (!file_exists($exe)) { + throw new Exception("Path '$exe' doesn't exist."); + } + + return $exe; + } + + protected function createEnv() : array + { + $env = parent::createEnv(); + + $fcgi_env = (array)$this->conf->getSectionItem("php", "fcgi:env"); + + foreach ($fcgi_env as $k => $v) { + $env[$k] = $v; + } + + return $env; + } + + public function prepareInit(PackageWorkman $pw, bool $force = false) : void + { + } + + public function init() : void + { +/* echo "Initializing PHP FCGI.\n"; +echo "PHP FCGI initialization done.\n";*/ + } + + public function up() : void + { + echo "Starting PHP FCGI.\n"; + + if ("cache" == $this->scenario) { + if (file_exists($this->opcache_file_cache)) { + $this->rm($this->opcache_file_cache); + } + if (!mkdir($this->opcache_file_cache)) { + throw new Exception("Failed to create '{$this->opcache_file_cache}'"); + } + } + + $exe = $this->getExeFilename(); + $ini = $this->getIniFilename(); + $host = $this->conf->getSectionItem("php", "fcgi", "host"); + $port = $this->conf->getSectionItem("php", "fcgi", "port"); + + $cmd = "start /b $exe -n -c $ini -b $host:$port 2>&1"; + + $desc = array( + 0 => array("file", "php://stdin", "r"), + 1 => array("file", "php://stdout", "w"), + 2 => array("file", "php://stderr", "w"), + ); + + $p = proc_open($cmd, $desc, $pipes, $this->getRootDir(), $this->createEnv()); + + /* Give some time, it might be slow on PGI enabled proc. */ + sleep(3); + + /*while(false !== ($s = fread($pipes[2], 1024))) { + echo "$s"; + }*/ + + $c = proc_close($p); + + if ($c) { + throw new Exception("PHP FCGI process exited with code '$c'."); + } + + /* XXX for Opcache, setup also file cache. */ + + echo "PHP FCGI started.\n"; + } + + public function down(bool $force = false) : void + { + echo "Stopping PHP FCGI.\n"; + + exec("taskkill /f /im php-cgi.exe >nul 2>&1"); + + /* XXX Add cleanup interface. */ + if ("cache" == $this->scenario) { + try { + $this->rm($this->opcache_file_cache); + } catch (\UnexpectedValueException $e) { + echo $e->getMessage(), "\n"; + } + } + + echo "PHP FCGI stopped.\n"; + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Server/MariaDB.php b/lib/php/libsdk/SDK/Build/PGO/Server/MariaDB.php new file mode 100644 index 0000000..c59aba0 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Server/MariaDB.php @@ -0,0 +1,149 @@ +conf = $conf; + $this->base = $conf->getSrvDir(strtolower($this->name)); + } + + /** @return void */ + protected function setupDist() + { + /* pass */ + } + + public function prepareInit(PackageWorkman $pw, bool $force = false) : void + { + $url = $this->conf->getSectionItem($this->name, "pkg_url"); + $pw->fetchAndUnzip($url, "mariadb.zip", $this->conf->getSrvDir(), "mariadb", $force); + } + + public function init() : void + { + echo "Initializing " . $this->name . ".\n"; + + $this->setupDist(); + + $this->up(); + $this->down(true); + + echo $this->name . " initialization done.\n"; + } + + public function up() : void + { + echo "Starting " . $this->name . ".\n"; + + $cwd = getcwd(); + + chdir($this->base); + + $port = $this->conf->getSectionItem($this->name, "port"); + + //$h = popen("start /b .\\bin\\mysqld.exe --port=$port >nul 2>&1", "r"); + $h = popen("start /b .\\bin\\mysqld.exe --port=$port 2>&1", "r"); + + if (!is_resource($h)) { + chdir($cwd); + throw new Exception("Failed to start MariaDB."); + } + sleep(3); + + while (!feof($h)) { + echo fread($h, 1024); + } + pclose($h); + + chdir($cwd); + + echo $this->name . " started.\n"; + } + + public function down(bool $force = false) : void + { + echo "Stopping " . $this->name . ".\n"; + + $cwd = getcwd(); + + chdir($this->base); + + $user = $this->conf->getSectionItem($this->name, "user"); + $pass = $this->conf->getSectionItem($this->name, "pass"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $cmd = sprintf(".\\bin\\mysqladmin.exe --host=$host --port=$port -u $user %s--shutdown_timeout=0 shutdown", ($pass ? "-p$pass " : "")); + exec($cmd); + + if ($force) { + sleep(1); + exec("taskkill /f /im mysqld.exe >nul 2>&1"); + } + + chdir($cwd); + + echo $this->name . " stopped.\n"; + } + + public function query(string $s, string $db = NULL) : void + { + $ret = NULL; + + $cwd = getcwd(); + + chdir($this->base); + + $user = $this->conf->getSectionItem($this->name, "user"); + $pass = $this->conf->getSectionItem($this->name, "pass"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $pass_arg = $pass ? "-p$pass " : ""; + $db_arg = $db ? "-D $db" : ""; + shell_exec(".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port $db_arg -e \"$s\""); + //var_dump($this->base, getcwd(), ".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port -e \"$s\""); + + chdir($cwd); + } + + public function import(string $path, string $db = NULL) : void + { + $ret = NULL; + + $cwd = getcwd(); + + chdir($this->base); + + $user = $this->conf->getSectionItem($this->name, "user"); + $pass = $this->conf->getSectionItem($this->name, "pass"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $pass_arg = $pass ? "-p$pass " : ""; + $db_arg = $db ? "-D $db" : ""; + shell_exec(".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port $db_arg < \"$path\""); + + chdir($cwd); + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Server/NGINX.php b/lib/php/libsdk/SDK/Build/PGO/Server/NGINX.php new file mode 100644 index 0000000..107b1d3 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Server/NGINX.php @@ -0,0 +1,160 @@ +conf = $conf; + $this->base = $conf->getSrvDir(strtolower($this->name)); + $this->php = $php; + } + + protected function setupDist() : void + { + $nginx_conf_in = $this->conf->getTplDir($this->name) . DIRECTORY_SEPARATOR . "nginx.conf"; + $conf_fn = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf"; + + $port = $this->conf->getSectionItem($this->name, "port"); + if (!$port) { + $port = $this->conf->getNextPort(); + $this->conf->setSectionItem($this->name, "port", $port); + } + + $vars = array( + $this->conf->buildTplVarName($this->name, "docroot") => str_replace("\\", "/", $this->base . DIRECTORY_SEPARATOR . "html"), + ); + + $this->conf->processTplFile( + $nginx_conf_in, + $conf_fn, + $vars + ); + } + + public function prepareInit(PackageWorkman $pw, bool $force = false) : void + { + $url = $this->conf->getSectionItem($this->name, "pkg_url"); + $pw->fetchAndUnzip($url, "nginx.zip", $this->conf->getSrvDir(), "nginx", $force); + } + + public function init() : void + { + echo "Initializing " . $this->name . ".\n"; + + $this->setupDist(); + + $this->upMe(); + $this->downMe(true); + + + echo $this->name . " initialization done.\n"; + } + + protected function upMe() : void + { + echo "Starting " . $this->name . ".\n"; + + $cwd = getcwd(); + + chdir($this->base); + + $h = popen("start /b .\\nginx.exe 2>&1", "r"); + if (!is_resource($h)) { + chdir($cwd); + throw new Exception("Failed to start NGINX."); + } + sleep(3); + +/* while (!feof($h)) { + echo fread($h, 1024); + }*/ + + pclose($h); + + chdir($cwd); + + echo $this->name . " started.\n"; + } + + public function up() : void + { + + $this->php->up(); + $this->upMe(); + } + + public function downMe(bool $force = false) : void + { + echo "Stopping " . $this->name . ".\n"; + + $cwd = getcwd(); + + chdir($this->base); + + exec(".\\nginx.exe -s quit"); + + if ($force) { + sleep(1); + exec("taskkill /f /im nginx.exe >nul 2>&1"); + } + + chdir($cwd); + + echo $this->name . " stopped.\n"; + } + + public function down(bool $force = false) : void + { + $this->php->down(); + $this->downMe($force); + } + + /* Use only for init phase! */ + /** + * @param array $tpl_vars + * @return void + */ + public function addServer(string $part_tpl_fn, array $tpl_vars = array()) + { + if (!file_exists($part_tpl_fn)) { + throw new Exception("Template file '$part_tpl_fn' doesn't exist."); + } + + /* We've already did a fresh (re)config, so use the work file now. */ + $nginx_conf_in = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf"; + $cur_conf = file_get_contents($nginx_conf_in); + + $in = file_get_contents($part_tpl_fn); + $out = $this->conf->processTpl($in, $tpl_vars); + + $tpl = " # PHP_SDK_PGO_NGINX_SERVERS_INC_TPL"; + $new_conf = str_replace($tpl, "$out\n$tpl", $cur_conf); + + $conf_fn = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf"; + if (!file_put_contents($conf_fn, $new_conf)) { + throw new Exception("Couldn't write '$conf_fn'."); + } + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Server/PostgreSQL.php b/lib/php/libsdk/SDK/Build/PGO/Server/PostgreSQL.php new file mode 100644 index 0000000..f4c08da --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Server/PostgreSQL.php @@ -0,0 +1,144 @@ +conf = $conf; + $this->base = $conf->getSrvDir(strtolower($this->name)); + $this->data_dir = $this->base . DIRECTORY_SEPARATOR . "data"; + } + + /** @return void */ + protected function setupDist() + { + $user = $this->conf->getSectionItem($this->name, "user"); + if (!$user) { + $user = trim(shell_exec("pwgen -1 -s 8")); + $this->conf->setSectionItem($this->getName(), "user", $user); + } + $pass = $this->conf->getSectionItem($this->name, "pass"); + if (!$pass) { + $pass = trim(shell_exec("pwgen -1 -s 8")); + $this->conf->setSectionItem($this->getName(), "pass", $pass); + } + + if (!is_dir($this->data_dir)) { + $pwfile = tempnam(sys_get_temp_dir(), "tmp"); + if (strlen($pass) !== file_put_contents($pwfile, $pass)) { + throw new Exception("Couldn't write '$pwfile'."); + } + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "initdb.exe --auth=trust --nosync --username=$user --pwfile=$pwfile --encoding=UTF8 " . $this->data_dir; + //$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "initdb.exe --auth=trust --nosync --username=$user --encoding=UTF8 " . $this->data_dir; + /*echo "$cmd\n"; + echo file_get_contents($pwfile) . "\n";*/ + exec($cmd); + unlink($pwfile); + } + } + + public function prepareInit(PackageWorkman $pw, bool $force = false) : void + { + $url = $this->conf->getSectionItem($this->name, "pkg_url"); + $pw->fetchAndUnzip($url, "postgresql.zip", $this->conf->getSrvDir(), "postgresql", $force); + } + + public function init() : void + { + echo "Initializing " . $this->name . ".\n"; + + $this->setupDist(); + + $this->up(); + $this->down(true); + + echo $this->name . " initialization done.\n"; + } + + public function up() : void + { + echo "Starting " . $this->name . ".\n"; + + + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "pg_ctl.exe start -D " . $this->data_dir . " -o \"-h $host -p $port\""; + $h = popen($cmd, "r"); + /* XXX error check*/ + pclose($h); + + echo $this->name . " started.\n"; + } + + public function down(bool $force = false) : void + { + echo "Stopping " . $this->name . ".\n"; + + + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "pg_ctl.exe stop -D " . $this->data_dir . " -m fast"; + exec($cmd); + + if ($force) { + //sleep(1); + //exec("taskkill /f /im nginx.exe >nul 2>&1"); + } + + echo $this->name . " stopped.\n"; + } + + public function createDb(string $db_name) : void + { + $user = $this->conf->getSectionItem($this->name, "user"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "createdb.exe -h $host -p $port -U $user $db_name"; + exec($cmd); + } + + public function dropDb(string $db_name) : void + { + $user = $this->conf->getSectionItem($this->name, "user"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "dropdb.exe --if-exists -h $host -p $port -U $user $db_name"; + exec($cmd); + } + + public function query(string $s, string $db = NULL) : void + { + $ret = NULL; + + $user = $this->conf->getSectionItem($this->name, "user"); + $host = $this->conf->getSectionItem($this->name, "host"); + $port = $this->conf->getSectionItem($this->name, "port"); + + $db_arg = $db ? "-d $db" : ""; + $cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "psql.exe -h $host -p $port -U $user $db_arg -c \"$s\""; + shell_exec($cmd); + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Tool/PGO.php b/lib/php/libsdk/SDK/Build/PGO/Tool/PGO.php new file mode 100644 index 0000000..e592ad8 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Tool/PGO.php @@ -0,0 +1,112 @@ +conf = $conf; + $this->php = $php; + } + + protected function getPgcName(string $fname) : string + { + $bn = basename($fname, substr($fname, -4, 4)); + $dn = dirname($fname); + + return $dn . DIRECTORY_SEPARATOR . $bn . "!" . $this->idx . ".pgc"; + } + + protected function getPgdName(string $fname) : string + { + $bn = basename($fname, substr($fname, -4, 4)); + $dn = dirname($fname); + + return $dn . DIRECTORY_SEPARATOR . $bn . ".pgd"; + } + + /** @return array */ + protected function getWorkItems() : array + { + $exe = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.exe"); + $dll = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.dll"); + $dll = array_merge($dll, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "php*.dll")); + + /* find out next index */ + $tpl = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "php{7,8,}{ts,}.dll", GLOB_BRACE)[0]; + if (!$tpl) { + throw new Exception("Couldn't find php7[ts].dll in the PHP root dir."); + } + do { + if (!file_exists($this->getPgcName($tpl))) { + break; + } + $this->idx++; + } while (true); + + return array_unique(array_merge($exe, $dll)); + } + + public function dump(bool $merge = true) : void + { + $its = $this->getWorkItems(); + + foreach ($its as $base) { + $pgc = $this->getPgcName($base); + $pgd = $this->getPgdName($base); + + shell_exec("pgosweep $base $pgc"); + //passthru("pgosweep $base $pgc"); + + if ($merge) { + shell_exec("pgomgr /merge:1000 $pgc $pgd"); + //passthru("pgomgr /merge:1000 $pgc $pgd"); + /* File is already spent, no need to keep it. + If seeing linker warnings about no pgc + were found for some object - most + likely the object were not included in + any training scenario. */ + @unlink($pgc); + } + } + } + + public function waste() : void + { + $this->dump(false); + } + + public function clean(bool $clean_pgc = true, bool $clean_pgd = true) : void + { + if ($clean_pgc) { + $its = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.pgc"); + $its = array_merge($its, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "*" . DIRECTORY_SEPARATOR . "*.pgc")); + foreach (array_unique($its) as $pgc) { + unlink($pgc); + } + } + + if ($clean_pgd) { + $its = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.pgd"); + $its = array_merge($its, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "*" . DIRECTORY_SEPARATOR . "*.pgd")); + foreach (array_unique($its) as $pgd) { + shell_exec("pgomgr /clear $pgd"); + //passthru("pgomgr /clear $pgd"); + } + } + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Tool/PackageWorkman.php b/lib/php/libsdk/SDK/Build/PGO/Tool/PackageWorkman.php new file mode 100644 index 0000000..9ccd2ac --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Tool/PackageWorkman.php @@ -0,0 +1,57 @@ +conf = $conf; + } + + public function fetch(string $url, string $tgt_fn, bool $force = false) : void + { + $cache_fn = $this->conf->getPkgCacheDir() . DIRECTORY_SEPARATOR . basename($tgt_fn); + + if ($force || !file_exists($cache_fn)) { + echo "Fetching '$url' into '$tgt_fn'\n"; + $this->download($url, $cache_fn); + } + + if ($force || !file_exists($tgt_fn)) { + if ($cache_fn != $tgt_fn && !$this->cp($cache_fn, $tgt_fn)) { + throw new Exception("Failed to copy '$cache_fn' to '$tgt_fn'."); + } + } + } + + /* Only for zips! */ + public function fetchAndUnzip(string $url, string $zip_bn, string $zip_tgt_dn, string $tgt_bn = NULL, bool $force = false) : void + { + $cache_fn = $this->conf->getPkgCacheDir() . DIRECTORY_SEPARATOR . $zip_bn; + + if ($force || !file_exists($cache_fn)) { + $this->fetch($url, $cache_fn, $force); + } + + $tgt_name = $zip_tgt_dn . ($tgt_bn ? DIRECTORY_SEPARATOR . $tgt_bn : ""); + if ($force || $tgt_bn && !file_exists($tgt_name) || !$tgt_bn /* This means unzip always if no rename. */) { + echo "Unpacking '$cache_fn' to '$tgt_name'\n"; + try { + $this->unzip($cache_fn, $zip_tgt_dn, $tgt_bn); + } catch (\Throwable $e) { + $this->rm($cache_fn); + throw $e; + } + } + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/Tool/Training.php b/lib/php/libsdk/SDK/Build/PGO/Tool/Training.php new file mode 100644 index 0000000..68026dc --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/Tool/Training.php @@ -0,0 +1,126 @@ +conf = $conf; + $this->t_case = $t_case; + + $type = $this->t_case->getType(); + if (!in_array($type, array("web", "cli"))) { + throw new Exception("Unknown training type '$type'."); + } + } + + public function getCase() : TrainingCase + { + return $this->t_case; + } + + /** @param array $stat */ + public function runWeb(int $max_runs, ?array &$stat = array()) : void + { + $url_list_fn = $this->t_case->getJobFilename(); + + if (!file_exists($url_list_fn)) { + printf("\033[31m WARNING: Job file '$url_list_fn' not found!\033[0m\n"); + } + + $a = file($url_list_fn, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + + $stat = array("http_code" => array(), "not_ok" => array()); + + for ($k = 0; $k < $max_runs; $k++) { + echo "."; + + $ch = array(); + + $mh = curl_multi_init(); + + foreach ($a as $i => $u) { + + $ch[$i] = curl_init($u); + + curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT_MS, 500000); + curl_setopt($ch[$i], CURLOPT_TIMEOUT_MS, 500000); + curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch[$i], CURLOPT_USERAGENT, SDKConfig::getSdkUserAgentName()); + /* ??? */ + /*curl_setopt($ch[$i], CURLOPT_FOLLOWLOCATION, true);*/ + + curl_multi_add_handle($mh, $ch[$i]); + } + + $active = NULL; + + do { + $mrc = curl_multi_exec($mh, $active); + } while ($mrc == CURLM_CALL_MULTI_PERFORM); + + while ($active && $mrc == CURLM_OK) { + if (curl_multi_select($mh, 42.0) != -1) { + do { + $mrc = curl_multi_exec($mh, $active); + } while ($mrc == CURLM_CALL_MULTI_PERFORM); + } + } + + foreach ($ch as $h) { + curl_multi_remove_handle($mh, $h); + + /* Gather some stats */ + $info = curl_getinfo($h); + $http_code = $info["http_code"]; + + if (isset($stat["http_code"][$http_code])) { + $stat["http_code"][$http_code]++; + } else { + $stat["http_code"][$http_code] = 1; + } + + if (!$this->t_case->httpStatusOk((int)$http_code)) { + $stat["not_ok"][] = $info; + + //echo curl_multi_getcontent($h) ; + } + + curl_close($h); + } + + curl_multi_close($mh); + + } + + echo "\n"; + + } + + /* TODO Extend with number runs. */ + /** @param array $stat */ + public function run(int $max_runs = 1, ?array &$stat = array()) : void + { + $type = $this->t_case->getType(); + switch ($type) { + case "web": + $this->runWeb($max_runs, $stat); + break; + + case "cli": + default: + throw new Exception("Unknown training type '$type'."); + } + } +} diff --git a/lib/php/libsdk/SDK/Build/PGO/TrainingCaseIterator.php b/lib/php/libsdk/SDK/Build/PGO/TrainingCaseIterator.php new file mode 100644 index 0000000..f335b24 --- /dev/null +++ b/lib/php/libsdk/SDK/Build/PGO/TrainingCaseIterator.php @@ -0,0 +1,113 @@ + + */ +class TrainingCaseIterator implements \Iterator +{ + /** @var PGOConfig */ + protected $conf; + + /** @var array */ + protected $items = array(); + + /** @var int */ + protected $idx; + + /** @var object */ + protected $el; + + public function __construct(PGOConfig $conf) + { + $this->rewind(); + + $this->conf = $conf; + + $items = glob($this->conf->getCasesTplDir() . DIRECTORY_SEPARATOR . "*"); + foreach ($items as $it) { + if (!is_dir($it)) { + continue; + } + + if (!file_exists($this->getHandlerFilename($it))) { + echo "Test case handler isn't present in '$it'.\n"; + continue; + } + + if ($this->isInactive($it)) { + echo "The test case in '$it' is marked inactive.\n"; + continue; + } + + $this->items[] = $it; + } + + + } + + protected function isInactive(string $base) : bool + { + return file_exists($base . DIRECTORY_SEPARATOR . "inactive"); + } + + protected function getHandlerFilename(string $base) : string + { + return $base . DIRECTORY_SEPARATOR . "TrainingCaseHandler.php"; + } + + #[\ReturnTypeWillChange] + public function current() + { + $base = $this->items[$this->idx]; + $ns = basename($base); + + /* Don't overwrite generated config. */ + $it = $this->conf->getSectionItem($ns); + if (!$it) { + $this->conf->importSectionFromDir($ns, $base); + } + + require_once $this->getHandlerFilename($base); + + $srv_http = $this->conf->getSrv($this->conf->getSectionItem($ns, "srv_http")); + $srv_db = $this->conf->getSrv($this->conf->getSectionItem($ns, "srv_db")); + + $class = "$ns\\TrainingCaseHandler"; + + $this->el = new $class($this->conf, $srv_http, $srv_db); + + return $this->el; + } + + #[\ReturnTypeWillChange] + public function next() + { + $this->idx++; + } + + #[\ReturnTypeWillChange] + public function rewind() + { + $this->idx = 0; + } + + #[\ReturnTypeWillChange] + public function valid() + { + return $this->idx < count($this->items); + } + + #[\ReturnTypeWillChange] + public function key() + { + if (!is_object($this->el)) { + return NULL; + } + + return $this->el->getName(); + } +} diff --git a/lib/php/libsdk/SDK/Cache.php b/lib/php/libsdk/SDK/Cache.php new file mode 100644 index 0000000..4b3f429 --- /dev/null +++ b/lib/php/libsdk/SDK/Cache.php @@ -0,0 +1,100 @@ +id = $id; + $this->hash = md5($id); + /* XXX pass as arg, fine for now. */ + }/*}}}*/ + + protected function getCacheablePath(string $path, bool $relative = false) : string + {/*{{{*/ + if ($relative) { + $dir = Config::getCacheDir(); + $name = $path; + } else { + $dir = dirname($path); + $name = basename($path); + } + + return $dir . DIRECTORY_SEPARATOR . $this->hash . "." . $name; + }/*}}}*/ + + public function fileIsCached(string $path, bool $relative = false) : bool + {/*{{{*/ + return file_exists($this->getCacheablePath($path, $relative)); + }/*}}}*/ + + /* TODO Sometimes a timestamp comparison might make sense. */ + public function cachedContentDiffers(string $path, string $content, bool $relative = false) : bool + {/*{{{*/ + $p = $this->getCacheablePath($path, $relative); + + if (!file_exists($p)) { + return true; + } + + $old_sum = md5_file($p); + $new_sum = md5($content); + + return $old_sum !== $new_sum; + }/*}}}*/ + + public function cacheContent(string $path, string $content, bool $relative = false) : void + {/*{{{*/ + $p = $this->getCacheablePath($path, $relative); + + $to_write = strlen($content); + $wrote = 0; + + $fd = fopen($p, "wb"); + + flock($fd, LOCK_EX); + + do { + $got = fwrite($fd, substr($content, $wrote)); + if (false === $got) { + break; + } + $wrote += $got; + } while ($wrote < $to_write); + + flock($fd, LOCK_UN); + + fclose($fd); + + if ($to_write !== $wrote) { + throw new Exception("Couldn't cache '$p'"); + } + }/*}}}*/ + + public function getCachedContent(string $path, bool $relative = false) : ?string + {/*{{{*/ + $p = $this->getCacheablePath($path, $relative); + + if (file_exists($p)) { + return file_get_contents($p); + } + + return NULL; + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Config.php b/lib/php/libsdk/SDK/Config.php new file mode 100644 index 0000000..d6ccf8b --- /dev/null +++ b/lib/php/libsdk/SDK/Config.php @@ -0,0 +1,456 @@ + */ + protected static $knownBranches = array (); + + /* Helper props and methods. */ + + /** @var ?string */ + protected static $currentBranchName = NULL; + + /** @var ?string */ + protected static $currentArchName = NULL; + + /** @var ?string */ + protected static $currentCrtName = NULL; + + /** @var ?string */ + protected static $currentStabilityName = NULL; + + /** @var ?string */ + protected static $depsLocalPath = NULL; + + public static function getDepsHost() : string + {/*{{{*/ + return self::$depsHost; + }/*}}}*/ + + public static function getDepsPort() : int + {/*{{{*/ + return self::$depsPort; + }/*}}}*/ + + public static function getDepsUriScheme() : string + {/*{{{*/ + return self::$depsUriScheme; + }/*}}}*/ + + public static function getDepsBaseUri() : string + {/*{{{*/ + return self::$depsBaseUri; + }/*}}}*/ + + public static function setCurrentArchName(string $arch) : void + {/*{{{*/ + $arch = strtolower($arch); + + if ("x64" != $arch && "x86" != $arch && "arm64" != $arch) { + throw new Exception("Unknown arch keyword, x86 or x64 or arm64 is accepted"); + } + + self::$currentArchName = $arch; + } /*}}}*/ + + public static function getCurrentArchName() : string + {/*{{{*/ + if (NULL === self::$currentArchName) { + if (FALSE !== ($env = getenv('PHP_SDK_ARCH'))) { + self::setCurrentArchName($env); + } else { + /* XXX this might be not true for other compilers! */ + passthru("where cl.exe >nul", $status); + if ($status) { + throw new Exception("Couldn't execute cl.exe."); + } + + exec("cl.exe /? 2>&1", $out); + + if (preg_match(",x64,", $out[0])) { + self::setCurrentArchName("x64"); + } elseif (preg_match(",x86,", $out[0])) { + self::setCurrentArchName("x86"); + } elseif (preg_match(",arm64,", $out[0])) { + self::setCurrentArchName("arm64"); + } else { + throw new Exception("Couldn't determine Arch."); + } + } + } + + return self::$currentArchName; + } /*}}}*/ + + public static function setCurrentCrtName(string $crt) : void + {/*{{{*/ + self::$currentCrtName = $crt; + } /*}}}*/ + + public static function getCurrentCrtName() : ?string + {/*{{{*/ + if (NULL === self::$currentCrtName) { + if (FALSE !== ($env = getenv('PHP_SDK_VS'))) { + self::setCurrentCrtName($env); + } else { + $all_branches = Config::getKnownBranches(); + + if (!isset($all_branches[Config::getCurrentBranchName()])) { + throw new Exception("Couldn't find any configuration for branch '" . Config::getCurrentBranchName() . "'"); + } + + $branch = $all_branches[Config::getCurrentBranchName()]; + if (count($branch) > 1) { + throw new Exception("Multiple CRTs are available for this branch, please choose one from " . implode(",", array_keys($branch))); + } + + self::setCurrentCrtName(array_keys($branch)[0]); + } + } + + return self::$currentCrtName; + } /*}}}*/ + + public static function setCurrentStabilityName(string $stability) : void + {/*{{{*/ + if ("stable" != $stability && "staging" != $stability) { + throw new Exception("Unknown stability keyword, either stable or staging is accepted"); + } + + self::$currentStabilityName = $stability; + } /*}}}*/ + + public static function getCurrentStabilityName() : ?string + {/*{{{*/ + if (NULL === self::$currentStabilityName) { + if ("master" == Config::getCurrentBranchName()) { + Config::setCurrentStabilityName("staging"); + } else { + Config::setCurrentStabilityName("stable"); + } + } + + return self::$currentStabilityName; + } /*}}}*/ + + /** @return array */ + public static function getKnownBranches() : array + {/*{{{*/ + if (empty(self::$knownBranches)) { + $cache_file = "known_branches.txt"; + $deps_path = self::getDepsLocalPath(); + if (!$deps_path) { + throw new Exception("Couldn't determine dependencies path. Please either switch to the PHP source root or use -d option."); + } + $cache = new Cache($deps_path); + $fetcher = new Fetcher(self::$depsHost, self::$depsPort, self::$depsUriScheme); + + $tmp = $fetcher->getByUri(self::$depsBaseUri . "/series/"); + if ("" !== $tmp) { + $data = array(); + if (preg_match_all(",packages-(.+)-(v[cs]\d+)-(x86|x64|arm64)-(stable|staging)\.txt,Us", $tmp, $m, PREG_SET_ORDER)) { + foreach ($m as $b) { + if (!isset($data[$b[1]])) { + $data[$b[1]] = array(); + } + + $data[$b[1]][$b[2]][] = array("arch" => $b[3], "stability" => $b[4]); + } + + $cache->cachecontent($cache_file, json_encode($data, JSON_PRETTY_PRINT), true); + } + } else { + /* It might be ok to use cached branches list, if a fetch failed. */ + $tmp = $cache->getCachedContent($cache_file, true); + if (NULL == $tmp) { + throw new Exception("No cached branches list found"); + } + $data = json_decode($tmp, true); + } + + if (!is_array($data) || empty($data)) { + throw new Exception("Failed to fetch supported branches"); + } + self::$knownBranches = $data; + } + + return self::$knownBranches; + }/*}}}*/ + + public static function setCurrentBranchName(string $name) : void + {/*{{{*/ + if (!array_key_exists($name, self::getKnownBranches())) { + throw new Exception("Unsupported branch '$name'"); + } + + self::$currentBranchName = $name; + }/*}}}*/ + + public static function guessCurrentBranchName() : ?string + {/*{{{*/ + $branch = NULL; + $found = false; + + $rmtools_branch = getenv("PHP_RMTOOLS_PHP_BUILD_BRANCH"); + if ("master" == $rmtools_branch) { + return "master"; + } + + /* Try to figure out the branch. The worky scenarios are + - CWD is in php-src + - phpize is on the path + FIXME for the dev package, there should be a php-config utility + */ + $fl = "main/php_version.h"; + $found = file_exists($fl); + + if (!$found) { + exec("where phpize", $out, $status); + if (!$status) { + $fl = dirname($out[0]) . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . $fl; + $found = file_exists($fl); + } + } + + if ($found) { + $s = file_get_contents($fl); + $major = $minor = NULL; + + if (preg_match(",PHP_MAJOR_VERSION (\d+),", $s, $m)) { + $major = $m[1]; + } + if (preg_match(",PHP_MINOR_VERSION (\d+),", $s, $m)) { + $minor = $m[1]; + } + + if (is_numeric($major) && is_numeric($minor)) { + $branch = "$major.$minor"; + } + + /* Verify that we use an available branch name. Master has some + version, but no dedicated series. For master, it rather + makes sense to use master as branch name. */ + $git = trim(shell_exec("where git.exe")); + if ($git && is_dir(".git")) { + $cmd = "\"$git\" branch"; + + $ret = trim(shell_exec($cmd)); + if (preg_match_all(",\*\s+master,", $ret) > 0) { + $branch = "master"; + } + } + } + + return $branch; + }/*}}}*/ + + public static function getCurrentBranchName() : string + {/*{{{*/ + if (NULL == self::$currentBranchName) { + $branch = self::guessCurrentBranchName(); + self::setCurrentBranchName($branch); + } + + return self::$currentBranchName; + }/*}}}*/ + + /** @return array */ + public static function getCurrentBranchData() : array + {/*{{{*/ + $ret = array(); + $branches = self::getKnownBranches(); + + $current_branch_name = self::getCurrentBranchName(); + if (!array_key_exists($current_branch_name, $branches)) { + throw new Exception("Unknown branch '$current_branch_name'"); + } + + $crt = null; + $cur_crt = Config::getCurrentCrtName(); + if (count($branches[$current_branch_name]) > 1) { + if (NULL === $cur_crt) { + throw new Exception("More than one CRT is available for branch '$current_branch_name', pass one explicitly."); + } + + $cur_crt_usable = false; + foreach (array_keys($branches[$current_branch_name]) as $crt) { + if ($cur_crt == $crt) { + $cur_crt_usable = true; + break; + } + } + if (!$cur_crt_usable) { + throw new Exception("The passed CRT '$cur_crt' doesn't match any available for branch '$current_branch_name'"); + } + $data = $branches[$current_branch_name][$cur_crt]; + } else { + /* Evaluate CRTs, to avoid ambiquity. */ + $crt = key($branches[$current_branch_name]); + $data = $branches[$current_branch_name][$crt]; + if ($crt != $cur_crt) { + throw new Exception("The passed CRT '$cur_crt' doesn't match any available for branch '$current_branch_name'"); + } + } + + $ret["name"] = $current_branch_name; + $ret["crt"] = $crt; + + /* Last step, filter by arch and stability. */ + foreach ($data as $d) { + if (self::getCurrentArchName() == $d["arch"]) { + if (self::getCurrentStabilityName() == $d["stability"]) { + $ret["arch"] = $d["arch"]; + $ret["stability"] = $d["stability"]; + } + } + } + + if (!isset($ret["arch"]) || !$ret["arch"]) { + throw new Exception("Failed to find config with arch '" . self::getCurrentArchName() . "'"); + } + if (!isset($ret["stability"]) || !$ret["stability"]) { + throw new Exception("Failed to find config with stability '" . self::getCurrentStabilityName() . "'"); + } + if (!isset($ret["crt"]) || !$ret["crt"]) { + throw new Exception("Failed to find config with arch '" . self::getCurrentArchName() . "'"); + } + + return $ret; + }/*}}}*/ + + public static function getSdkNugetFeedUrl() : string + {/*{{{*/ + return self::$sdkNugetFeedUrl; + }/*}}}*/ + + public static function getSdkPath() : string + {/*{{{*/ + $path = getenv("PHP_SDK_ROOT_PATH"); + + if (!$path) { + throw new Exception("PHP_SDK_ROOT_PATH isn't set!"); + } + + $path = realpath($path); + if (!file_exists($path)) { + throw new Exception("The path '$path' is non existent."); + } + + return $path; + }/*}}}*/ + + public static function getSdkVersion() : string + {/*{{{*/ + $path = self::getSdkPath() . DIRECTORY_SEPARATOR . "VERSION"; + + if (!file_exists($path)) { + throw new Exception("Couldn't find the SDK version file."); + } + + return trim(file_get_contents($path)); + }/*}}}*/ + + public static function getDepsLocalPath() : ?string + {/*{{{*/ + if (NULL == self::$depsLocalPath) { + if (file_exists("Makefile")) { + $s = file_get_contents("Makefile"); + + if (preg_match(",PHP_BUILD=(.+),", $s, $m)) { + if (isset($m[1])) { + self::setDepsLocalPath(trim($m[1])); + } + } + } + } + + if (NULL == self::$depsLocalPath) { + $tmp = dirname(getcwd()) . DIRECTORY_SEPARATOR . "deps"; + if (is_dir($tmp)) { + self::setDepsLocalPath($tmp); + } + } + + if (NULL == self::$depsLocalPath) { + $tmp = realpath("../deps"); + if (is_dir($tmp)) { + self::setDepsLocalPath($tmp); + } + } + + if (NULL == self::$depsLocalPath) { + if (file_exists("main/php_version.h")) { + /* Deps dir might not exist. */ + self::setDepsLocalPath(realpath("..") . DIRECTORY_SEPARATOR . "deps"); + } + } + + return self::$depsLocalPath; + }/*}}}*/ + + public static function setDepsLocalPath(string $path) : void + {/*{{{*/ + self::$depsLocalPath = $path; + }/*}}}*/ + + public static function getCacheDir() : string + {/*{{{*/ + $path = self::getSdkPath() . DIRECTORY_SEPARATOR . ".cache"; + + if (!file_exists($path)) { + if (!mkdir($path)) { + throw new Exception("Failed to create '$path'"); + } + } + + return $path; + }/*}}}*/ + + public static function getTmpDir() : string + {/*{{{*/ + $path = self::getSdkPath() . DIRECTORY_SEPARATOR . ".tmp"; + + if (!file_exists($path)) { + if (!mkdir($path)) { + throw new Exception("Failed to create '$path'"); + } + } + + return $path; + }/*}}}*/ + + public static function getSdkUserAgentName() : string + {/*{{{*/ + return "PHP-SDK-BINARY-TOOLS/" . self::getSdkVersion(); + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Exception.php b/lib/php/libsdk/SDK/Exception.php new file mode 100644 index 0000000..0c58457 --- /dev/null +++ b/lib/php/libsdk/SDK/Exception.php @@ -0,0 +1,17 @@ +isDir()) { + $ret = $ret && rmdir($item->getPathname()); + } else { + $ret = $ret && unlink($item->getPathname()); + } + } + return $ret && rmdir($path); + }/*}}}*/ + + /* TODO islink and more checks */ + protected function cp_or_mv(string $src, string $dst, callable $cb) : bool + {/*{{{*/ + if (!file_exists($src)) { + return false; + } else if (is_file($src)) { + return call_user_func($cb, $src, $dst); + } + + if (!file_exists($dst)) { + $this->md($dst); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator( + $src, + \FilesystemIterator::SKIP_DOTS + ), + \RecursiveIteratorIterator::CHILD_FIRST + ); + $cut_len = strlen($src)+1; + foreach ($iterator as $item) { + $src_path = $item->getPathname(); + $sub = substr($src_path, $cut_len); + $dst_path = $dst . DIRECTORY_SEPARATOR . $sub; + $dst_parent = dirname($dst_path); + + if (!is_dir($dst_parent)) { + if (!$this->md($dst_parent)) { + throw new Exception("Unable to create '$dst_parent'"); + } + } + + if ($item->isFile()) { + if (!call_user_func($cb, $src_path, $dst_path)) { + assert(is_string($cb)); + throw new Exception("Unable to $cb '$src_path' to '$dst_path'"); + } + } + + } + + return true; + }/*}}}*/ + + protected function cp(string $src, string $dst) : bool + {/*{{{*/ + return $this->cp_or_mv($src, $dst, "copy"); + }/*}}}*/ + + protected function mv(string $src, string $dst) : bool + {/*{{{*/ + $ret = $this->cp_or_mv($src, $dst, "rename"); + + $ret = $ret && $this->rm($src); + + return $ret; + }/*}}}*/ + + protected function download(string $url, string $dest_fn = NULL) : ?string + {/*{{{*/ + $fd = NULL; + $retry = 0; + +retry: + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + + if ($dest_fn) { + $fd = fopen($dest_fn, "w+"); + curl_setopt($ch, CURLOPT_FILE, $fd); + } else { + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + } + + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_USERAGENT, Config::getSdkUserAgentName()); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + + // workaround for + curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + + $ret = curl_exec($ch); + + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (false === $ret || 200 !== $code) { + $err = curl_error($ch); + curl_close($ch); + if ($dest_fn) { + fclose($fd); + } + if ($retry++ < 3) { + goto retry; + } + throw new Exception($err); + } + + curl_close($ch); + + if ($dest_fn) { + fclose($fd); + return NULL; + } + + return $ret; + }/*}}}*/ + + /* TODO More detailed zip errors. */ + protected function unzip(string $zip_fn, string $dest_fn, string $dest_dn = NULL) : void + {/*{{{*/ + $zip = new \ZipArchive; + + $res = $zip->open($zip_fn); + if (true !== $res) { + throw new Exception("Failed to open '$zip_fn'."); + } + + $res = $zip->extractTo($dest_fn); + if (true !== $res) { + $zip->close(); + throw new Exception("Failed to unzip '$zip_fn'."); + } + + /* Not robust, useful for zips containing one dir sibling only in the root. */ + if ($dest_dn) { + $stat = $zip->statIndex(0); + if (false === $stat) { + $zip->close(); + throw new Exception("Failed to stat first index in '$zip_fn'."); + } + + $zip->close(); + + /* Index of zero might be not the zipped folder, unusual but true. */ + /*$name = $stat["name"]; + if ("/" != substr($name, -1)) { + throw new Exception("'$name' is not a directory."); + } + $name = substr($name, 0, -1);*/ + + $name = rtrim($stat["name"], "/"); + while (strstr($name, '/') !== false) { + $name = dirname($name); + } + + $old_dir = $dest_fn . DIRECTORY_SEPARATOR . $name; + $new_dir = $dest_fn . DIRECTORY_SEPARATOR . $dest_dn; + if (file_exists($new_dir)) { + if (!$this->rm($new_dir)) { + throw new Exception("Failed to remove '$new_dir'."); + } + } + /* if (!$this->mv($old_dir, $new_dir)) { */ + if (!rename($old_dir, $new_dir)) { + throw new Exception("Failed to rename '$old_dir' to '$new_dir'."); + } + } else { + $zip->close(); + } + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/lib/php/libsdk/SDK/Lock.php b/lib/php/libsdk/SDK/Lock.php new file mode 100644 index 0000000..cc4a2a8 --- /dev/null +++ b/lib/php/libsdk/SDK/Lock.php @@ -0,0 +1,117 @@ +fn = Config::getTmpDir() . DIRECTORY_SEPARATOR . $hash . ".lock"; + + if ($auto) { + if ($autoShared) { + $this->shared(); + } else { + $this->exclusive(); + } + } + }/*}}}*/ + + public function __destruct() + {/*{{{*/ + $this->unlock(); + /* We don't really know no one else waits on the same lock yet.*/ + /*if (file_exists($this->fn) && !$this->shared) { + @unlink($this->fn); + }*/ + }/*}}}*/ + + public function shared(bool $block = false) : bool + {/*{{{*/ + $flags = LOCK_SH; + if (!$block) { + $flags |= LOCK_NB; + } + + return $this->doLock($flags); + }/*}}}*/ + + public function exclusive(bool $block = false) : bool + {/*{{{*/ + $flags = LOCK_EX; + if (!$block) { + $flags |= LOCK_NB; + } + + return $this->doLock($flags); + }/*}}}*/ + + protected function doLock(int $flags = LOCK_EX) : bool + {/*{{{*/ + if ($this->locked) { + /* Or throw an exception, as we don't know which lock type the outta world expected. */ + return true; + } + + $this->shared = $flags & LOCK_SH; + if ($this->shared) { + $this->fd = fopen($this->fn, "rb"); + } else { + $this->fd = fopen($this->fn, "wb"); + } + if (false === $this->fd) { + throw new Exception("Failed to open lock under '$this->fn'"); + } + $this->locked = flock($this->fd, $flags, $this->wouldBlock); + return $this->locked; + }/*}}}*/ + + public function unlock() : bool + {/*{{{*/ + if (!$this->locked) { + return true; + } + + $this->doLock(LOCK_UN); + + fclose($this->fd); + $this->fd = NULL; + + return $this->locked; + }/*}}}*/ + + public function locked() : bool + {/*{{{*/ + return $this->locked; + }/*}}}*/ + + public function wouldBlock() : bool + {/*{{{*/ + return 1 === $this->wouldBlock; + }/*}}}*/ +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/msys2/usr/bin/awk.exe b/msys2/usr/bin/awk.exe new file mode 100755 index 0000000..005a85b Binary files /dev/null and b/msys2/usr/bin/awk.exe differ diff --git a/msys2/usr/bin/bison.exe b/msys2/usr/bin/bison.exe new file mode 100755 index 0000000..873933d Binary files /dev/null and b/msys2/usr/bin/bison.exe differ diff --git a/msys2/usr/bin/bsdtar.exe b/msys2/usr/bin/bsdtar.exe new file mode 100755 index 0000000..c0de10e Binary files /dev/null and b/msys2/usr/bin/bsdtar.exe differ diff --git a/msys2/usr/bin/bzip2.exe b/msys2/usr/bin/bzip2.exe new file mode 100755 index 0000000..2cb9d06 Binary files /dev/null and b/msys2/usr/bin/bzip2.exe differ diff --git a/msys2/usr/bin/diff.exe b/msys2/usr/bin/diff.exe new file mode 100755 index 0000000..b6c3d1d Binary files /dev/null and b/msys2/usr/bin/diff.exe differ diff --git a/msys2/usr/bin/diff3.exe b/msys2/usr/bin/diff3.exe new file mode 100755 index 0000000..40fdba8 Binary files /dev/null and b/msys2/usr/bin/diff3.exe differ diff --git a/msys2/usr/bin/gawk.exe b/msys2/usr/bin/gawk.exe new file mode 100755 index 0000000..005a85b Binary files /dev/null and b/msys2/usr/bin/gawk.exe differ diff --git a/msys2/usr/bin/grep.exe b/msys2/usr/bin/grep.exe new file mode 100755 index 0000000..4be6039 Binary files /dev/null and b/msys2/usr/bin/grep.exe differ diff --git a/msys2/usr/bin/gzip.exe b/msys2/usr/bin/gzip.exe new file mode 100755 index 0000000..ba14ced Binary files /dev/null and b/msys2/usr/bin/gzip.exe differ diff --git a/msys2/usr/bin/m4.exe b/msys2/usr/bin/m4.exe new file mode 100755 index 0000000..100be51 Binary files /dev/null and b/msys2/usr/bin/m4.exe differ diff --git a/msys2/usr/bin/md5sum.exe b/msys2/usr/bin/md5sum.exe new file mode 100755 index 0000000..49146a7 Binary files /dev/null and b/msys2/usr/bin/md5sum.exe differ diff --git a/msys2/usr/bin/msys-2.0.dll b/msys2/usr/bin/msys-2.0.dll new file mode 100644 index 0000000..e72cb67 Binary files /dev/null and b/msys2/usr/bin/msys-2.0.dll differ diff --git a/msys2/usr/bin/msys-assuan-0.dll b/msys2/usr/bin/msys-assuan-0.dll new file mode 100644 index 0000000..4c10cf4 Binary files /dev/null and b/msys2/usr/bin/msys-assuan-0.dll differ diff --git a/msys2/usr/bin/msys-bz2-1.dll b/msys2/usr/bin/msys-bz2-1.dll new file mode 100644 index 0000000..ff7c4f7 Binary files /dev/null and b/msys2/usr/bin/msys-bz2-1.dll differ diff --git a/msys2/usr/bin/msys-crypto-1.0.0.dll b/msys2/usr/bin/msys-crypto-1.0.0.dll new file mode 100644 index 0000000..826673f Binary files /dev/null and b/msys2/usr/bin/msys-crypto-1.0.0.dll differ diff --git a/msys2/usr/bin/msys-expat-1.dll b/msys2/usr/bin/msys-expat-1.dll new file mode 100644 index 0000000..5f0bc04 Binary files /dev/null and b/msys2/usr/bin/msys-expat-1.dll differ diff --git a/msys2/usr/bin/msys-gcc_s-seh-1.dll b/msys2/usr/bin/msys-gcc_s-seh-1.dll new file mode 100755 index 0000000..0b2ce7c Binary files /dev/null and b/msys2/usr/bin/msys-gcc_s-seh-1.dll differ diff --git a/msys2/usr/bin/msys-gmp-10.dll b/msys2/usr/bin/msys-gmp-10.dll new file mode 100644 index 0000000..1edccd5 Binary files /dev/null and b/msys2/usr/bin/msys-gmp-10.dll differ diff --git a/msys2/usr/bin/msys-gpg-error-0.dll b/msys2/usr/bin/msys-gpg-error-0.dll new file mode 100644 index 0000000..081ff4b Binary files /dev/null and b/msys2/usr/bin/msys-gpg-error-0.dll differ diff --git a/msys2/usr/bin/msys-gpgme-11.dll b/msys2/usr/bin/msys-gpgme-11.dll new file mode 100644 index 0000000..b8dcd6f Binary files /dev/null and b/msys2/usr/bin/msys-gpgme-11.dll differ diff --git a/bin/libiconv2.dll b/msys2/usr/bin/msys-iconv-2.dll similarity index 51% rename from bin/libiconv2.dll rename to msys2/usr/bin/msys-iconv-2.dll index 544dd92..2a6c04c 100644 Binary files a/bin/libiconv2.dll and b/msys2/usr/bin/msys-iconv-2.dll differ diff --git a/msys2/usr/bin/msys-icudata62.dll b/msys2/usr/bin/msys-icudata62.dll new file mode 100644 index 0000000..5a03330 Binary files /dev/null and b/msys2/usr/bin/msys-icudata62.dll differ diff --git a/msys2/usr/bin/msys-icuuc62.dll b/msys2/usr/bin/msys-icuuc62.dll new file mode 100644 index 0000000..743781b Binary files /dev/null and b/msys2/usr/bin/msys-icuuc62.dll differ diff --git a/msys2/usr/bin/msys-idn-12.dll b/msys2/usr/bin/msys-idn-12.dll new file mode 100644 index 0000000..9437a48 Binary files /dev/null and b/msys2/usr/bin/msys-idn-12.dll differ diff --git a/msys2/usr/bin/msys-idn2-0.dll b/msys2/usr/bin/msys-idn2-0.dll new file mode 100644 index 0000000..cd87945 Binary files /dev/null and b/msys2/usr/bin/msys-idn2-0.dll differ diff --git a/msys2/usr/bin/msys-intl-8.dll b/msys2/usr/bin/msys-intl-8.dll new file mode 100644 index 0000000..affdcd7 Binary files /dev/null and b/msys2/usr/bin/msys-intl-8.dll differ diff --git a/msys2/usr/bin/msys-lz4-1.dll b/msys2/usr/bin/msys-lz4-1.dll new file mode 100644 index 0000000..41f74f0 Binary files /dev/null and b/msys2/usr/bin/msys-lz4-1.dll differ diff --git a/msys2/usr/bin/msys-lzma-5.dll b/msys2/usr/bin/msys-lzma-5.dll new file mode 100644 index 0000000..e7cc293 Binary files /dev/null and b/msys2/usr/bin/msys-lzma-5.dll differ diff --git a/msys2/usr/bin/msys-lzo2-2.dll b/msys2/usr/bin/msys-lzo2-2.dll new file mode 100644 index 0000000..3ce0335 Binary files /dev/null and b/msys2/usr/bin/msys-lzo2-2.dll differ diff --git a/msys2/usr/bin/msys-metalink-3.dll b/msys2/usr/bin/msys-metalink-3.dll new file mode 100644 index 0000000..67d4be1 Binary files /dev/null and b/msys2/usr/bin/msys-metalink-3.dll differ diff --git a/msys2/usr/bin/msys-mpfr-6.dll b/msys2/usr/bin/msys-mpfr-6.dll new file mode 100644 index 0000000..3534b93 Binary files /dev/null and b/msys2/usr/bin/msys-mpfr-6.dll differ diff --git a/msys2/usr/bin/msys-ncursesw6.dll b/msys2/usr/bin/msys-ncursesw6.dll new file mode 100644 index 0000000..c9cdab4 Binary files /dev/null and b/msys2/usr/bin/msys-ncursesw6.dll differ diff --git a/msys2/usr/bin/msys-nettle-6.dll b/msys2/usr/bin/msys-nettle-6.dll new file mode 100644 index 0000000..a1fa92e Binary files /dev/null and b/msys2/usr/bin/msys-nettle-6.dll differ diff --git a/msys2/usr/bin/msys-pcre-1.dll b/msys2/usr/bin/msys-pcre-1.dll new file mode 100644 index 0000000..09404a5 Binary files /dev/null and b/msys2/usr/bin/msys-pcre-1.dll differ diff --git a/msys2/usr/bin/msys-psl-5.dll b/msys2/usr/bin/msys-psl-5.dll new file mode 100644 index 0000000..34cbafe Binary files /dev/null and b/msys2/usr/bin/msys-psl-5.dll differ diff --git a/msys2/usr/bin/msys-readline7.dll b/msys2/usr/bin/msys-readline7.dll new file mode 100644 index 0000000..846b0d1 Binary files /dev/null and b/msys2/usr/bin/msys-readline7.dll differ diff --git a/msys2/usr/bin/msys-ssl-1.0.0.dll b/msys2/usr/bin/msys-ssl-1.0.0.dll new file mode 100644 index 0000000..a86e60c Binary files /dev/null and b/msys2/usr/bin/msys-ssl-1.0.0.dll differ diff --git a/msys2/usr/bin/msys-stdc++-6.dll b/msys2/usr/bin/msys-stdc++-6.dll new file mode 100644 index 0000000..7ca81fc Binary files /dev/null and b/msys2/usr/bin/msys-stdc++-6.dll differ diff --git a/msys2/usr/bin/msys-unistring-2.dll b/msys2/usr/bin/msys-unistring-2.dll new file mode 100644 index 0000000..42e81d2 Binary files /dev/null and b/msys2/usr/bin/msys-unistring-2.dll differ diff --git a/msys2/usr/bin/msys-uuid-1.dll b/msys2/usr/bin/msys-uuid-1.dll new file mode 100644 index 0000000..23a7d7d Binary files /dev/null and b/msys2/usr/bin/msys-uuid-1.dll differ diff --git a/msys2/usr/bin/msys-xml2-2.dll b/msys2/usr/bin/msys-xml2-2.dll new file mode 100644 index 0000000..e8693c6 Binary files /dev/null and b/msys2/usr/bin/msys-xml2-2.dll differ diff --git a/msys2/usr/bin/msys-z.dll b/msys2/usr/bin/msys-z.dll new file mode 100644 index 0000000..02a153d Binary files /dev/null and b/msys2/usr/bin/msys-z.dll differ diff --git a/msys2/usr/bin/patch.exe b/msys2/usr/bin/patch.exe new file mode 100755 index 0000000..c11b0be Binary files /dev/null and b/msys2/usr/bin/patch.exe differ diff --git a/msys2/usr/bin/pwgen.exe b/msys2/usr/bin/pwgen.exe new file mode 100755 index 0000000..c5a3f9c Binary files /dev/null and b/msys2/usr/bin/pwgen.exe differ diff --git a/msys2/usr/bin/re2c.exe b/msys2/usr/bin/re2c.exe new file mode 100755 index 0000000..157b4c0 Binary files /dev/null and b/msys2/usr/bin/re2c.exe differ diff --git a/msys2/usr/bin/sed.exe b/msys2/usr/bin/sed.exe new file mode 100755 index 0000000..21ab42b Binary files /dev/null and b/msys2/usr/bin/sed.exe differ diff --git a/msys2/usr/bin/sha1sum.exe b/msys2/usr/bin/sha1sum.exe new file mode 100755 index 0000000..b10dfe2 Binary files /dev/null and b/msys2/usr/bin/sha1sum.exe differ diff --git a/msys2/usr/bin/sha224sum.exe b/msys2/usr/bin/sha224sum.exe new file mode 100755 index 0000000..31cef78 Binary files /dev/null and b/msys2/usr/bin/sha224sum.exe differ diff --git a/msys2/usr/bin/sha256sum.exe b/msys2/usr/bin/sha256sum.exe new file mode 100755 index 0000000..a2c7a57 Binary files /dev/null and b/msys2/usr/bin/sha256sum.exe differ diff --git a/msys2/usr/bin/sha384sum.exe b/msys2/usr/bin/sha384sum.exe new file mode 100755 index 0000000..ec0c274 Binary files /dev/null and b/msys2/usr/bin/sha384sum.exe differ diff --git a/msys2/usr/bin/sha512sum.exe b/msys2/usr/bin/sha512sum.exe new file mode 100755 index 0000000..3412897 Binary files /dev/null and b/msys2/usr/bin/sha512sum.exe differ diff --git a/msys2/usr/bin/tar.exe b/msys2/usr/bin/tar.exe new file mode 100755 index 0000000..03a0792 Binary files /dev/null and b/msys2/usr/bin/tar.exe differ diff --git a/msys2/usr/bin/tee.exe b/msys2/usr/bin/tee.exe new file mode 100755 index 0000000..4d56e47 Binary files /dev/null and b/msys2/usr/bin/tee.exe differ diff --git a/msys2/usr/bin/unzip.exe b/msys2/usr/bin/unzip.exe new file mode 100755 index 0000000..9418410 Binary files /dev/null and b/msys2/usr/bin/unzip.exe differ diff --git a/msys2/usr/bin/unzipsfx.exe b/msys2/usr/bin/unzipsfx.exe new file mode 100755 index 0000000..507c9f4 Binary files /dev/null and b/msys2/usr/bin/unzipsfx.exe differ diff --git a/msys2/usr/bin/wget.exe b/msys2/usr/bin/wget.exe new file mode 100755 index 0000000..969cafc Binary files /dev/null and b/msys2/usr/bin/wget.exe differ diff --git a/msys2/usr/bin/xz.exe b/msys2/usr/bin/xz.exe new file mode 100755 index 0000000..d1a12c4 Binary files /dev/null and b/msys2/usr/bin/xz.exe differ diff --git a/msys2/usr/bin/zip.exe b/msys2/usr/bin/zip.exe new file mode 100755 index 0000000..e285725 Binary files /dev/null and b/msys2/usr/bin/zip.exe differ diff --git a/msys2/usr/etc/wgetrc b/msys2/usr/etc/wgetrc new file mode 100644 index 0000000..cb5f002 --- /dev/null +++ b/msys2/usr/etc/wgetrc @@ -0,0 +1,140 @@ +### +### Sample Wget initialization file .wgetrc +### + +## You can use this file to change the default behaviour of wget or to +## avoid having to type many many command-line options. This file does +## not contain a comprehensive list of commands -- look at the manual +## to find out what you can put into this file. You can find this here: +## $ info wget.info 'Startup File' +## Or online here: +## https://www.gnu.org/software/wget/manual/wget.html#Startup-File +## +## Wget initialization file can reside in /etc/wgetrc +## (global, for all users) or $HOME/.wgetrc (for a single user). +## +## To use the settings in this file, you will have to uncomment them, +## as well as change them, in most cases, as the values on the +## commented-out lines are the default values (e.g. "off"). +## +## Command are case-, underscore- and minus-insensitive. +## For example ftp_proxy, ftp-proxy and ftpproxy are the same. + + +## +## Global settings (useful for setting up in /etc/wgetrc). +## Think well before you change them, since they may reduce wget's +## functionality, and make it behave contrary to the documentation: +## + +# You can set retrieve quota for beginners by specifying a value +# optionally followed by 'K' (kilobytes) or 'M' (megabytes). The +# default quota is unlimited. +#quota = inf + +# You can lower (or raise) the default number of retries when +# downloading a file (default is 20). +#tries = 20 + +# Lowering the maximum depth of the recursive retrieval is handy to +# prevent newbies from going too "deep" when they unwittingly start +# the recursive retrieval. The default is 5. +#reclevel = 5 + +# By default Wget uses "passive FTP" transfer where the client +# initiates the data connection to the server rather than the other +# way around. That is required on systems behind NAT where the client +# computer cannot be easily reached from the Internet. However, some +# firewalls software explicitly supports active FTP and in fact has +# problems supporting passive transfer. If you are in such +# environment, use "passive_ftp = off" to revert to active FTP. +#passive_ftp = off + +# The "wait" command below makes Wget wait between every connection. +# If, instead, you want Wget to wait only between retries of failed +# downloads, set waitretry to maximum number of seconds to wait (Wget +# will use "linear backoff", waiting 1 second after the first failure +# on a file, 2 seconds after the second failure, etc. up to this max). +#waitretry = 10 + + +## +## Local settings (for a user to set in his $HOME/.wgetrc). It is +## *highly* undesirable to put these settings in the global file, since +## they are potentially dangerous to "normal" users. +## +## Even when setting up your own ~/.wgetrc, you should know what you +## are doing before doing so. +## + +# Set this to on to use timestamping by default: +#timestamping = off + +# It is a good idea to make Wget send your email address in a `From:' +# header with your request (so that server administrators can contact +# you in case of errors). Wget does *not* send `From:' by default. +#header = From: Your Name + +# You can set up other headers, like Accept-Language. Accept-Language +# is *not* sent by default. +#header = Accept-Language: en + +# You can set the default proxies for Wget to use for http, https, and ftp. +# They will override the value in the environment. +#https_proxy = http://proxy.yoyodyne.com:18023/ +#http_proxy = http://proxy.yoyodyne.com:18023/ +#ftp_proxy = http://proxy.yoyodyne.com:18023/ + +# If you do not want to use proxy at all, set this to off. +#use_proxy = on + +# You can customize the retrieval outlook. Valid options are default, +# binary, mega and micro. +#dot_style = default + +# Setting this to off makes Wget not download /robots.txt. Be sure to +# know *exactly* what /robots.txt is and how it is used before changing +# the default! +#robots = on + +# It can be useful to make Wget wait between connections. Set this to +# the number of seconds you want Wget to wait. +#wait = 0 + +# You can force creating directory structure, even if a single is being +# retrieved, by setting this to on. +#dirstruct = off + +# You can turn on recursive retrieving by default (don't do this if +# you are not sure you know what it means) by setting this to on. +#recursive = off + +# To always back up file X as X.orig before converting its links (due +# to -k / --convert-links / convert_links = on having been specified), +# set this variable to on: +#backup_converted = off + +# To have Wget follow FTP links from HTML files by default, set this +# to on: +#follow_ftp = off + +# To try ipv6 addresses first: +#prefer-family = IPv6 + +# Set default IRI support state +#iri = off + +# Force the default system encoding +#localencoding = UTF-8 + +# Force the default remote server encoding +#remoteencoding = UTF-8 + +# Turn on to prevent following non-HTTPS links when in recursive mode +#httpsonly = off + +# Tune HTTPS security (auto, SSLv2, SSLv3, TLSv1, PFS) +#secureprotocol = auto + +# default root certs location +ca_certificate=/usr/ssl/certs/ca-bundle.crt diff --git a/msys2/usr/lib/awk/grcat.exe b/msys2/usr/lib/awk/grcat.exe new file mode 100644 index 0000000..9265f31 Binary files /dev/null and b/msys2/usr/lib/awk/grcat.exe differ diff --git a/msys2/usr/lib/awk/pwcat.exe b/msys2/usr/lib/awk/pwcat.exe new file mode 100644 index 0000000..d8c805e Binary files /dev/null and b/msys2/usr/lib/awk/pwcat.exe differ diff --git a/msys2/usr/lib/gawk/filefuncs.dll b/msys2/usr/lib/gawk/filefuncs.dll new file mode 100644 index 0000000..33db710 Binary files /dev/null and b/msys2/usr/lib/gawk/filefuncs.dll differ diff --git a/msys2/usr/lib/gawk/fnmatch.dll b/msys2/usr/lib/gawk/fnmatch.dll new file mode 100644 index 0000000..21218d8 Binary files /dev/null and b/msys2/usr/lib/gawk/fnmatch.dll differ diff --git a/msys2/usr/lib/gawk/fork.dll b/msys2/usr/lib/gawk/fork.dll new file mode 100644 index 0000000..029fd41 Binary files /dev/null and b/msys2/usr/lib/gawk/fork.dll differ diff --git a/msys2/usr/lib/gawk/inplace.dll b/msys2/usr/lib/gawk/inplace.dll new file mode 100644 index 0000000..e4331e3 Binary files /dev/null and b/msys2/usr/lib/gawk/inplace.dll differ diff --git a/msys2/usr/lib/gawk/ordchr.dll b/msys2/usr/lib/gawk/ordchr.dll new file mode 100644 index 0000000..78ee9c4 Binary files /dev/null and b/msys2/usr/lib/gawk/ordchr.dll differ diff --git a/msys2/usr/lib/gawk/readdir.dll b/msys2/usr/lib/gawk/readdir.dll new file mode 100644 index 0000000..7a9172a Binary files /dev/null and b/msys2/usr/lib/gawk/readdir.dll differ diff --git a/msys2/usr/lib/gawk/readfile.dll b/msys2/usr/lib/gawk/readfile.dll new file mode 100644 index 0000000..0a01f8d Binary files /dev/null and b/msys2/usr/lib/gawk/readfile.dll differ diff --git a/msys2/usr/lib/gawk/revoutput.dll b/msys2/usr/lib/gawk/revoutput.dll new file mode 100644 index 0000000..ab33536 Binary files /dev/null and b/msys2/usr/lib/gawk/revoutput.dll differ diff --git a/msys2/usr/lib/gawk/revtwoway.dll b/msys2/usr/lib/gawk/revtwoway.dll new file mode 100644 index 0000000..9f302d5 Binary files /dev/null and b/msys2/usr/lib/gawk/revtwoway.dll differ diff --git a/msys2/usr/lib/gawk/rwarray.dll b/msys2/usr/lib/gawk/rwarray.dll new file mode 100644 index 0000000..65b3560 Binary files /dev/null and b/msys2/usr/lib/gawk/rwarray.dll differ diff --git a/msys2/usr/lib/gawk/testext.dll b/msys2/usr/lib/gawk/testext.dll new file mode 100644 index 0000000..d2fed5d Binary files /dev/null and b/msys2/usr/lib/gawk/testext.dll differ diff --git a/msys2/usr/lib/gawk/time.dll b/msys2/usr/lib/gawk/time.dll new file mode 100644 index 0000000..c1f8637 Binary files /dev/null and b/msys2/usr/lib/gawk/time.dll differ diff --git a/share/aclocal/bison-i18n.m4 b/msys2/usr/share/aclocal/bison-i18n.m4 similarity index 95% rename from share/aclocal/bison-i18n.m4 rename to msys2/usr/share/aclocal/bison-i18n.m4 index 7571712..a45df0d 100644 --- a/share/aclocal/bison-i18n.m4 +++ b/msys2/usr/share/aclocal/bison-i18n.m4 @@ -1,5 +1,8 @@ # bison-i18n.m4 serial 2 -dnl Copyright (C) 2005-2006 Free Software Foundation, Inc. + +dnl Copyright (C) 2005-2006, 2009-2015, 2018-2019 Free Software +dnl Foundation, Inc. + dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/msys2/usr/share/awk/assert.awk b/msys2/usr/share/awk/assert.awk new file mode 100644 index 0000000..c8e1349 --- /dev/null +++ b/msys2/usr/share/awk/assert.awk @@ -0,0 +1,20 @@ +# assert --- assert that a condition is true. Otherwise, exit. + +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# May, 1993 + +function assert(condition, string) +{ + if (! condition) { + printf("%s:%d: assertion failed: %s\n", + FILENAME, FNR, string) > "/dev/stderr" + _assert_exit = 1 + exit 1 + } +} + +END { + if (_assert_exit) + exit 1 +} diff --git a/msys2/usr/share/awk/bits2str.awk b/msys2/usr/share/awk/bits2str.awk new file mode 100644 index 0000000..5dddc1c --- /dev/null +++ b/msys2/usr/share/awk/bits2str.awk @@ -0,0 +1,16 @@ +# bits2str --- turn an integer into readable ones and zeros + +function bits2str(bits, data, mask) +{ + if (bits == 0) + return "0" + + mask = 1 + for (; bits != 0; bits = rshift(bits, 1)) + data = (and(bits, mask) ? "1" : "0") data + + while ((length(data) % 8) != 0) + data = "0" data + + return data +} diff --git a/msys2/usr/share/awk/cliff_rand.awk b/msys2/usr/share/awk/cliff_rand.awk new file mode 100644 index 0000000..e6a793a --- /dev/null +++ b/msys2/usr/share/awk/cliff_rand.awk @@ -0,0 +1,14 @@ +# cliff_rand.awk --- generate Cliff random numbers +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# December 2000 + +BEGIN { _cliff_seed = 0.1 } + +function cliff_rand() +{ + _cliff_seed = (100 * log(_cliff_seed)) % 1 + if (_cliff_seed < 0) + _cliff_seed = - _cliff_seed + return _cliff_seed +} diff --git a/msys2/usr/share/awk/ctime.awk b/msys2/usr/share/awk/ctime.awk new file mode 100644 index 0000000..cea25b7 --- /dev/null +++ b/msys2/usr/share/awk/ctime.awk @@ -0,0 +1,12 @@ +# ctime.awk +# +# awk version of C ctime(3) function + +function ctime(ts, format) +{ + format = "%a %b %e %H:%M:%S %Z %Y" + + if (ts == 0) + ts = systime() # use current time as default + return strftime(format, ts) +} diff --git a/msys2/usr/share/awk/ftrans.awk b/msys2/usr/share/awk/ftrans.awk new file mode 100644 index 0000000..6461eff --- /dev/null +++ b/msys2/usr/share/awk/ftrans.awk @@ -0,0 +1,15 @@ +# ftrans.awk --- handle datafile transitions +# +# user supplies beginfile() and endfile() functions +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# November 1992 + +FNR == 1 { + if (_filename_ != "") + endfile(_filename_) + _filename_ = FILENAME + beginfile(FILENAME) +} + +END { endfile(_filename_) } diff --git a/msys2/usr/share/awk/getopt.awk b/msys2/usr/share/awk/getopt.awk new file mode 100644 index 0000000..6b1f4c5 --- /dev/null +++ b/msys2/usr/share/awk/getopt.awk @@ -0,0 +1,79 @@ +# getopt.awk --- Do C library getopt(3) function in awk +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# +# Initial version: March, 1991 +# Revised: May, 1993 + +# External variables: +# Optind -- index in ARGV of first nonoption argument +# Optarg -- string value of argument to current option +# Opterr -- if nonzero, print our own diagnostic +# Optopt -- current option letter + +# Returns: +# -1 at end of options +# "?" for unrecognized option +# a character representing the current option + +# Private Data: +# _opti -- index in multiflag option, e.g., -abc +function getopt(argc, argv, options, thisopt, i) +{ + if (length(options) == 0) # no options given + return -1 + + if (argv[Optind] == "--") { # all done + Optind++ + _opti = 0 + return -1 + } else if (argv[Optind] !~ /^-[^:[:space:]]/) { + _opti = 0 + return -1 + } + if (_opti == 0) + _opti = 2 + thisopt = substr(argv[Optind], _opti, 1) + Optopt = thisopt + i = index(options, thisopt) + if (i == 0) { + if (Opterr) + printf("%c -- invalid option\n", thisopt) > "/dev/stderr" + if (_opti >= length(argv[Optind])) { + Optind++ + _opti = 0 + } else + _opti++ + return "?" + } + if (substr(options, i + 1, 1) == ":") { + # get option argument + if (length(substr(argv[Optind], _opti + 1)) > 0) + Optarg = substr(argv[Optind], _opti + 1) + else + Optarg = argv[++Optind] + _opti = 0 + } else + Optarg = "" + if (_opti == 0 || _opti >= length(argv[Optind])) { + Optind++ + _opti = 0 + } else + _opti++ + return thisopt +} +BEGIN { + Opterr = 1 # default is to diagnose + Optind = 1 # skip ARGV[0] + + # test program + if (_getopt_test) { + while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1) + printf("c = <%c>, Optarg = <%s>\n", + _go_c, Optarg) + printf("non-option arguments:\n") + for (; Optind < ARGC; Optind++) + printf("\tARGV[%d] = <%s>\n", + Optind, ARGV[Optind]) + } +} diff --git a/msys2/usr/share/awk/gettime.awk b/msys2/usr/share/awk/gettime.awk new file mode 100644 index 0000000..4cb5633 --- /dev/null +++ b/msys2/usr/share/awk/gettime.awk @@ -0,0 +1,62 @@ +# getlocaltime.awk --- get the time of day in a usable format +# +# Arnold Robbins, arnold@skeeve.com, Public Domain, May 1993 +# + +# Returns a string in the format of output of date(1) +# Populates the array argument time with individual values: +# time["second"] -- seconds (0 - 59) +# time["minute"] -- minutes (0 - 59) +# time["hour"] -- hours (0 - 23) +# time["althour"] -- hours (0 - 12) +# time["monthday"] -- day of month (1 - 31) +# time["month"] -- month of year (1 - 12) +# time["monthname"] -- name of the month +# time["shortmonth"] -- short name of the month +# time["year"] -- year modulo 100 (0 - 99) +# time["fullyear"] -- full year +# time["weekday"] -- day of week (Sunday = 0) +# time["altweekday"] -- day of week (Monday = 0) +# time["dayname"] -- name of weekday +# time["shortdayname"] -- short name of weekday +# time["yearday"] -- day of year (0 - 365) +# time["timezone"] -- abbreviation of timezone name +# time["ampm"] -- AM or PM designation +# time["weeknum"] -- week number, Sunday first day +# time["altweeknum"] -- week number, Monday first day + +function getlocaltime(time, ret, now, i) +{ + # get time once, avoids unnecessary system calls + now = systime() + + # return date(1)-style output + ret = strftime("%a %b %e %H:%M:%S %Z %Y", now) + + # clear out target array + delete time + + # fill in values, force numeric values to be + # numeric by adding 0 + time["second"] = strftime("%S", now) + 0 + time["minute"] = strftime("%M", now) + 0 + time["hour"] = strftime("%H", now) + 0 + time["althour"] = strftime("%I", now) + 0 + time["monthday"] = strftime("%d", now) + 0 + time["month"] = strftime("%m", now) + 0 + time["monthname"] = strftime("%B", now) + time["shortmonth"] = strftime("%b", now) + time["year"] = strftime("%y", now) + 0 + time["fullyear"] = strftime("%Y", now) + 0 + time["weekday"] = strftime("%w", now) + 0 + time["altweekday"] = strftime("%u", now) + 0 + time["dayname"] = strftime("%A", now) + time["shortdayname"] = strftime("%a", now) + time["yearday"] = strftime("%j", now) + 0 + time["timezone"] = strftime("%Z", now) + time["ampm"] = strftime("%p", now) + time["weeknum"] = strftime("%U", now) + 0 + time["altweeknum"] = strftime("%W", now) + 0 + + return ret +} diff --git a/msys2/usr/share/awk/group.awk b/msys2/usr/share/awk/group.awk new file mode 100644 index 0000000..e85d215 --- /dev/null +++ b/msys2/usr/share/awk/group.awk @@ -0,0 +1,83 @@ +# group.awk --- functions for dealing with the group file +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# May 1993 +# Revised October 2000 +# Revised December 2010 + +BEGIN { + # Change to suit your system + _gr_awklib = "/usr/lib/awk/" +} + +function _gr_init( oldfs, oldrs, olddol0, grcat, + using_fw, using_fpat, n, a, i) +{ + if (_gr_inited) + return + + oldfs = FS + oldrs = RS + olddol0 = $0 + using_fw = (PROCINFO["FS"] == "FIELDWIDTHS") + using_fpat = (PROCINFO["FS"] == "FPAT") + FS = ":" + RS = "\n" + + grcat = _gr_awklib "grcat" + while ((grcat | getline) > 0) { + if ($1 in _gr_byname) + _gr_byname[$1] = _gr_byname[$1] "," $4 + else + _gr_byname[$1] = $0 + if ($3 in _gr_bygid) + _gr_bygid[$3] = _gr_bygid[$3] "," $4 + else + _gr_bygid[$3] = $0 + + n = split($4, a, "[ \t]*,[ \t]*") + for (i = 1; i <= n; i++) + if (a[i] in _gr_groupsbyuser) + _gr_groupsbyuser[a[i]] = _gr_groupsbyuser[a[i]] " " $1 + else + _gr_groupsbyuser[a[i]] = $1 + + _gr_bycount[++_gr_count] = $0 + } + close(grcat) + _gr_count = 0 + _gr_inited++ + FS = oldfs + if (using_fw) + FIELDWIDTHS = FIELDWIDTHS + else if (using_fpat) + FPAT = FPAT + RS = oldrs + $0 = olddol0 +} +function getgrnam(group) +{ + _gr_init() + return _gr_byname[group] +} +function getgrgid(gid) +{ + _gr_init() + return _gr_bygid[gid] +} +function getgruser(user) +{ + _gr_init() + return _gr_groupsbyuser[user] +} +function getgrent() +{ + _gr_init() + if (++_gr_count in _gr_bycount) + return _gr_bycount[_gr_count] + return "" +} +function endgrent() +{ + _gr_count = 0 +} diff --git a/msys2/usr/share/awk/inplace.awk b/msys2/usr/share/awk/inplace.awk new file mode 100644 index 0000000..6771bc4 --- /dev/null +++ b/msys2/usr/share/awk/inplace.awk @@ -0,0 +1,55 @@ +# inplace --- load and invoke the inplace extension. +# +# Copyright (C) 2013, 2017 the Free Software Foundation, Inc. +# +# This file is part of GAWK, the GNU implementation of the +# AWK Programming Language. +# +# GAWK is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# GAWK is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +# Andrew J. Schorr, aschorr@telemetry-investments.com +# January 2013 + +@load "inplace" + +# Please set INPLACE_SUFFIX to make a backup copy. For example, you may +# want to set INPLACE_SUFFIX to .bak on the command line or in a BEGIN rule. + +# By default, each filename on the command line will be edited inplace. +# But you can selectively disable this by adding an inplace=0 argument +# prior to files that you do not want to process this way. You can then +# reenable it later on the commandline by putting inplace=1 before files +# that you wish to be subject to inplace editing. + +# N.B. We call inplace_end() in the BEGINFILE and END rules so that any +# actions in an ENDFILE rule will be redirected as expected. + +BEGIN { + inplace = 1 # enabled by default +} + +BEGINFILE { + if (_inplace_filename != "") + inplace_end(_inplace_filename, INPLACE_SUFFIX) + if (inplace) + inplace_begin(_inplace_filename = FILENAME, INPLACE_SUFFIX) + else + _inplace_filename = "" +} + +END { + if (_inplace_filename != "") + inplace_end(_inplace_filename, INPLACE_SUFFIX) +} diff --git a/msys2/usr/share/awk/join.awk b/msys2/usr/share/awk/join.awk new file mode 100644 index 0000000..4a4ac92 --- /dev/null +++ b/msys2/usr/share/awk/join.awk @@ -0,0 +1,16 @@ +# join.awk --- join an array into a string +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# May 1993 + +function join(array, start, end, sep, result, i) +{ + if (sep == "") + sep = " " + else if (sep == SUBSEP) # magic value + sep = "" + result = array[start] + for (i = start + 1; i <= end; i++) + result = result sep array[i] + return result +} diff --git a/msys2/usr/share/awk/libintl.awk b/msys2/usr/share/awk/libintl.awk new file mode 100644 index 0000000..7efd2b4 --- /dev/null +++ b/msys2/usr/share/awk/libintl.awk @@ -0,0 +1,14 @@ +function bindtextdomain(dir, domain) +{ + return dir +} + +function dcgettext(string, domain, category) +{ + return string +} + +function dcngettext(string1, string2, number, domain, category) +{ + return (number == 1 ? string1 : string2) +} diff --git a/msys2/usr/share/awk/noassign.awk b/msys2/usr/share/awk/noassign.awk new file mode 100644 index 0000000..99227b3 --- /dev/null +++ b/msys2/usr/share/awk/noassign.awk @@ -0,0 +1,17 @@ +# noassign.awk --- library file to avoid the need for a +# special option that disables command-line assignments +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# October 1999 + +function disable_assigns(argc, argv, i) +{ + for (i = 1; i < argc; i++) + if (argv[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/) + argv[i] = ("./" argv[i]) +} + +BEGIN { + if (No_command_assign) + disable_assigns(ARGC, ARGV) +} diff --git a/msys2/usr/share/awk/ord.awk b/msys2/usr/share/awk/ord.awk new file mode 100644 index 0000000..be47e15 --- /dev/null +++ b/msys2/usr/share/awk/ord.awk @@ -0,0 +1,44 @@ +# ord.awk --- do ord and chr + +# Global identifiers: +# _ord_: numerical values indexed by characters +# _ord_init: function to initialize _ord_ +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# 16 January, 1992 +# 20 July, 1992, revised + +BEGIN { _ord_init() } + +function _ord_init( low, high, i, t) +{ + low = sprintf("%c", 7) # BEL is ascii 7 + if (low == "\a") { # regular ascii + low = 0 + high = 127 + } else if (sprintf("%c", 128 + 7) == "\a") { + # ascii, mark parity + low = 128 + high = 255 + } else { # ebcdic(!) + low = 0 + high = 255 + } + + for (i = low; i <= high; i++) { + t = sprintf("%c", i) + _ord_[t] = i + } +} +function ord(str, c) +{ + # only first character is of interest + c = substr(str, 1, 1) + return _ord_[c] +} + +function chr(c) +{ + # force c to be numeric by adding 0 + return sprintf("%c", c + 0) +} diff --git a/msys2/usr/share/awk/passwd.awk b/msys2/usr/share/awk/passwd.awk new file mode 100644 index 0000000..676045f --- /dev/null +++ b/msys2/usr/share/awk/passwd.awk @@ -0,0 +1,63 @@ +# passwd.awk --- access password file information +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# May 1993 +# Revised October 2000 +# Revised December 2010 + +BEGIN { + # tailor this to suit your system + _pw_awklib = "/usr/lib/awk/" +} + +function _pw_init( oldfs, oldrs, olddol0, pwcat, using_fw, using_fpat) +{ + if (_pw_inited) + return + + oldfs = FS + oldrs = RS + olddol0 = $0 + using_fw = (PROCINFO["FS"] == "FIELDWIDTHS") + using_fpat = (PROCINFO["FS"] == "FPAT") + FS = ":" + RS = "\n" + + pwcat = _pw_awklib "pwcat" + while ((pwcat | getline) > 0) { + _pw_byname[$1] = $0 + _pw_byuid[$3] = $0 + _pw_bycount[++_pw_total] = $0 + } + close(pwcat) + _pw_count = 0 + _pw_inited = 1 + FS = oldfs + if (using_fw) + FIELDWIDTHS = FIELDWIDTHS + else if (using_fpat) + FPAT = FPAT + RS = oldrs + $0 = olddol0 +} +function getpwnam(name) +{ + _pw_init() + return _pw_byname[name] +} +function getpwuid(uid) +{ + _pw_init() + return _pw_byuid[uid] +} +function getpwent() +{ + _pw_init() + if (_pw_count < _pw_total) + return _pw_bycount[++_pw_count] + return "" +} +function endpwent() +{ + _pw_count = 0 +} diff --git a/msys2/usr/share/awk/processarray.awk b/msys2/usr/share/awk/processarray.awk new file mode 100644 index 0000000..79a86d1 --- /dev/null +++ b/msys2/usr/share/awk/processarray.awk @@ -0,0 +1,12 @@ +function process_array(arr, name, process, do_arrays, i, new_name) +{ + for (i in arr) { + new_name = (name "[" i "]") + if (isarray(arr[i])) { + if (do_arrays) + @process(new_name, arr[i]) + process_array(arr[i], new_name, process, do_arrays) + } else + @process(new_name, arr[i]) + } +} diff --git a/msys2/usr/share/awk/quicksort.awk b/msys2/usr/share/awk/quicksort.awk new file mode 100644 index 0000000..e0ed8bc --- /dev/null +++ b/msys2/usr/share/awk/quicksort.awk @@ -0,0 +1,35 @@ +# quicksort.awk --- Quicksort algorithm, with user-supplied +# comparison function +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# January 2009 + + +# quicksort --- C.A.R. Hoare's quicksort algorithm. See Wikipedia +# or almost any algorithms or computer science text. +# +# Adapted from K&R-II, page 110 + +function quicksort(data, left, right, less_than, i, last) +{ + if (left >= right) # do nothing if array contains fewer + return # than two elements + + quicksort_swap(data, left, int((left + right) / 2)) + last = left + for (i = left + 1; i <= right; i++) + if (@less_than(data[i], data[left])) + quicksort_swap(data, ++last, i) + quicksort_swap(data, left, last) + quicksort(data, left, last - 1, less_than) + quicksort(data, last + 1, right, less_than) +} + +# quicksort_swap --- helper function for quicksort, should really be inline + +function quicksort_swap(data, i, j, temp) +{ + temp = data[i] + data[i] = data[j] + data[j] = temp +} diff --git a/msys2/usr/share/awk/readable.awk b/msys2/usr/share/awk/readable.awk new file mode 100644 index 0000000..37970a8 --- /dev/null +++ b/msys2/usr/share/awk/readable.awk @@ -0,0 +1,17 @@ +# readable.awk --- library file to skip over unreadable files +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# October 2000 +# December 2010 + +BEGIN { + for (i = 1; i < ARGC; i++) { + if (ARGV[i] ~ /^[a-zA-Z_][a-zA-Z0-9_]*=.*/ \ + || ARGV[i] == "-" || ARGV[i] == "/dev/stdin") + continue # assignment or standard input + else if ((getline junk < ARGV[i]) < 0) # unreadable + delete ARGV[i] + else + close(ARGV[i]) + } +} diff --git a/msys2/usr/share/awk/readfile.awk b/msys2/usr/share/awk/readfile.awk new file mode 100644 index 0000000..9137b26 --- /dev/null +++ b/msys2/usr/share/awk/readfile.awk @@ -0,0 +1,15 @@ +# readfile.awk --- read an entire file at once +# +# Original idea by Denis Shirokov, cosmogen@gmail.com, April 2013 +# + +function readfile(file, tmp, save_rs) +{ + save_rs = RS + RS = "^$" + getline tmp < file + close(file) + RS = save_rs + + return tmp +} diff --git a/msys2/usr/share/awk/rewind.awk b/msys2/usr/share/awk/rewind.awk new file mode 100644 index 0000000..a646eac --- /dev/null +++ b/msys2/usr/share/awk/rewind.awk @@ -0,0 +1,20 @@ +# rewind.awk --- rewind the current file and start over +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# September 2000 + +function rewind( i) +{ + # shift remaining arguments up + for (i = ARGC; i > ARGIND; i--) + ARGV[i] = ARGV[i-1] + + # make sure gawk knows to keep going + ARGC++ + + # make current file next to get done + ARGV[ARGIND+1] = FILENAME + + # do it + nextfile +} diff --git a/msys2/usr/share/awk/round.awk b/msys2/usr/share/awk/round.awk new file mode 100644 index 0000000..899645f --- /dev/null +++ b/msys2/usr/share/awk/round.awk @@ -0,0 +1,29 @@ +# round.awk --- do normal rounding +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# August, 1996 + +function round(x, ival, aval, fraction) +{ + ival = int(x) # integer part, int() truncates + + # see if fractional part + if (ival == x) # no fraction + return ival # ensure no decimals + + if (x < 0) { + aval = -x # absolute value + ival = int(aval) + fraction = aval - ival + if (fraction >= .5) + return int(x) - 1 # -2.5 --> -3 + else + return int(x) # -2.3 --> -2 + } else { + fraction = x - ival + if (fraction >= .5) + return ival + 1 + else + return ival + } +} diff --git a/msys2/usr/share/awk/shellquote.awk b/msys2/usr/share/awk/shellquote.awk new file mode 100644 index 0000000..cd943dc --- /dev/null +++ b/msys2/usr/share/awk/shellquote.awk @@ -0,0 +1,22 @@ +# shell_quote --- quote an argument for passing to the shell +# +# Michael Brennan +# brennan@madronabluff.com +# September 2014 + +function shell_quote(s, # parameter + SINGLE, QSINGLE, i, X, n, ret) # locals +{ + if (s == "") + return "\"\"" + + SINGLE = "\x27" # single quote + QSINGLE = "\"\x27\"" + n = split(s, X, SINGLE) + + ret = SINGLE X[1] SINGLE + for (i = 2; i <= n; i++) + ret = ret QSINGLE SINGLE X[i] SINGLE + + return ret +} diff --git a/msys2/usr/share/awk/strtonum.awk b/msys2/usr/share/awk/strtonum.awk new file mode 100644 index 0000000..783496e --- /dev/null +++ b/msys2/usr/share/awk/strtonum.awk @@ -0,0 +1,58 @@ +# mystrtonum --- convert string to number + +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# February, 2004 +# Revised June, 2014 + +function mystrtonum(str, ret, n, i, k, c) +{ + if (str ~ /^0[0-7]*$/) { + # octal + n = length(str) + ret = 0 + for (i = 1; i <= n; i++) { + c = substr(str, i, 1) + # index() returns 0 if c not in string, + # includes c == "0" + k = index("1234567", c) + + ret = ret * 8 + k + } + } else if (str ~ /^0[xX][[:xdigit:]]+$/) { + # hexadecimal + str = substr(str, 3) # lop off leading 0x + n = length(str) + ret = 0 + for (i = 1; i <= n; i++) { + c = substr(str, i, 1) + c = tolower(c) + # index() returns 0 if c not in string, + # includes c == "0" + k = index("123456789abcdef", c) + + ret = ret * 16 + k + } + } else if (str ~ \ + /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) { + # decimal number, possibly floating point + ret = str + 0 + } else + ret = "NOT-A-NUMBER" + + return ret +} + +# BEGIN { # gawk test harness +# a[1] = "25" +# a[2] = ".31" +# a[3] = "0123" +# a[4] = "0xdeadBEEF" +# a[5] = "123.45" +# a[6] = "1.e3" +# a[7] = "1.32" +# a[8] = "1.32E2" +# +# for (i = 1; i in a; i++) +# print a[i], strtonum(a[i]), mystrtonum(a[i]) +# } diff --git a/msys2/usr/share/awk/walkarray.awk b/msys2/usr/share/awk/walkarray.awk new file mode 100644 index 0000000..5e36f46 --- /dev/null +++ b/msys2/usr/share/awk/walkarray.awk @@ -0,0 +1,9 @@ +function walk_array(arr, name, i) +{ + for (i in arr) { + if (isarray(arr[i])) + walk_array(arr[i], (name "[" i "]")) + else + printf("%s[%s] = %s\n", name, i, arr[i]) + } +} diff --git a/msys2/usr/share/awk/zerofile.awk b/msys2/usr/share/awk/zerofile.awk new file mode 100644 index 0000000..8ea549c --- /dev/null +++ b/msys2/usr/share/awk/zerofile.awk @@ -0,0 +1,19 @@ +# zerofile.awk --- library file to process empty input files +# +# Arnold Robbins, arnold@skeeve.com, Public Domain +# June 2003 + +BEGIN { Argind = 0 } + +ARGIND > Argind + 1 { + for (Argind++; Argind < ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +} + +ARGIND != Argind { Argind = ARGIND } + +END { + if (ARGIND > Argind) + for (Argind++; Argind <= ARGIND; Argind++) + zerofile(ARGV[Argind], Argind) +} diff --git a/msys2/usr/share/bison/README b/msys2/usr/share/bison/README new file mode 100644 index 0000000..ed21736 --- /dev/null +++ b/msys2/usr/share/bison/README @@ -0,0 +1,191 @@ +This directory contains data needed by Bison. + +# Directory content +## Skeletons +Bison skeletons: the general shapes of the different parser kinds, that are +specialized for specific grammars by the bison program. + +Currently, the supported skeletons are: + +- yacc.c + It used to be named bison.simple: it corresponds to C Yacc + compatible LALR(1) parsers. + +- lalr1.cc + Produces a C++ parser class. + +- lalr1.java + Produces a Java parser class. + +- glr.c + A Generalized LR C parser based on Bison's LALR(1) tables. + +- glr.cc + A Generalized LR C++ parser. Actually a C++ wrapper around glr.c. + +These skeletons are the only ones supported by the Bison team. Because the +interface between skeletons and the bison program is not finished, *we are +not bound to it*. In particular, Bison is not mature enough for us to +consider that "foreign skeletons" are supported. + +## m4sugar +This directory contains M4sugar, sort of an extended library for M4, which +is used by Bison to instantiate the skeletons. + +## xslt +This directory contains XSLT programs that transform Bison's XML output into +various formats. + +- bison.xsl + A library of routines used by the other XSLT programs. + +- xml2dot.xsl + Conversion into GraphViz's dot format. + +- xml2text.xsl + Conversion into text. + +- xml2xhtml.xsl + Conversion into XHTML. + +# Implementation note about the skeletons + +"Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison +executable with LR tables, facts about the symbols, etc. and they generate +the output (say parser.cc, parser.hh, location.hh, etc.). They are only in +charge of generating the parser and its auxiliary files, they do not +generate the XML output, the parser.output reports, nor the graphical +rendering. + +The bits of information passing from bison to the backend is named +"muscles". Muscles are passed to M4 via its standard input: it's a set of +m4 definitions. To see them, use `--trace=muscles`. + +Except for muscles, whose names are generated by bison, the skeletons have +no constraint at all on the macro names: there is no technical/theoretical +limitation, as long as you generate the output, you can do what you want. +However, of course, that would be a bad idea if, say, the C and C++ +skeletons used different approaches and had completely different +implementations. That would be a maintenance nightmare. + +Below, we document some of the macros that we use in several of the +skeletons. If you are to write a new skeleton, please, implement them for +your language. Overall, be sure to follow the same patterns as the existing +skeletons. + +## Symbols + +### `b4_symbol(NUM, FIELD)` +In order to unify the handling of the various aspects of symbols (tag, type +name, whether terminal, etc.), bison.exe defines one macro per (token, +field), where field can `has_id`, `id`, etc.: see +`prepare_symbols_definitions()` in `src/output.c`. + +The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS: + +- `has_id`: 0 or 1. + + Whether the symbol has an id. + +- `id`: string + If has_id, the id (prefixed by api.token.prefix if defined), otherwise + defined as empty. Guaranteed to be usable as a C identifier. + +- `tag`: string. + A representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc. + +- `user_number`: integer + The external number as used by yylex. Can be ASCII code when a character, + some number chosen by bison, or some user number in the case of + %token FOO . Corresponds to yychar in yacc.c. + +- `is_token`: 0 or 1 + Whether this is a terminal symbol. + +- `number`: integer + The internal number (computed from the external number by yytranslate). + Corresponds to yytoken in yacc.c. This is the same number that serves as + key in b4_symbol(NUM, FIELD). + + In bison, symbols are first assigned increasing numbers in order of + appearance (but tokens first, then nterms). After grammar reduction, + unused nterms are then renumbered to appear last (i.e., first tokens, then + used nterms and finally unused nterms). This final number NUM is the one + contained in this field, and it is the one used as key in `b4_symbol(NUM, + FIELD)`. + + The code of the rule actions, however, is emitted before we know what + symbols are unused, so they use the original numbers. To avoid confusion, + they actually use "orig NUM" instead of just "NUM". bison also emits + definitions for `b4_symbol(orig NUM, number)` that map from original + numbers to the new ones. `b4_symbol` actually resolves `orig NUM` in the + other case, i.e., `b4_symbol(orig 42, tag)` would return the tag of the + symbols whose original number was 42. + +- `has_type`: 0, 1 + Whether has a semantic value. + +- `type_tag`: string + When api.value.type=union, the generated name for the union member. + yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc. + +- `type` + If it has a semantic value, its type tag, or, if variant are used, + its type. + In the case of api.value.type=union, type is the real type (e.g. int). + +- `has_printer`: 0, 1 +- `printer`: string +- `printer_file`: string +- `printer_line`: integer + If the symbol has a printer, everything about it. + +- `has_destructor`, `destructor`, `destructor_file`, `destructor_line` + Likewise. + +### `b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])` +Expansion of $$, $1, $3, etc. + +The semantic value from a given VAL. +- `VAL`: some semantic value storage (typically a union). e.g., `yylval` +- `SYMBOL-NUM`: the symbol number from which we extract the type tag. +- `TYPE-TAG`, the user forced the ``. + +The result can be used safely, it is put in parens to avoid nasty precedence +issues. + +### `b4_lhs_value(SYMBOL-NUM, [TYPE])` +Expansion of `$$` or `$$`, for symbol `SYMBOL-NUM`. + +### `b4_rhs_data(RULE-LENGTH, POS)` +The data corresponding to the symbol `#POS`, where the current rule has +`RULE-LENGTH` symbols on RHS. + +### `b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])` +Expansion of `$POS`, where the current rule has `RULE-LENGTH` symbols +on RHS. + +----- + +Local Variables: +mode: markdown +fill-column: 76 +ispell-dictionary: "american" +End: + +Copyright (C) 2002, 2008-2015, 2018-2019 Free Software Foundation, Inc. + +This file is part of GNU Bison. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/share/bison/m4sugar/foreach.m4 b/msys2/usr/share/bison/m4sugar/foreach.m4 similarity index 56% rename from share/bison/m4sugar/foreach.m4 rename to msys2/usr/share/bison/m4sugar/foreach.m4 index cd4d1fc..7093d0f 100644 --- a/share/bison/m4sugar/foreach.m4 +++ b/msys2/usr/share/bison/m4sugar/foreach.m4 @@ -4,11 +4,12 @@ # Speeds up GNU M4 1.4.x by avoiding quadratic $@ recursion, but penalizes # GNU M4 1.6 by requiring more memory and macro expansions. # -# Copyright (C) 2008 Free Software Foundation, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or +# Copyright (C) 2008-2017 Free Software Foundation, Inc. + +# This file is part of Autoconf. This program is free +# software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -16,38 +17,16 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception, the Free Software Foundation gives unlimited -# permission to copy, distribute and modify the configure scripts that -# are the output of Autoconf. You need not follow the terms of the GNU -# General Public License when using or distributing such scripts, even -# though portions of the text of Autoconf appear in them. The GNU -# General Public License (GPL) does govern all other use of the material -# that constitutes the Autoconf program. -# -# Certain portions of the Autoconf source text are designed to be copied -# (in certain cases, depending on the input) into the output of -# Autoconf. We call these the "data" portions. The rest of the Autoconf -# source text consists of comments plus executable code that decides which -# of the data portions to output in any given case. We call these -# comments and executable code the "non-data" portions. Autoconf never -# copies any of the non-data portions into its output. -# -# This special exception to the GPL applies to versions of Autoconf -# released by the Free Software Foundation. When you make and -# distribute a modified version of Autoconf, you may extend this special -# exception to the GPL to apply to your modified version as well, *unless* -# your modified version has the potential to copy into its output some -# of the text that was the non-data portion of the version that you started -# with. (In other words, unless your change moves or copies text from -# the non-data portions to the data portions.) If your modification has -# such potential, you must delete any notice of this special exception -# to the GPL from your modified version. +# Under Section 7 of GPL version 3, you are granted additional +# permissions described in the Autoconf Configure Script Exception, +# version 3.0, as published by the Free Software Foundation. # +# You should have received a copy of the GNU General Public License +# and a copy of the Autoconf Configure Script Exception along with +# this program; see the files COPYINGv3 and COPYING.EXCEPTION +# respectively. If not, see . + # Written by Eric Blake. -# # In M4 1.4.x, every byte of $@ is rescanned. This means that an # algorithm on n arguments that recurses with one less argument each @@ -77,29 +56,29 @@ # # Please keep this file in sync with m4sugar.m4. -# m4_foreach(VARIABLE, LIST, EXPRESSION) -# -------------------------------------- -# Expand EXPRESSION assigning each value of the LIST to VARIABLE. -# LIST should have the form `item_1, item_2, ..., item_n', i.e. the -# whole list must *quoted*. Quote members too if you don't want them -# to be expanded. +# _m4_foreach(PRE, POST, IGNORED, ARG...) +# --------------------------------------- +# Form the common basis of the m4_foreach and m4_map macros. For each +# ARG, expand PRE[ARG]POST[]. The IGNORED argument makes recursion +# easier, and must be supplied rather than implicit. # # This version minimizes the number of times that $@ is evaluated by -# using m4_for to generate a boilerplate into VARIABLE then passing $@ -# to that temporary macro. Thus, the recursion is done in m4_for -# without reparsing any user input, and is not quadratic. For an idea -# of how this works, note that m4_foreach(i,[1,2],[i]) defines i to be -# m4_define([$1],[$3])$2[]m4_define([$1],[$4])$2[]m4_popdef([i]) -# then calls i([i],[i],[1],[2]). -m4_define([m4_foreach], -[m4_if([$2], [], [], [_$0([$1], [$3], $2)])]) - +# using m4_for to generate a boilerplate into _m4_f then passing $@ to +# that temporary macro. Thus, the recursion is done in m4_for without +# reparsing any user input, and is not quadratic. For an idea of how +# this works, note that m4_foreach(i,[1,2],[i]) calls +# _m4_foreach([m4_define([i],],[)i],[],[1],[2]) +# which defines _m4_f: +# $1[$4]$2[]$1[$5]$2[]_m4_popdef([_m4_f]) +# then calls _m4_f([m4_define([i],],[)i],[],[1],[2]) for a net result: +# m4_define([i],[1])i[]m4_define([i],[2])i[]_m4_popdef([_m4_f]). m4_define([_m4_foreach], -[m4_define([$1], m4_pushdef([$1])_m4_for([$1], [3], [$#], [1], - [$0_([1], [2], _m4_defn([$1]))])[m4_popdef([$1])])m4_indir([$1], $@)]) +[m4_if([$#], [3], [], + [m4_pushdef([_m4_f], _m4_for([4], [$#], [1], + [$0_([1], [2],], [)])[_m4_popdef([_m4_f])])_m4_f($@)])]) m4_define([_m4_foreach_], -[[m4_define([$$1], [$$3])$$2[]]]) +[[$$1[$$3]$$2[]]]) # m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT) # ----------------------------------------------------------- @@ -114,11 +93,14 @@ m4_define([_m4_foreach_], # m4_if([$1],[$2],[$3],[$1],[$4],[$5],_m4_popdef([_m4_case])[$6]) m4_define([m4_case], [m4_if(m4_eval([$# <= 2]), [1], [$2], -[m4_pushdef([_$0], [m4_if(]m4_for([_m4_count], [2], m4_decr([$#]), [2], - [_$0_([1], _m4_count, m4_incr(_m4_count))])[_m4_popdef( +[m4_pushdef([_$0], [m4_if(]_m4_for([2], m4_eval([($# - 1) / 2 * 2]), [2], + [_$0_(], [)])[_m4_popdef( [_$0])]m4_dquote($m4_eval([($# + 1) & ~1]))[)])_$0($@)])]) m4_define([_m4_case_], +[$0_([1], [$1], m4_incr([$1]))]) + +m4_define([_m4_case__], [[[$$1],[$$2],[$$3],]]) # m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT) @@ -142,15 +124,18 @@ m4_define([m4_bmatch], [m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], [$#], 2, [$2], - [m4_define([_m4_b], m4_pushdef([_m4_b])[m4_define([_m4_b], - _m4_defn([_$0]))]_m4_for([_m4_b], [3], m4_eval([($# + 1) / 2 * 2 - 1]), - [2], [_$0_([1], m4_decr(_m4_b), _m4_b)])[_m4_b([], [],]m4_dquote( - [$]m4_incr(_m4_b))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])]) + [m4_pushdef([_m4_b], [m4_define([_m4_b], + _m4_defn([_$0]))]_m4_for([3], m4_eval([($# + 1) / 2 * 2 - 1]), + [2], [_$0_(], [)])[_m4_b([], [],]m4_dquote([$]m4_eval( + [($# + 1) / 2 * 2]))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])]) m4_define([_m4_bmatch], [m4_if(m4_bregexp([$1], [$2]), [-1], [], [[$3]m4_define([$0])])]) m4_define([_m4_bmatch_], +[$0_([1], m4_decr([$1]), [$1])]) + +m4_define([_m4_bmatch__], [[_m4_b([$$1], [$$2], [$$3])]]) @@ -170,12 +155,15 @@ m4_define([_m4_bmatch_], # [[$m]m4_define([_m4_c])])])_m4_c([[$m+1]]_m4_popdef([_m4_c])) # We invoke m4_unquote(_m4_c($@)), for concatenation with later text. m4_define([_m4_cond], -[m4_define([_m4_c], m4_pushdef([_m4_c])[m4_define([_m4_c], - _m4_defn([m4_unquote]))]_m4_for([_m4_c], [2], m4_eval([$# / 3 * 3 - 1]), [3], - [$0_(m4_decr(_m4_c), _m4_c, m4_incr(_m4_c))])[_m4_c(]m4_dquote(m4_dquote( +[m4_pushdef([_m4_c], [m4_define([_m4_c], + _m4_defn([m4_unquote]))]_m4_for([2], m4_eval([$# / 3 * 3 - 1]), [3], + [$0_(], [)])[_m4_c(]m4_dquote(m4_dquote( [$]m4_eval([$# / 3 * 3 + 1])))[_m4_popdef([_m4_c]))])m4_unquote(_m4_c($@))]) m4_define([_m4_cond_], +[$0_(m4_decr([$1]), [$1], m4_incr([$1]))]) + +m4_define([_m4_cond__], [[_m4_c([m4_if(($$1), [($$2)], [[$$3]m4_define([_m4_c])])])]]) # m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...) @@ -196,11 +184,14 @@ m4_define([_m4_cond_], # m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$m-1], [$m]))m4_unquote( # _m4_defn([_m4_p])_m4_popdef([_m4_p])) m4_define([_m4_bpatsubsts], -[m4_define([_m4_p], m4_pushdef([_m4_p])[m4_define([_m4_p], - ]m4_dquote([$]1)[)]_m4_for([_m4_p], [3], [$#], [2], [$0_(m4_decr(_m4_p), - _m4_p)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)]) +[m4_pushdef([_m4_p], [m4_define([_m4_p], + ]m4_dquote([$]1)[)]_m4_for([3], [$#], [2], [$0_(], + [)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)]) m4_define([_m4_bpatsubsts_], +[$0_(m4_decr([$1]), [$1])]) + +m4_define([_m4_bpatsubsts__], [[m4_define([_m4_p], m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]]) @@ -213,9 +204,9 @@ m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]]) # ,[$5],[$6],...,[$m]_m4_popdef([_m4_s]) # before calling m4_shift(_m4_s($@)). m4_define([_m4_shiftn], -[m4_if(m4_incr([$1]), [$#], [], [m4_define([_m4_s], - m4_pushdef([_m4_s])_m4_for([_m4_s], m4_eval([$1 + 2]), [$#], [1], - [[,]m4_dquote([$]_m4_s)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])]) +[m4_if(m4_incr([$1]), [$#], [], [m4_pushdef([_m4_s], + _m4_for(m4_eval([$1 + 2]), [$#], [1], + [[,]m4_dquote($], [)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])]) # m4_do(STRING, ...) # ------------------ @@ -227,16 +218,16 @@ m4_define([_m4_shiftn], # $1[]$2[]...[]$n[]_m4_popdef([_m4_do]) m4_define([m4_do], [m4_if([$#], [0], [], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [1], [$#], [1], - [$_$0[[]]])[_m4_popdef([_$0])])_$0($@)])]) + [m4_pushdef([_$0], _m4_for([1], [$#], [1], + [$], [[[]]])[_m4_popdef([_$0])])_$0($@)])]) # m4_dquote_elt(ARGS) # ------------------- # Return ARGS as an unquoted list of double-quoted arguments. # -# m4_foreach to the rescue. It's easier to shift off the leading comma. +# _m4_foreach to the rescue. m4_define([m4_dquote_elt], -[m4_shift(m4_foreach([_m4_elt], [$@], [,m4_dquote(_m4_defn([_m4_elt]))]))]) +[m4_if([$#], [0], [], [[[$1]]_m4_foreach([,m4_dquote(], [)], $@)])]) # m4_reverse(ARGS) # ---------------- @@ -246,67 +237,36 @@ m4_define([m4_dquote_elt], # [$m], [$m-1], ..., [$2], [$1]_m4_popdef([_m4_r]) m4_define([m4_reverse], [m4_if([$#], [0], [], [$#], [1], [[$1]], -[m4_define([_m4_r], m4_dquote([$$#])m4_pushdef([_m4_r])_m4_for([_m4_r], - m4_decr([$#]), [1], [-1], - [[, ]m4_dquote([$]_m4_r)])[_m4_popdef([_m4_r])])_m4_r($@)])]) - +[m4_pushdef([_m4_r], [[$$#]]_m4_for(m4_decr([$#]), [1], [-1], + [[, ]m4_dquote($], [)])[_m4_popdef([_m4_r])])_m4_r($@)])]) -# m4_map(MACRO, LIST) -# ------------------- -# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements -# of LIST. $1, $2... must in turn be lists, appropriate for m4_apply. -# -# m4_map/m4_map_sep only execute once; the speedup comes in fixing -# _m4_map. The mismatch in () is intentional, since $1 supplies the -# opening `(' (but it sure looks odd!). Build the temporary _m4_m: -# $1, [$3])$1, [$4])...$1, [$m])_m4_popdef([_m4_m]) -m4_define([_m4_map], -[m4_if([$#], [2], [], - [m4_define([_m4_m], m4_pushdef([_m4_m])_m4_for([_m4_m], [3], [$#], [1], - [$0_([1], _m4_m)])[_m4_popdef([_m4_m])])_m4_m($@)])]) - -m4_define([_m4_map_], -[[$$1, [$$2])]]) - -# m4_transform(EXPRESSION, ARG...) -# -------------------------------- -# Expand EXPRESSION([ARG]) for each argument. More efficient than -# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) -# -# Invoke the temporary macro _m4_transform, defined as: -# $1([$2])[]$1([$3])[]...$1([$m])[]_m4_popdef([_m4_transform]) -m4_define([m4_transform], -[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], - [$#], [1], [], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [2], [$#], [1], - [_$0_([1], _$0)])[_m4_popdef([_$0])])_$0($@)])]) -m4_define([_m4_transform_], -[[$$1([$$2])[]]]) - -# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) -# -------------------------------------------------------------- +# m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) +# ------------------------------------------------------------- # Perform a pairwise grouping of consecutive ARGs, by expanding # EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the # final argument is expanded with END-EXPR([ARGn]). # -# Build the temporary macro _m4_transform_pair, with the $2([$m+1]) +# Build the temporary macro _m4_map_args_pair, with the $2([$m+1]) # only output if $# is odd: # $1([$3], [$4])[]$1([$5], [$6])[]...$1([$m-1], -# [$m])[]m4_default([$2], [$1])([$m+1])[]_m4_popdef([_m4_transform_pair]) -m4_define([m4_transform_pair], +# [$m])[]m4_default([$2], [$1])([$m+1])[]_m4_popdef([_m4_map_args_pair]) +m4_define([m4_map_args_pair], [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])], [$#], [2], [], [$#], [3], [m4_default([$2], [$1])([$3])[]], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [3], - m4_eval([$# / 2 * 2 - 1]), [2], [_$0_([1], _$0, m4_incr(_$0))])_$0_end( + [m4_pushdef([_$0], _m4_for([3], + m4_eval([$# / 2 * 2 - 1]), [2], [_$0_(], [)])_$0_end( [1], [2], [$#])[_m4_popdef([_$0])])_$0($@)])]) -m4_define([_m4_transform_pair_], +m4_define([_m4_map_args_pair_], +[$0_([1], [$1], m4_incr([$1]))]) + +m4_define([_m4_map_args_pair__], [[$$1([$$2], [$$3])[]]]) -m4_define([_m4_transform_pair_end], +m4_define([_m4_map_args_pair_end], [m4_if(m4_eval([$3 & 1]), [1], [[m4_default([$$2], [$$1])([$$3])[]]])]) # m4_join(SEP, ARG1, ARG2...) @@ -316,23 +276,23 @@ m4_define([_m4_transform_pair_end], # # Use a self-modifying separator, since we don't know how many # arguments might be skipped before a separator is first printed, but -# be careful if the separator contains $. m4_foreach to the rescue. +# be careful if the separator contains $. _m4_foreach to the rescue. m4_define([m4_join], [m4_pushdef([_m4_sep], [m4_define([_m4_sep], _m4_defn([m4_echo]))])]dnl -[m4_foreach([_m4_arg], [m4_shift($@)], - [m4_ifset([_m4_arg], [_m4_sep([$1])_m4_defn([_m4_arg])])])]dnl -[_m4_popdef([_m4_sep])]) +[_m4_foreach([_$0([$1],], [)], $@)_m4_popdef([_m4_sep])]) + +m4_define([_m4_join], +[m4_if([$2], [], [], [_m4_sep([$1])[$2]])]) # m4_joinall(SEP, ARG1, ARG2...) # ------------------------------ # Produce ARG1SEPARG2...SEPARGn. An empty ARG results in back-to-back SEP. # No expansion is performed on SEP or ARGs. # -# A bit easier than m4_join. m4_foreach to the rescue. +# A bit easier than m4_join. _m4_foreach to the rescue. m4_define([m4_joinall], [[$2]m4_if(m4_eval([$# <= 2]), [1], [], - [m4_foreach([_m4_arg], [m4_shift2($@)], - [[$1]_m4_defn([_m4_arg])])])]) + [_m4_foreach([$1], [], m4_shift($@))])]) # m4_list_cmp(A, B) # ----------------- @@ -346,24 +306,26 @@ m4_define([m4_joinall], # is found. For example, m4_list_cmp([1], [1,2]) creates _m4_cmp as # m4_if(m4_eval([($1) != ($3)]), [1], [m4_cmp([$1], [$3])], # m4_eval([($2) != ($4)]), [1], [m4_cmp([$2], [$4])], -# [0]_m4_popdef([_m4_cmp], [_m4_size])) -# then calls _m4_cmp([1+0], [0], [1], [2+0]) +# [0]_m4_popdef([_m4_cmp])) +# then calls _m4_cmp([1+0], [0*2], [1], [2+0]) m4_define([_m4_list_cmp_raw], -[m4_if([$1], [$2], 0, [m4_pushdef( - [_m4_size])_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)), - $2+0_m4_list_pad(m4_count($2), m4_count($1)))])]) +[m4_if([$1], [$2], 0, + [_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)), + $2+0_m4_list_pad(m4_count($2), m4_count($1)))])]) m4_define([_m4_list_pad], [m4_if(m4_eval($1 < $2), [1], - [_m4_for([_m4_size], m4_incr([$1]), [$2], [1], [,0])])]) + [_m4_for(m4_incr([$1]), [$2], [1], [,0*])])]) m4_define([_m4_list_cmp], -[m4_define([_m4_size], m4_eval([$# >> 1]))]dnl -[m4_define([_m4_cmp], m4_pushdef([_m4_cmp])[m4_if(]_m4_for([_m4_cmp], - [1], _m4_size, [1], [$0_(_m4_cmp, m4_eval(_m4_cmp + _m4_size))])[ - [0]_m4_popdef([_m4_cmp], [_m4_size]))])_m4_cmp($@)]) +[m4_pushdef([_m4_cmp], [m4_if(]_m4_for( + [1], m4_eval([$# >> 1]), [1], [$0_(], [,]m4_eval([$# >> 1])[)])[ + [0]_m4_popdef([_m4_cmp]))])_m4_cmp($@)]) m4_define([_m4_list_cmp_], +[$0_([$1], m4_eval([$1 + $2]))]) + +m4_define([_m4_list_cmp__], [[m4_eval([($$1) != ($$2)]), [1], [m4_cmp([$$1], [$$2])], ]]) @@ -373,12 +335,12 @@ m4_define([_m4_list_cmp_], # Return the decimal value of the maximum (or minimum) in a series of # integer expressions. # -# m4_foreach to the rescue; we only need to replace _m4_minmax. Here, +# _m4_foreach to the rescue; we only need to replace _m4_minmax. Here, # we need a temporary macro to track the best answer so far, so that # the foreach expression is tractable. m4_define([_m4_minmax], -[m4_pushdef([_m4_best], m4_eval([$2]))m4_foreach([_m4_arg], [m4_shift2($@)], - [m4_define([_m4_best], $1(_m4_best, _m4_defn([_m4_arg])))])]dnl +[m4_pushdef([_m4_best], m4_eval([$2]))_m4_foreach( + [m4_define([_m4_best], $1(_m4_best,], [))], m4_shift($@))]dnl [_m4_best[]_m4_popdef([_m4_best])]) # m4_set_add_all(SET, VALUE...) @@ -386,15 +348,15 @@ m4_define([_m4_minmax], # Add each VALUE into SET. This is O(n) in the number of VALUEs, and # can be faster than calling m4_set_add for each VALUE. # -# m4_foreach to the rescue. If no deletions have occurred, then avoid -# the speed penalty of m4_set_add. +# _m4_foreach to the rescue. If no deletions have occurred, then +# avoid the speed penalty of m4_set_add. m4_define([m4_set_add_all], [m4_if([$#], [0], [], [$#], [1], [], [m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1]) - + m4_len(m4_foreach([_m4_arg], [m4_shift($@)], - m4_ifdef([_m4_set_cleanup($1)], - [[m4_set_add([$1], _m4_defn([_m4_arg]))]], - [[m4_ifdef([_m4_set([$1],]_m4_defn([_m4_arg])[)], [], - [m4_define([_m4_set([$1],]_m4_defn([_m4_arg])[)], - [1])m4_pushdef([_m4_set([$1])], - _m4_defn([_m4_arg]))-])]])))))])]) + + m4_len(_m4_foreach(m4_ifdef([_m4_set_cleanup($1)], + [[m4_set_add]], [[_$0]])[([$1],], [)], $@))))])]) + +m4_define([_m4_set_add_all], +[m4_ifdef([_m4_set([$1],$2)], [], + [m4_define([_m4_set([$1],$2)], + [1])m4_pushdef([_m4_set([$1])], [$2])-])]) diff --git a/share/bison/m4sugar/m4sugar.m4 b/msys2/usr/share/bison/m4sugar/m4sugar.m4 similarity index 65% rename from share/bison/m4sugar/m4sugar.m4 rename to msys2/usr/share/bison/m4sugar/m4sugar.m4 index 6fbd343..bbd6958 100644 --- a/share/bison/m4sugar/m4sugar.m4 +++ b/msys2/usr/share/bison/m4sugar/m4sugar.m4 @@ -3,12 +3,12 @@ divert(-1)# -*- Autoconf -*- # Base M4 layer. # Requires GNU M4. # -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -# 2008 Free Software Foundation, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or +# Copyright (C) 1999-2017 Free Software Foundation, Inc. + +# This file is part of Autoconf. This program is free +# software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -16,38 +16,16 @@ divert(-1)# -*- Autoconf -*- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception, the Free Software Foundation gives unlimited -# permission to copy, distribute and modify the configure scripts that -# are the output of Autoconf. You need not follow the terms of the GNU -# General Public License when using or distributing such scripts, even -# though portions of the text of Autoconf appear in them. The GNU -# General Public License (GPL) does govern all other use of the material -# that constitutes the Autoconf program. -# -# Certain portions of the Autoconf source text are designed to be copied -# (in certain cases, depending on the input) into the output of -# Autoconf. We call these the "data" portions. The rest of the Autoconf -# source text consists of comments plus executable code that decides which -# of the data portions to output in any given case. We call these -# comments and executable code the "non-data" portions. Autoconf never -# copies any of the non-data portions into its output. -# -# This special exception to the GPL applies to versions of Autoconf -# released by the Free Software Foundation. When you make and -# distribute a modified version of Autoconf, you may extend this special -# exception to the GPL to apply to your modified version as well, *unless* -# your modified version has the potential to copy into its output some -# of the text that was the non-data portion of the version that you started -# with. (In other words, unless your change moves or copies text from -# the non-data portions to the data portions.) If your modification has -# such potential, you must delete any notice of this special exception -# to the GPL from your modified version. +# Under Section 7 of GPL version 3, you are granted additional +# permissions described in the Autoconf Configure Script Exception, +# version 3.0, as published by the Free Software Foundation. # +# You should have received a copy of the GNU General Public License +# and a copy of the Autoconf Configure Script Exception along with +# this program; see the files COPYINGv3 and COPYING.EXCEPTION +# respectively. If not, see . + # Written by Akim Demaille. -# # Set the quotes, whatever the current quoting system. changequote() @@ -89,6 +67,10 @@ m4_undefine([undefine]) # Nevertheless, one huge difference is the handling of `$0'. If `from' # uses `$0', then with 1, `to''s `$0' is `to', while it is `from' in 2. # The user would certainly prefer to see `to'. +# +# This definition is in effect during m4sugar initialization, when +# there are no pushdef stacks; later on, we redefine it to something +# more powerful for all other clients to use. m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))]) @@ -128,7 +110,6 @@ m4_ifdef([changeword],dnl conditionally available in 1.4.x m4_rename_m4([debugfile]) m4_rename_m4([debugmode]) m4_rename_m4([decr]) -m4_undefine([divert]) m4_rename_m4([divnum]) m4_rename_m4([dumpdef]) m4_rename_m4([errprint]) @@ -162,7 +143,41 @@ m4_rename_m4([sysval]) m4_rename_m4([traceoff]) m4_rename_m4([traceon]) m4_rename_m4([translit]) -m4_undefine([undivert]) + +# _m4_defn(ARG) +# ------------- +# _m4_defn is for internal use only - it bypasses the wrapper, so it +# must only be used on one argument at a time, and only on macros +# known to be defined. Make sure this still works if the user renames +# m4_defn but not _m4_defn. +m4_copy([m4_defn], [_m4_defn]) + +# _m4_divert_raw(NUM) +# ------------------- +# _m4_divert_raw is for internal use only. Use this instead of +# m4_builtin([divert], NUM), so that tracing diversion flow is easier. +m4_rename([divert], [_m4_divert_raw]) + +# _m4_popdef(ARG...) +# ------------------ +# _m4_popdef is for internal use only - it bypasses the wrapper, so it +# must only be used on macros known to be defined. Make sure this +# still works if the user renames m4_popdef but not _m4_popdef. +m4_copy([m4_popdef], [_m4_popdef]) + +# _m4_undefine(ARG...) +# -------------------- +# _m4_undefine is for internal use only - it bypasses the wrapper, so +# it must only be used on macros known to be defined. Make sure this +# still works if the user renames m4_undefine but not _m4_undefine. +m4_copy([m4_undefine], [_m4_undefine]) + +# _m4_undivert(NUM...) +# -------------------- +# _m4_undivert is for internal use only, and should always be given +# arguments. Use this instead of m4_builtin([undivert], NUM...), so +# that tracing diversion flow is easier. +m4_rename([undivert], [_m4_undivert]) ## ------------------- ## @@ -172,6 +187,7 @@ m4_undefine([undivert]) # m4_location # ----------- +# Output the current file, colon, and the current line number. m4_define([m4_location], [__file__:__line__]) @@ -195,9 +211,8 @@ m4_define([m4_warning], # ---------------------------- # Fatal the user. :) m4_define([m4_fatal], -[m4_errprintn(m4_location[: error: $1])dnl -m4_expansion_stack_dump()dnl -m4_exit(m4_if([$2],, 1, [$2]))]) +[m4_errprintn(m4_location[: error: $1] +m4_expansion_stack)m4_exit(m4_if([$2],, 1, [$2]))]) # m4_assert(EXPRESSION, [EXIT-STATUS = 1]) @@ -215,11 +230,12 @@ m4_define([m4_assert], ## ------------- ## -# _m4_warn(CATEGORY, MESSAGE, STACK-TRACE) -# ---------------------------------------- +# _m4_warn(CATEGORY, MESSAGE, [STACK-TRACE]) +# ------------------------------------------ # Report a MESSAGE to the user if the CATEGORY of warnings is enabled. # This is for traces only. -# The STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE". +# If present, STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE", +# where the last line (and no other) ends with "the top level". # # Within m4, the macro is a no-op. This macro really matters # when autom4te post-processes the trace output. @@ -231,10 +247,7 @@ m4_define([_m4_warn], []) # Report a MESSAGE to the user if the CATEGORY of warnings is enabled. m4_define([m4_warn], [_m4_warn([$1], [$2], -m4_ifdef([m4_expansion_stack], - [_m4_defn([m4_expansion_stack]) -m4_location[: the top level]]))dnl -]) +m4_ifdef([_m4_expansion_stack], [m4_expansion_stack]))]) @@ -299,6 +312,29 @@ m4_builtin([sinclude], [$1])]) # it runs TRUE, etc. +# m4_ifblank(COND, [IF-BLANK], [IF-TEXT]) +# m4_ifnblank(COND, [IF-TEXT], [IF-BLANK]) +# ---------------------------------------- +# If COND is empty, or consists only of blanks (space, tab, newline), +# then expand IF-BLANK, otherwise expand IF-TEXT. This differs from +# m4_ifval only if COND has just whitespace, but it helps optimize in +# spite of users who mistakenly leave trailing space after what they +# thought was an empty argument: +# macro( +# [] +# ) +# +# Writing one macro in terms of the other causes extra overhead, so +# we inline both definitions. +m4_define([m4_ifblank], +[m4_if(m4_translit([[$1]], [ ][ ][ +]), [], [$2], [$3])]) + +m4_define([m4_ifnblank], +[m4_if(m4_translit([[$1]], [ ][ ][ +]), [], [$3], [$2])]) + + # m4_ifval(COND, [IF-TRUE], [IF-FALSE]) # ------------------------------------- # If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE. @@ -395,20 +431,35 @@ m4_define([m4_bmatch], [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shift3($@))], [$3])])]) +# m4_argn(N, ARGS...) +# ------------------- +# Extract argument N (greater than 0) from ARGS. Example: +# m4_define([b], [B]) +# m4_argn([2], [a], [b], [c]) => b +# +# Rather than using m4_car(m4_shiftn([$1], $@)), we exploit the fact that +# GNU m4 can directly reference any argument, through an indirect macro. +m4_define([m4_argn], +[m4_assert([0 < $1])]dnl +[m4_pushdef([_$0], [_m4_popdef([_$0])]m4_dquote([$]m4_incr([$1])))_$0($@)]) -# m4_car(LIST) -# m4_cdr(LIST) -# ------------ -# Manipulate m4 lists. + +# m4_car(ARGS...) +# m4_cdr(ARGS...) +# --------------- +# Manipulate m4 lists. m4_car returns the first argument. m4_cdr +# bundles all but the first argument into a quoted list. These two +# macros are generally used with list arguments, with quoting removed +# to break the list into multiple m4 ARGS. m4_define([m4_car], [[$1]]) m4_define([m4_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) -# _m4_cdr(LIST) -# ------------- -# Like m4_cdr, except include a leading comma unless only one element +# _m4_cdr(ARGS...) +# ---------------- +# Like m4_cdr, except include a leading comma unless only one argument # remains. Why? Because comparing a large list against [] is more # expensive in expansion time than comparing the number of arguments; so # _m4_cdr can be used to reduce the number of arguments when it is time @@ -499,6 +550,36 @@ m4_define([_m4_bpatsubsts], m4_shift3($@))])]) +# m4_copy(SRC, DST) +# ----------------- +# Define the pushdef stack DST as a copy of the pushdef stack SRC; +# give an error if DST is already defined. This is particularly nice +# for copying self-modifying pushdef stacks, where the top definition +# includes one-shot initialization that is later popped to the normal +# definition. This version intentionally does nothing if SRC is +# undefined. +# +# Some macros simply can't be renamed with this method: namely, anything +# involved in the implementation of m4_stack_foreach_sep. +m4_define([m4_copy], +[m4_ifdef([$2], [m4_fatal([$0: won't overwrite defined macro: $2])], + [m4_stack_foreach_sep([$1], [m4_pushdef([$2],], [)])])]dnl +[m4_ifdef([m4_location($1)], [m4_define([m4_location($2)], m4_location)])]) + + +# m4_copy_force(SRC, DST) +# m4_rename_force(SRC, DST) +# ------------------------- +# Like m4_copy/m4_rename, except blindly overwrite any existing DST. +# Note that m4_copy_force tolerates undefined SRC, while m4_rename_force +# does not. +m4_define([m4_copy_force], +[m4_ifdef([$2], [_m4_undefine([$2])])m4_copy($@)]) + +m4_define([m4_rename_force], +[m4_ifdef([$2], [_m4_undefine([$2])])m4_rename($@)]) + + # m4_define_default(MACRO, VALUE) # ------------------------------- # If MACRO is undefined, set it to VALUE. @@ -507,14 +588,43 @@ m4_define([m4_define_default], # m4_default(EXP1, EXP2) -# ---------------------- -# Returns EXP1 if non empty, otherwise EXP2. +# m4_default_nblank(EXP1, EXP2) +# ----------------------------- +# Returns EXP1 if not empty/blank, otherwise EXP2. Expand the result. # -# This macro is called on hot paths, so inline the contents of m4_ifval, +# m4_default is called on hot paths, so inline the contents of m4_ifval, # for one less round of expansion. m4_define([m4_default], [m4_if([$1], [], [$2], [$1])]) +m4_define([m4_default_nblank], +[m4_ifblank([$1], [$2], [$1])]) + + +# m4_default_quoted(EXP1, EXP2) +# m4_default_nblank_quoted(EXP1, EXP2) +# ------------------------------------ +# Returns EXP1 if non empty/blank, otherwise EXP2. Leave the result quoted. +# +# For comparison: +# m4_define([active], [ACTIVE]) +# m4_default([active], [default]) => ACTIVE +# m4_default([], [active]) => ACTIVE +# -m4_default([ ], [active])- => - - +# -m4_default_nblank([ ], [active])- => -ACTIVE- +# m4_default_quoted([active], [default]) => active +# m4_default_quoted([], [active]) => active +# -m4_default_quoted([ ], [active])- => - - +# -m4_default_nblank_quoted([ ], [active])- => -active- +# +# m4_default macro is called on hot paths, so inline the contents of m4_ifval, +# for one less round of expansion. +m4_define([m4_default_quoted], +[m4_if([$1], [], [[$2]], [[$1]])]) + +m4_define([m4_default_nblank_quoted], +[m4_ifblank([$1], [[$2]], [[$1]])]) + # m4_defn(NAME) # ------------- @@ -528,45 +638,61 @@ m4_define([m4_default], # This macro is called frequently, so minimize the amount of additional # expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, # (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_defn is for internal use only - it bypasses the wrapper, so it -# must only be used on one argument at a time, and only on macros -# known to be defined. Make sure this still works if the user renames -# m4_defn but not _m4_defn. -m4_copy([m4_defn], [_m4_defn]) m4_define([m4_defn], [m4_if([$#], [0], [[$0]], [$#], [1], [m4_ifdef([$1], [_m4_defn([$1])], [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) - + [m4_map_args([$0], $@)])]) -# _m4_dumpdefs_up(NAME) -# --------------------- -m4_define([_m4_dumpdefs_up], -[m4_ifdef([$1], - [m4_pushdef([_m4_dumpdefs], _m4_defn([$1]))dnl -m4_dumpdef([$1])dnl -_m4_popdef([$1])dnl -_m4_dumpdefs_up([$1])])]) - - -# _m4_dumpdefs_down(NAME) -# ----------------------- -m4_define([_m4_dumpdefs_down], -[m4_ifdef([_m4_dumpdefs], - [m4_pushdef([$1], _m4_defn([_m4_dumpdefs]))dnl -_m4_popdef([_m4_dumpdefs])dnl -_m4_dumpdefs_down([$1])])]) - -# m4_dumpdefs(NAME) -# ----------------- +# m4_dumpdef(NAME...) +# ------------------- +# In m4 1.4.x, dumpdef writes to the current debugfile, rather than +# stderr. This in turn royally confuses autom4te; so we follow the +# lead of newer m4 and always dump to stderr. Unlike the original, +# this version requires an argument, since there is no convenient way +# in m4 1.4.x to grab the names of all defined macros. Newer m4 +# always dumps to stderr, regardless of the current debugfile; it also +# provides m4symbols as a way to grab all current macro names. But +# dumpdefs is not frequently called, so we don't need to worry about +# conditionally using these newer features. Also, this version +# doesn't sort multiple arguments. +# +# If we detect m4 1.6 or newer, then provide an alternate definition, +# installed during m4_init, that allows builtins through. +# Unfortunately, there is no nice way in m4 1.4.x to dump builtins. +m4_define([m4_dumpdef], +[m4_if([$#], [0], [m4_fatal([$0: missing argument])], + [$#], [1], [m4_ifdef([$1], [m4_errprintn( + [$1: ]m4_dquote(_m4_defn([$1])))], [m4_fatal([$0: undefined macro: $1])])], + [m4_map_args([$0], $@)])]) + +m4_define([_m4_dumpdef], +[m4_if([$#], [0], [m4_fatal([$0: missing argument])], + [$#], [1], [m4_builtin([dumpdef], [$1])], + [m4_map_args_sep([m4_builtin([dumpdef],], [)], [], $@)])]) + + +# m4_dumpdefs(NAME...) +# -------------------- # Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its -# value stack (most recent displayed first). +# value stack (most recent displayed first). Also, this version silently +# ignores undefined macros, rather than erroring out. +# +# This macro cheats, because it relies on the current definition of NAME +# while the second argument of m4_stack_foreach_lifo is evaluated (which +# would be undefined according to the API). m4_define([m4_dumpdefs], -[_m4_dumpdefs_up([$1])dnl -_m4_dumpdefs_down([$1])]) +[m4_if([$#], [0], [m4_fatal([$0: missing argument])], + [$#], [1], [m4_stack_foreach_lifo([$1], [m4_dumpdef([$1])m4_ignore])], + [m4_map_args([$0], $@)])]) + +# m4_esyscmd_s(COMMAND) +# --------------------- +# Like m4_esyscmd, except strip any trailing newlines, thus behaving +# more like shell command substitution. +m4_define([m4_esyscmd_s], +[m4_chomp_all(m4_esyscmd([$1]))]) # m4_popdef(NAME) @@ -577,16 +703,11 @@ _m4_dumpdefs_down([$1])]) # This macro is called frequently, so minimize the amount of additional # expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, # (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_popdef is for internal use only - it bypasses the wrapper, so it -# must only be used on macros known to be defined. Make sure this -# still works if the user renames m4_popdef but not _m4_popdef. -m4_copy([m4_popdef], [_m4_popdef]) m4_define([m4_popdef], [m4_if([$#], [0], [[$0]], [$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])], [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) + [m4_map_args([$0], $@)])]) # m4_shiftn(N, ...) @@ -615,7 +736,7 @@ m4_define([_m4_shiftn], # m4_shift2(...) # m4_shift3(...) -# ----------------- +# -------------- # Returns ... shifted twice, and three times. Faster than m4_shiftn. m4_define([m4_shift2], [m4_shift(m4_shift($@))]) m4_define([m4_shift3], [m4_shift(m4_shift(m4_shift($@)))]) @@ -643,16 +764,11 @@ m4_define([_m4_shift3], # This macro is called frequently, so minimize the amount of additional # expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, # (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_undefine is for internal use only - it bypasses the wrapper, so -# it must only be used on macros known to be defined. Make sure this -# still works if the user renames m4_undefine but not _m4_undefine. -m4_copy([m4_undefine], [_m4_undefine]) m4_define([m4_undefine], [m4_if([$#], [0], [[$0]], [$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])], [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) + [m4_map_args([$0], $@)])]) # _m4_wrap(PRE, POST) # ------------------- @@ -707,6 +823,20 @@ m4_define([_m4_apply], m4_define([m4_count], [$#]) +# m4_curry(MACRO, ARG...) +# ----------------------- +# Perform argument currying. The expansion of this macro is another +# macro that takes exactly one argument, appends it to the end of the +# original ARG list, then invokes MACRO. For example: +# m4_curry([m4_curry], [m4_reverse], [1])([2])([3]) => 3, 2, 1 +# Not quite as practical as m4_incr, but you could also do: +# m4_define([add], [m4_eval(([$1]) + ([$2]))]) +# m4_define([add_one], [m4_curry([add], [1])]) +# add_one()([2]) => 3 +m4_define([m4_curry], [$1(m4_shift($@,)_$0]) +m4_define([_m4_curry], [[$1])]) + + # m4_do(STRING, ...) # ------------------ # This macro invokes all its arguments (in sequence, of course). It is @@ -746,10 +876,12 @@ m4_define([m4_echo], [$@]) # m4_expand(ARG) -# -------------- -# Return the expansion of ARG as a single string. Unlike m4_quote($1), this -# correctly preserves whitespace following single-quoted commas that appeared -# within ARG. +# _m4_expand(ARG) +# --------------- +# Return the expansion of ARG as a single string. Unlike +# m4_quote($1), this preserves whitespace following single-quoted +# commas that appear within ARG. It also deals with shell case +# statements. # # m4_define([active], [ACT, IVE]) # m4_define([active2], [[ACT, IVE]]) @@ -758,17 +890,42 @@ m4_define([m4_echo], [$@]) # m4_expand([active, active2]) # => ACT, IVE, ACT, IVE # -# Unfortunately, due to limitations in m4, ARG must expand to something -# with balanced quotes (use quadrigraphs to get around this). The input -# is not likely to have unbalanced -=<{(/)}>=- quotes, and it is possible -# to have unbalanced (), provided it was specified with proper [] quotes. -# -# Exploit that extra () will group unquoted commas and the following -# whitespace, then convert () to []. m4_bpatsubst can't handle newlines -# inside $1, and m4_substr strips quoting. So we (ab)use m4_changequote. -m4_define([m4_expand], [_$0(-=<{($1)}>=-)]) -m4_define([_m4_expand], -[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])]) +# Unfortunately, due to limitations in m4, ARG must expand to +# something with balanced quotes (use quadrigraphs to get around +# this), and should not contain the unlikely delimiters -=<{( or +# )}>=-. It is possible to have unbalanced quoted `(' or `)', as well +# as unbalanced unquoted `)'. m4_expand can handle unterminated +# comments or dnl on the final line, at the expense of speed; it also +# aids in detecting attempts to incorrectly change the current +# diversion inside ARG. Meanwhile, _m4_expand is faster but must be +# given a terminated expansion, and has no safety checks for +# mis-diverted text. +# +# Exploit that extra unquoted () will group unquoted commas and the +# following whitespace. m4_bpatsubst can't handle newlines inside $1, +# and m4_substr strips quoting. So we (ab)use m4_changequote, using +# temporary quotes to remove the delimiters that conveniently included +# the unquoted () that were added prior to the changequote. +# +# Thanks to shell case statements, too many people are prone to pass +# underquoted `)', so we try to detect that by passing a marker as a +# fourth argument; if the marker is not present, then we assume that +# we encountered an early `)', and re-expand the first argument, but +# this time with one more `(' in the second argument and in the +# open-quote delimiter. We must also ignore the slop from the +# previous try. The final macro is thus half line-noise, half art. +m4_define([m4_expand], +[m4_pushdef([m4_divert], _m4_defn([_m4_divert_unsafe]))]dnl +[m4_pushdef([m4_divert_push], _m4_defn([_m4_divert_unsafe]))]dnl +[m4_chomp(_$0([$1 +]))_m4_popdef([m4_divert], [m4_divert_push])]) + +m4_define([_m4_expand], [$0_([$1], [(], -=<{($1)}>=-, [}>=-])]) + +m4_define([_m4_expand_], +[m4_if([$4], [}>=-], + [m4_changequote([-=<{$2], [)}>=-])$3m4_changequote([, ])], + [$0([$1], [($2], -=<{($2$1)}>=-, [}>=-])m4_ignore$2])]) # m4_ignore(ARGS) @@ -793,7 +950,7 @@ m4_define([m4_make_list], [m4_join([, # m4_noquote(STRING) # ------------------ # Return the result of ignoring all quotes in STRING and invoking the -# macros it contains. Amongst other things, this is useful for enabling +# macros it contains. Among other things, this is useful for enabling # macro invocations inside strings with [] blocks (for instance regexps # and help-strings). On the other hand, since all quotes are disabled, # any macro expanded during this time that relies on nested [] quoting @@ -860,31 +1017,29 @@ m4_define([m4_unquote], [$*]) # VARIABLE names. Changing VARIABLE inside EXPRESSION will not impact # the number of iterations. # -# Uses _m4_defn for speed, and avoid dnl in the macro body. +# Uses _m4_defn for speed, and avoid dnl in the macro body. Factor +# the _m4_for call so that EXPRESSION is only parsed once. m4_define([m4_for], [m4_pushdef([$1], m4_eval([$2]))]dnl [m4_cond([m4_eval(([$3]) > ([$2]))], 1, - [m4_pushdef([_m4_step], m4_eval(m4_default([$4], - 1)))m4_assert(_m4_step > 0)_$0([$1], _m4_defn([$1]), - m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])), - _m4_step, [$5])], + [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4], + 1)))m4_assert(_m4_step > 0)_$0(_m4_defn([$1]), + m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])), _m4_step,], [m4_eval(([$3]) < ([$2]))], 1, - [m4_pushdef([_m4_step], m4_eval(m4_default([$4], - -1)))m4_assert(_m4_step < 0)_$0([$1], _m4_defn([$1]), - m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])), - _m4_step, [$5])], - [m4_pushdef([_m4_step])$5])[]]dnl -[m4_popdef([_m4_step], [$1])]) + [m4_pushdef([_m4_step], m4_eval(m4_default_quoted([$4], + -1)))m4_assert(_m4_step < 0)_$0(_m4_defn([$1]), + m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])), _m4_step,], + [m4_pushdef([_m4_step])_$0(_m4_defn([$1]), _m4_defn([$1]), 0,])]dnl +[[m4_define([$1],], [)$5])m4_popdef([_m4_step], [$1])]) - -# _m4_for(VARIABLE, COUNT, LAST, STEP, EXPRESSION) -# ------------------------------------------------ +# _m4_for(COUNT, LAST, STEP, PRE, POST) +# ------------------------------------- # Core of the loop, no consistency checks, all arguments are plain -# numbers. Define VARIABLE to COUNT, expand EXPRESSION, then alter -# COUNT by STEP and iterate if COUNT is not LAST. +# numbers. Expand PRE[COUNT]POST, then alter COUNT by STEP and +# iterate if COUNT is not LAST. m4_define([_m4_for], -[m4_define([$1], [$2])$5[]m4_if([$2], [$3], [], - [$0([$1], m4_eval([$2 + $4]), [$3], [$4], [$5])])]) +[$4[$1]$5[]m4_if([$1], [$2], [], + [$0(m4_eval([$1 + $3]), [$2], [$3], [$4], [$5])])]) # Implementing `foreach' loops in m4 is much more tricky than it may @@ -994,22 +1149,29 @@ m4_define([_m4_for], # more memory for expansion. So, rather than directly compare $2 against # [] and use m4_car/m4_cdr for recursion, we instead unbox the list (which # requires swapping the argument order in the helper), insert an ignored -# third argument, and use m4_shift3 to detect when recursion is complete. -# -# Please keep foreach.m4 in sync with any adjustments made here. +# third argument, and use m4_shift3 to detect when recursion is complete, +# at which point this looks very much like m4_map_args. m4_define([m4_foreach], [m4_if([$2], [], [], - [m4_pushdef([$1])_$0([$1], [$3], [], $2)m4_popdef([$1])])]) + [m4_pushdef([$1])_$0([m4_define([$1],], [)$3], [], + $2)m4_popdef([$1])])]) +# _m4_foreach(PRE, POST, IGNORED, ARG...) +# --------------------------------------- +# Form the common basis of the m4_foreach and m4_map macros. For each +# ARG, expand PRE[ARG]POST[]. The IGNORED argument makes recursion +# easier, and must be supplied rather than implicit. +# +# Please keep foreach.m4 in sync with any adjustments made here. m4_define([_m4_foreach], [m4_if([$#], [3], [], - [m4_define([$1], [$4])$2[]$0([$1], [$2], m4_shift3($@))])]) + [$1[$4]$2[]$0([$1], [$2], m4_shift3($@))])]) # m4_foreach_w(VARIABLE, LIST, EXPRESSION) # ---------------------------------------- -# -# Like m4_foreach, but the list is whitespace separated. +# Like m4_foreach, but the list is whitespace separated. Depending on +# EXPRESSION, it may be more efficient to use m4_map_args_w. # # This macro is robust to active symbols: # m4_foreach_w([Var], [ active @@ -1017,8 +1179,11 @@ m4_define([_m4_foreach], # ive ], [-Var-])end # => -active--b--active-end # +# This used to use a slower implementation based on m4_foreach: +# m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3]) m4_define([m4_foreach_w], -[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])]) +[m4_pushdef([$1])m4_map_args_w([$2], + [m4_define([$1],], [)$3])m4_popdef([$1])]) # m4_map(MACRO, LIST) @@ -1031,24 +1196,20 @@ m4_define([m4_foreach_w], # # Since LIST may be quite large, we want to minimize how often it # appears in the expansion. Rather than use m4_car/m4_cdr iteration, -# we unbox the list, ignore the second argument, and use m4_shift2 to -# detect the end of recursion. The mismatch in () is intentional; see -# _m4_map. For m4_map, an empty list behaves like an empty sublist -# and gets ignored; for m4_mapall, we must special-case the empty -# list. -# -# Please keep foreach.m4 in sync with any adjustments made here. +# we unbox the list, and use _m4_foreach for iteration. For m4_map, +# an empty list behaves like an empty sublist and gets ignored; for +# m4_mapall, we must special-case the empty list. m4_define([m4_map], -[_m4_map([_m4_apply([$1]], [], $2)]) +[_m4_foreach([_m4_apply([$1],], [)], [], $2)]) m4_define([m4_mapall], [m4_if([$2], [], [], - [_m4_map([m4_apply([$1]], [], $2)])]) + [_m4_foreach([m4_apply([$1],], [)], [], $2)])]) -# m4_map_sep(MACRO, SEPARATOR, LIST) -# m4_mapall_sep(MACRO, SEPARATOR, LIST) -# ------------------------------------- +# m4_map_sep(MACRO, [SEPARATOR], LIST) +# m4_mapall_sep(MACRO, [SEPARATOR], LIST) +# --------------------------------------- # Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1, # $2... $N are the elements of LIST, and are in turn lists appropriate # for m4_apply. SEPARATOR is expanded, in order to allow the creation @@ -1065,56 +1226,41 @@ m4_define([m4_mapall], # helper macro and use that as the separator instead. m4_define([m4_map_sep], [m4_pushdef([m4_Sep], [m4_define([m4_Sep], _m4_defn([m4_unquote]))])]dnl -[_m4_map([_m4_apply([m4_Sep([$2])[]$1]], [], $3)m4_popdef([m4_Sep])]) +[_m4_foreach([_m4_apply([m4_Sep([$2])[]$1],], [)], [], $3)m4_popdef([m4_Sep])]) m4_define([m4_mapall_sep], [m4_if([$3], [], [], [_$0([$1], [$2], $3)])]) m4_define([_m4_mapall_sep], -[m4_apply([$1], [$3])_m4_map([m4_apply([$2[]$1]], m4_shift2($@))]) +[m4_apply([$1], [$3])_m4_foreach([m4_apply([$2[]$1],], [)], m4_shift2($@))]) -# _m4_map(PREFIX, IGNORED, SUBLIST, ...) -# -------------------------------------- -# Common implementation for all four m4_map variants. The mismatch in -# the number of () is intentional. PREFIX must supply a form of -# m4_apply, the open `(', and the MACRO to be applied. Each iteration -# then appends `,', the current SUBLIST and the closing `)', then -# recurses to the next SUBLIST. IGNORED is an aid to ending recursion -# efficiently. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([_m4_map], -[m4_if([$#], [2], [], - [$1, [$3])$0([$1], m4_shift2($@))])]) - -# m4_transform(EXPRESSION, ARG...) -# -------------------------------- +# m4_map_args(EXPRESSION, ARG...) +# ------------------------------- # Expand EXPRESSION([ARG]) for each argument. More efficient than -# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_transform], +# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) +# Shorthand for m4_map_args_sep([EXPRESSION(], [)], [], ARG...). +m4_define([m4_map_args], [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], [$#], [1], [], [$#], [2], [$1([$2])[]], - [$1([$2])[]$0([$1], m4_shift2($@))])]) + [_m4_foreach([$1(], [)], $@)])]) -# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) -# -------------------------------------------------------------- +# m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) +# ------------------------------------------------------------- # Perform a pairwise grouping of consecutive ARGs, by expanding # EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the # final argument is expanded with END-EXPR([ARGn]). # # For example: # m4_define([show], [($*)m4_newline])dnl -# m4_transform_pair([show], [], [a], [b], [c], [d], [e])dnl +# m4_map_args_pair([show], [], [a], [b], [c], [d], [e])dnl # => (a,b) # => (c,d) # => (e) # # Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_transform_pair], +m4_define([m4_map_args_pair], [m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])], [$#], [2], [], @@ -1123,19 +1269,124 @@ m4_define([m4_transform_pair], [$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])]) +# m4_map_args_sep([PRE], [POST], [SEP], ARG...) +# --------------------------------------------- +# Expand PRE[ARG]POST for each argument, with SEP between arguments. +m4_define([m4_map_args_sep], +[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], + [$#], [1], [], + [$#], [2], [], + [$#], [3], [], + [$#], [4], [$1[$4]$2[]], + [$1[$4]$2[]_m4_foreach([$3[]$1], [$2], m4_shift3($@))])]) + + +# m4_map_args_w(STRING, [PRE], [POST], [SEP]) +# ------------------------------------------- +# Perform the expansion of PRE[word]POST[] for each word in STRING +# separated by whitespace. More efficient than: +# m4_foreach_w([var], [STRING], [PRE[]m4_defn([var])POST]) +# Additionally, expand SEP between words. +# +# As long as we have to use m4_bpatsubst to split the string, we might +# as well make it also apply PRE and POST; this avoids iteration +# altogether. But we must be careful of any \ in PRE or POST. +# _m4_strip returns a quoted string, but that's okay, since it also +# supplies an empty leading and trailing argument due to our +# intentional whitespace around STRING. We use m4_substr to strip the +# empty elements and remove the extra layer of quoting. +m4_define([m4_map_args_w], +[_$0(_m4_split([ ]m4_flatten([$1])[ ], [[ ]+], + m4_if(m4_index([$2$3$4], [\]), [-1], [[$3[]$4[]$2]], + [m4_bpatsubst([[$3[]$4[]$2]], [\\], [\\\\])])), + m4_len([[]$3[]$4]), m4_len([$4[]$2[]]))]) + +m4_define([_m4_map_args_w], +[m4_substr([$1], [$2], m4_eval(m4_len([$1]) - [$2] - [$3]))]) + + +# m4_stack_foreach(MACRO, FUNC) +# m4_stack_foreach_lifo(MACRO, FUNC) +# ---------------------------------- +# Pass each stacked definition of MACRO to the one-argument macro FUNC. +# m4_stack_foreach proceeds in FIFO order, while m4_stack_foreach_lifo +# processes the topmost definitions first. In addition, FUNC should +# not push or pop definitions of MACRO, and should not expect anything about +# the active definition of MACRO (it will not be the topmost, and may not +# be the one passed to FUNC either). +# +# Some macros simply can't be examined with this method: namely, +# anything involved in the implementation of _m4_stack_reverse. +m4_define([m4_stack_foreach], +[_m4_stack_reverse([$1], [m4_tmp-$1])]dnl +[_m4_stack_reverse([m4_tmp-$1], [$1], [$2(_m4_defn([m4_tmp-$1]))])]) + +m4_define([m4_stack_foreach_lifo], +[_m4_stack_reverse([$1], [m4_tmp-$1], [$2(_m4_defn([m4_tmp-$1]))])]dnl +[_m4_stack_reverse([m4_tmp-$1], [$1])]) + +# m4_stack_foreach_sep(MACRO, [PRE], [POST], [SEP]) +# m4_stack_foreach_sep_lifo(MACRO, [PRE], [POST], [SEP]) +# ------------------------------------------------------ +# Similar to m4_stack_foreach and m4_stack_foreach_lifo, in that every +# definition of a pushdef stack will be visited. But rather than +# passing the definition as a single argument to a macro, this variant +# expands the concatenation of PRE[]definition[]POST, and expands SEP +# between consecutive expansions. Note that m4_stack_foreach([a], [b]) +# is equivalent to m4_stack_foreach_sep([a], [b(], [)]). +m4_define([m4_stack_foreach_sep], +[_m4_stack_reverse([$1], [m4_tmp-$1])]dnl +[_m4_stack_reverse([m4_tmp-$1], [$1], [$2[]_m4_defn([m4_tmp-$1])$3], [$4[]])]) + +m4_define([m4_stack_foreach_sep_lifo], +[_m4_stack_reverse([$1], [m4_tmp-$1], [$2[]_m4_defn([m4_tmp-$1])$3], [$4[]])]dnl +[_m4_stack_reverse([m4_tmp-$1], [$1])]) + + +# _m4_stack_reverse(OLD, NEW, [ACTION], [SEP]) +# -------------------------------------------- +# A recursive worker for pushdef stack manipulation. Destructively +# copy the OLD stack into the NEW, and expanding ACTION for each +# iteration. After the first iteration, SEP is promoted to the front +# of ACTION (note that SEP should include a trailing [] if it is to +# avoid interfering with ACTION). The current definition is examined +# after the NEW has been pushed but before OLD has been popped; this +# order is important, as ACTION is permitted to operate on either +# _m4_defn([OLD]) or _m4_defn([NEW]). Since the operation is +# destructive, this macro is generally used twice, with a temporary +# macro name holding the swapped copy. +m4_define([_m4_stack_reverse], +[m4_ifdef([$1], [m4_pushdef([$2], + _m4_defn([$1]))$3[]_m4_popdef([$1])$0([$1], [$2], [$4$3])])]) + + + ## --------------------------- ## ## 9. More diversion support. ## ## --------------------------- ## -# _m4_divert(DIVERSION-NAME or NUMBER) -# ------------------------------------ +# m4_cleardivert(DIVERSION-NAME...) +# --------------------------------- +# Discard any text in DIVERSION-NAME. +# +# This works even inside m4_expand. +m4_define([m4_cleardivert], +[m4_if([$#], [0], [m4_fatal([$0: missing argument])], + [_m4_divert_raw([-1])m4_undivert($@)_m4_divert_raw( + _m4_divert(_m4_defn([_m4_divert_diversion]), [-]))])]) + + +# _m4_divert(DIVERSION-NAME or NUMBER, [NOWARN]) +# ---------------------------------------------- # If DIVERSION-NAME is the name of a diversion, return its number, -# otherwise if it is a NUMBER return it. +# otherwise if it is a NUMBER return it. Issue a warning about +# the use of a number instead of a name, unless NOWARN is provided. m4_define([_m4_divert], [m4_ifdef([_m4_divert($1)], [m4_indir([_m4_divert($1)])], - [$1])]) + [m4_if([$2], [], [m4_warn([syntax], + [prefer named diversions])])$1])]) # KILL is only used to suppress output. m4_define([_m4_divert(KILL)], -1) @@ -1144,29 +1395,42 @@ m4_define([_m4_divert(KILL)], -1) m4_define([_m4_divert()], 0) -# _m4_divert_n_stack -# ------------------ -# Print m4_divert_stack with newline prepended, if it's nonempty. -m4_define([_m4_divert_n_stack], -[m4_ifdef([m4_divert_stack], [ -_m4_defn([m4_divert_stack])])]) +# m4_divert_stack +# --------------- +# Print the diversion stack, if it's nonempty. The caller is +# responsible for any leading or trailing newline. +m4_define([m4_divert_stack], +[m4_stack_foreach_sep_lifo([_m4_divert_stack], [], [], [ +])]) + + +# m4_divert_stack_push(MACRO-NAME, DIVERSION-NAME) +# ------------------------------------------------ +# Form an entry of the diversion stack from caller MACRO-NAME and +# entering DIVERSION-NAME and push it. +m4_define([m4_divert_stack_push], +[m4_pushdef([_m4_divert_stack], m4_location[: $1: $2])]) # m4_divert(DIVERSION-NAME) # ------------------------- # Change the diversion stream to DIVERSION-NAME. m4_define([m4_divert], -[m4_define([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)]dnl -[m4_builtin([divert], _m4_divert([$1]))]) +[m4_popdef([_m4_divert_stack])]dnl +[m4_define([_m4_divert_diversion], [$1])]dnl +[m4_divert_stack_push([$0], [$1])]dnl +[_m4_divert_raw(_m4_divert([$1]))]) -# m4_divert_push(DIVERSION-NAME) -# ------------------------------ +# m4_divert_push(DIVERSION-NAME, [NOWARN]) +# ---------------------------------------- # Change the diversion stream to DIVERSION-NAME, while stacking old values. +# For internal use only: if NOWARN is not empty, DIVERSION-NAME can be a +# number instead of a name. m4_define([m4_divert_push], -[m4_pushdef([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)]dnl +[m4_divert_stack_push([$0], [$1])]dnl [m4_pushdef([_m4_divert_diversion], [$1])]dnl -[m4_builtin([divert], _m4_divert([$1]))]) +[_m4_divert_raw(_m4_divert([$1], [$2]))]) # m4_divert_pop([DIVERSION-NAME]) @@ -1175,16 +1439,14 @@ m4_define([m4_divert_push], # If specified, verify we left DIVERSION-NAME. # When we pop the last value from the stack, we divert to -1. m4_define([m4_divert_pop], -[m4_ifndef([_m4_divert_diversion], - [m4_fatal([too many m4_divert_pop])])]dnl [m4_if([$1], [], [], [$1], _m4_defn([_m4_divert_diversion]), [], - [m4_fatal([$0($1): diversion mismatch: ]_m4_divert_n_stack)])]dnl -[_m4_popdef([m4_divert_stack], [_m4_divert_diversion])]dnl -[m4_builtin([divert], - m4_ifdef([_m4_divert_diversion], - [_m4_divert(_m4_defn([_m4_divert_diversion]))], - -1))]) + [m4_fatal([$0($1): diversion mismatch: +]m4_divert_stack)])]dnl +[_m4_popdef([_m4_divert_stack], [_m4_divert_diversion])]dnl +[m4_ifdef([_m4_divert_diversion], [], + [m4_fatal([too many m4_divert_pop])])]dnl +[_m4_divert_raw(_m4_divert(_m4_defn([_m4_divert_diversion]), [-]))]) # m4_divert_text(DIVERSION-NAME, CONTENT) @@ -1204,12 +1466,24 @@ m4_define([m4_divert_once], [m4_expand_once([m4_divert_text([$1], [$2])])]) -# m4_undivert(DIVERSION-NAME) -# --------------------------- -# Undivert DIVERSION-NAME. Unlike the M4 version, this only takes a single -# diversion identifier, and should not be used to undivert files. +# _m4_divert_unsafe(DIVERSION-NAME) +# --------------------------------- +# Issue a warning that the attempt to change the current diversion to +# DIVERSION-NAME is unsafe, because this macro is being expanded +# during argument collection of m4_expand. +m4_define([_m4_divert_unsafe], +[m4_fatal([$0: cannot change diversion to `$1' inside m4_expand])]) + + +# m4_undivert(DIVERSION-NAME...) +# ------------------------------ +# Undivert DIVERSION-NAME. Unlike the M4 version, this requires at +# least one DIVERSION-NAME; also, due to support for named diversions, +# this should not be used to undivert files. m4_define([m4_undivert], -[m4_builtin([undivert], _m4_divert([$1]))]) +[m4_if([$#], [0], [m4_fatal([$0: missing argument])], + [$#], [1], [_m4_undivert(_m4_divert([$1]))], + [m4_map_args([$0], $@)])]) ## --------------------------------------------- ## @@ -1227,15 +1501,16 @@ m4_define([m4_undivert], # 1. Implementation of m4_require # =============================== # -# Of course m4_defun AC_PROVIDE's the macro, so that a macro which has +# Of course m4_defun calls m4_provide, so that a macro which has # been expanded is not expanded again when m4_require'd, but the # difficult part is the proper expansion of macros when they are # m4_require'd. # -# The implementation is based on two ideas, (i) using diversions to +# The implementation is based on three ideas, (i) using diversions to # prepare the expansion of the macro and its dependencies (by Franc,ois -# Pinard), and (ii) expand the most recently m4_require'd macros _after_ -# the previous macros (by Axel Thimm). +# Pinard), (ii) expand the most recently m4_require'd macros _after_ +# the previous macros (by Axel Thimm), and (iii) track instances of +# provide before require (by Eric Blake). # # # The first idea: why use diversions? @@ -1247,8 +1522,8 @@ m4_define([m4_undivert], # undivert GROW. To understand why we need several diversions, # consider the following example: # -# | m4_defun([TEST1], [Test...REQUIRE([TEST2])1]) -# | m4_defun([TEST2], [Test...REQUIRE([TEST3])2]) +# | m4_defun([TEST1], [Test...m4_require([TEST2])1]) +# | m4_defun([TEST2], [Test...m4_require([TEST3])2]) # | m4_defun([TEST3], [Test...3]) # # Because m4_require is not required to be first in the outer macros, we @@ -1280,10 +1555,10 @@ m4_define([m4_undivert], # very surprising results in some situations. Let's consider the # following example to explain the bug: # -# | m4_defun([TEST1], [REQUIRE([TEST2a])REQUIRE([TEST2b])]) +# | m4_defun([TEST1], [m4_require([TEST2a])m4_require([TEST2b])]) # | m4_defun([TEST2a], []) -# | m4_defun([TEST2b], [REQUIRE([TEST3])]) -# | m4_defun([TEST3], [REQUIRE([TEST2a])]) +# | m4_defun([TEST2b], [m4_require([TEST3])]) +# | m4_defun([TEST3], [m4_require([TEST2a])]) # | # | AC_INIT # | TEST1 @@ -1318,7 +1593,7 @@ m4_define([m4_undivert], # Starting from 2.50, we use an implementation provided by Axel Thimm. # The idea is simple: the order in which macros are emitted must be the # same as the one in which macros are expanded. (The bug above can -# indeed be described as: a macro has been AC_PROVIDE'd before its +# indeed be described as: a macro has been m4_provide'd before its # dependent, but it is emitted after: the lack of correlation between # emission and expansion order is guilty). # @@ -1369,8 +1644,8 @@ m4_define([m4_undivert], # GROW: # BODY: TEST2a; TEST3; TEST2b: TEST1 # -# The idea is simple, but the implementation is a bit evolved. If you -# are like me, you will want to see the actual functioning of this +# The idea is simple, but the implementation is a bit involved. If +# you are like me, you will want to see the actual functioning of this # implementation to be convinced. The next section gives the full # details. # @@ -1386,7 +1661,7 @@ m4_define([m4_undivert], # You should keep the definitions of _m4_defun_pro, _m4_defun_epi, and # m4_require at hand to follow the steps. # -# This implements tries not to assume that the current diversion is +# This implementation tries not to assume that the current diversion is # BODY, so as soon as a macro (m4_defun'd) is expanded, we first # record the current diversion under the name _m4_divert_dump (denoted # DUMP below for short). This introduces an important difference with @@ -1421,7 +1696,7 @@ m4_define([m4_undivert], # BODY: empty # GROW - 1: TEST2a # diversions: GROW - 1, GROW, BODY |- -# Than the content of the temporary diversion is moved to DUMP and the +# Then the content of the temporary diversion is moved to DUMP and the # temporary diversion is popped. # DUMP: BODY # BODY: TEST2a @@ -1441,7 +1716,7 @@ m4_define([m4_undivert], # BODY: TEST2a # GROW - 2: TEST3 # diversions: GROW - 2, GROW - 1, GROW, BODY |- -# Than the diversion is appended to DUMP, and popped. +# Then the diversion is appended to DUMP, and popped. # DUMP: BODY # BODY: TEST2a; TEST3 # diversions: GROW - 1, GROW, BODY |- @@ -1469,6 +1744,79 @@ m4_define([m4_undivert], # diversions: BODY |- # # +# The third idea: track macros provided before they were required +# --------------------------------------------------------------- +# +# Using just the first two ideas, Autoconf 2.50 through 2.63 still had +# a subtle bug for more than seven years. Let's consider the +# following example to explain the bug: +# +# | m4_defun([TEST1], [1]) +# | m4_defun([TEST2], [2[]m4_require([TEST1])]) +# | m4_defun([TEST3], [3 TEST1 m4_require([TEST2])]) +# | TEST3 +# +# After the prologue of TEST3, we are collecting text in GROW with the +# intent of dumping it in BODY during the epilogue. Next, we +# encounter the direct invocation of TEST1, which provides the macro +# in place in GROW. From there, we encounter a requirement for TEST2, +# which must be collected in a new diversion. While expanding TEST2, +# we encounter a requirement for TEST1, but since it has already been +# expanded, the Axel Thimm algorithm states that we can treat it as a +# no-op. But that would lead to an end result of `2 3 1', meaning +# that we have once again output a macro (TEST2) prior to its +# requirements (TEST1). +# +# The problem can only occur if a single defun'd macro first provides, +# then later indirectly requires, the same macro. Note that directly +# expanding then requiring a macro is okay: because the dependency was +# met, the require phase can be a no-op. For that matter, the outer +# macro can even require two helpers, where the first helper expands +# the macro, and the second helper indirectly requires the macro. +# Out-of-order expansion is only present if the inner macro is +# required by something that will be hoisted in front of where the +# direct expansion occurred. In other words, we must be careful not +# to warn on: +# +# | m4_defun([TEST4], [4]) +# | m4_defun([TEST5], [5 TEST4 m4_require([TEST4])]) +# | TEST5 => 5 4 +# +# or even the more complex: +# +# | m4_defun([TEST6], [6]) +# | m4_defun([TEST7], [7 TEST6]) +# | m4_defun([TEST8], [8 m4_require([TEST6])]) +# | m4_defun([TEST9], [9 m4_require([TEST8])]) +# | m4_defun([TEST10], [10 m4_require([TEST7]) m4_require([TEST9])]) +# | TEST10 => 7 6 8 9 10 +# +# So, to detect whether a require was direct or indirect, m4_defun and +# m4_require track the name of the macro that caused a diversion to be +# created (using the stack _m4_diverting, coupled with an O(1) lookup +# _m4_diverting([NAME])), and m4_provide stores the name associated +# with the diversion at which a macro was provided. A require call is +# direct if it occurs within the same diversion where the macro was +# provided, or if the diversion associated with the providing context +# has been collected. +# +# The implementation of the warning involves tracking the set of +# macros which have been provided since the start of the outermost +# defun'd macro (the set is named _m4_provide). When starting an +# outermost macro, the set is emptied; when a macro is provided, it is +# added to the set; when require expands the body of a macro, it is +# removed from the set; and when a macro is indirectly required, the +# set is checked. If a macro is in the set, then it has been provided +# before it was required, and we satisfy dependencies by expanding the +# macro as if it had never been provided; in the example given above, +# this means we now output `1 2 3 1'. Meanwhile, a warning is issued +# to inform the user that her macros trigger the bug in older autoconf +# versions, and that her output file now contains redundant contents +# (and possibly new problems, if the repeated macro was not +# idempotent). Meanwhile, macros defined by m4_defun_once instead of +# m4_defun are idempotent, avoiding any warning or duplicate output. +# +# # 2. Keeping track of the expansion stack # ======================================= # @@ -1481,36 +1829,37 @@ m4_define([m4_undivert], # performance penalty this is implemented only for m4_defun'd macros, # not for define'd macros. # -# The scheme is simplistic: each time we enter an m4_defun'd macros, -# we prepend its name in m4_expansion_stack, and when we exit the -# macro, we remove it (thanks to pushdef/popdef). +# Each time we enter an m4_defun'd macros, we add a definition in +# _m4_expansion_stack, and when we exit the macro, we remove it (thanks +# to pushdef/popdef). m4_stack_foreach is used to print the expansion +# stack in the rare cases when it's needed. # # In addition, we want to detect circular m4_require dependencies. # Each time we expand a macro FOO we define _m4_expanding(FOO); and # m4_require(BAR) simply checks whether _m4_expanding(BAR) is defined. -# m4_expansion_stack_push(TEXT) -# ----------------------------- -m4_define([m4_expansion_stack_push], -[m4_pushdef([m4_expansion_stack], - [$1]m4_ifdef([m4_expansion_stack], [ -_m4_defn([m4_expansion_stack])]))]) - - -# m4_expansion_stack_pop -# ---------------------- -m4_define([m4_expansion_stack_pop], -[m4_popdef([m4_expansion_stack])]) - +# m4_expansion_stack +# ------------------ +# Expands to the entire contents of the expansion stack. The caller +# must supply a trailing newline. This macro always prints a +# location; check whether _m4_expansion_stack is defined to filter out +# the case when no defun'd macro is in force. +m4_define([m4_expansion_stack], +[m4_stack_foreach_sep_lifo([_$0], [_$0_entry(], [) +])m4_location[: the top level]]) + +# _m4_expansion_stack_entry(MACRO) +# -------------------------------- +# Format an entry for MACRO found on the expansion stack. +m4_define([_m4_expansion_stack_entry], +[_m4_defn([m4_location($1)])[: $1 is expanded from...]]) -# m4_expansion_stack_dump -# ----------------------- -# Dump the expansion stack. -m4_define([m4_expansion_stack_dump], -[m4_ifdef([m4_expansion_stack], - [m4_errprintn(_m4_defn([m4_expansion_stack]))])dnl -m4_errprintn(m4_location[: the top level])]) +# m4_expansion_stack_push(MACRO) +# ------------------------------ +# Form an entry of the expansion stack on entry to MACRO and push it. +m4_define([m4_expansion_stack_push], +[m4_pushdef([_m4_expansion_stack], [$1])]) # _m4_divert(GROW) @@ -1539,13 +1888,13 @@ m4_define([_m4_divert(GROW)], 10000) # This is called frequently, so minimize the number of macro invocations # by avoiding dnl and m4_defn overhead. m4_define([_m4_defun_pro], -m4_do([[m4_ifdef([m4_expansion_stack], [], [_m4_defun_pro_outer[]])]], - [[m4_expansion_stack_push(_m4_defn( - [m4_location($1)])[: $1 is expanded from...])]], - [[m4_pushdef([_m4_expanding($1)])]])) +[m4_ifdef([_m4_expansion_stack], [], [_m4_defun_pro_outer([$1])])]dnl +[m4_expansion_stack_push([$1])m4_pushdef([_m4_expanding($1)])]) m4_define([_m4_defun_pro_outer], -[m4_copy([_m4_divert_diversion], [_m4_divert_dump])m4_divert_push([GROW])]) +[m4_set_delete([_m4_provide])]dnl +[m4_pushdef([_m4_diverting([$1])])m4_pushdef([_m4_diverting], [$1])]dnl +[m4_pushdef([_m4_divert_dump], m4_divnum)m4_divert_push([GROW])]) # _m4_defun_epi(MACRO-NAME) # ------------------------- @@ -1555,46 +1904,103 @@ m4_define([_m4_defun_pro_outer], # This is called frequently, so minimize the number of macro invocations # by avoiding dnl and m4_popdef overhead. m4_define([_m4_defun_epi], -m4_do([[_m4_popdef([_m4_expanding($1)])]], - [[m4_expansion_stack_pop()]], - [[m4_ifdef([m4_expansion_stack], [], [_m4_defun_epi_outer[]])]], - [[m4_provide([$1])]])) +[_m4_popdef([_m4_expanding($1)], [_m4_expansion_stack])]dnl +[m4_ifdef([_m4_expansion_stack], [], [_m4_defun_epi_outer([$1])])]dnl +[m4_provide([$1])]) m4_define([_m4_defun_epi_outer], -[_m4_undefine([_m4_divert_dump])m4_divert_pop([GROW])m4_undivert([GROW])]) +[_m4_popdef([_m4_divert_dump], [_m4_diverting([$1])], [_m4_diverting])]dnl +[m4_divert_pop([GROW])m4_undivert([GROW])]) -# m4_defun(NAME, EXPANSION) -# ------------------------- -# Define a macro which automatically provides itself. Add machinery -# so the macro automatically switches expansion to the diversion -# stack if it is not already using it. In this case, once finished, -# it will bring back all the code accumulated in the diversion stack. -# This, combined with m4_require, achieves the topological ordering of -# macros. We don't use this macro to define some frequently called -# macros that are not involved in ordering constraints, to save m4 -# processing. +# _m4_divert_dump +# --------------- +# If blank, we are outside of any defun'd macro. Otherwise, expands +# to the diversion number (not name) where require'd macros should be +# moved once completed. +m4_define([_m4_divert_dump]) + + +# m4_divert_require(DIVERSION, NAME-TO-CHECK, [BODY-TO-EXPAND]) +# ------------------------------------------------------------- +# Same as m4_require, but BODY-TO-EXPAND goes into the named DIVERSION; +# requirements still go in the current diversion though. +# +m4_define([m4_divert_require], +[m4_ifdef([_m4_expanding($2)], + [m4_fatal([$0: circular dependency of $2])])]dnl +[m4_if(_m4_divert_dump, [], + [m4_fatal([$0($2): cannot be used outside of an m4_defun'd macro])])]dnl +[m4_provide_if([$2], [], + [_m4_require_call([$2], [$3], _m4_divert([$1], [-]))])]) + + +# m4_defun(NAME, EXPANSION, [MACRO = m4_define]) +# ---------------------------------------------- +# Define a macro NAME which automatically provides itself. Add +# machinery so the macro automatically switches expansion to the +# diversion stack if it is not already using it, prior to EXPANSION. +# In this case, once finished, it will bring back all the code +# accumulated in the diversion stack. This, combined with m4_require, +# achieves the topological ordering of macros. We don't use this +# macro to define some frequently called macros that are not involved +# in ordering constraints, to save m4 processing. +# +# MACRO is an undocumented argument; when set to m4_pushdef, and NAME +# is already defined, the new definition is added to the pushdef +# stack, rather than overwriting the current definition. It can thus +# be used to write self-modifying macros, which pop themselves to a +# previously m4_define'd definition so that subsequent use of the +# macro is faster. m4_define([m4_defun], -[m4_define([m4_location($1)], m4_location)dnl -m4_define([$1], - [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])]) +[m4_define([m4_location($1)], m4_location)]dnl +[m4_default([$3], [m4_define])([$1], + [_m4_defun_pro(]m4_dquote($[0])[)$2[]_m4_defun_epi(]m4_dquote($[0])[)])]) + + +# m4_defun_init(NAME, INIT, COMMON) +# --------------------------------- +# Like m4_defun, but split EXPANSION into two portions: INIT which is +# done only the first time NAME is invoked, and COMMON which is +# expanded every time. +# +# For now, the COMMON definition is always m4_define'd, giving an even +# lighter-weight definition. m4_defun allows self-providing, but once +# a macro is provided, m4_require no longer cares if it is m4_define'd +# or m4_defun'd. m4_defun also provides location tracking to identify +# dependency bugs, but once the INIT has been expanded, we know there +# are no dependency bugs. However, if a future use needs COMMON to be +# m4_defun'd, we can add a parameter, similar to the third parameter +# to m4_defun. +m4_define([m4_defun_init], +[m4_define([$1], [$3[]])m4_defun([$1], + [$2[]_m4_popdef(]m4_dquote($[0])[)m4_indir(]m4_dquote($[0])dnl +[m4_if(]m4_dquote($[#])[, [0], [], ]m4_dquote([,$]@)[))], [m4_pushdef])]) # m4_defun_once(NAME, EXPANSION) # ------------------------------ -# As m4_defun, but issues the EXPANSION only once, and warns if used -# several times. +# Like m4_defun, but guarantee that EXPANSION only happens once +# (thereafter, using NAME is a no-op). +# +# If _m4_divert_dump is empty, we are called at the top level; +# otherwise, we must ensure that we are required in front of the +# current defun'd macro. Use a helper macro so that EXPANSION need +# only occur once in the definition of NAME, since it might be large. m4_define([m4_defun_once], -[m4_define([m4_location($1)], m4_location)dnl -m4_define([$1], - [m4_provide_if([$1], - [m4_warn([syntax], [$1 invoked multiple times])], - [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])]) +[m4_define([m4_location($1)], m4_location)]dnl +[m4_define([$1], [_m4_defun_once([$1], [$2], m4_if(_m4_divert_dump, [], + [[_m4_defun_pro([$1])m4_unquote(], [)_m4_defun_epi([$1])]], +m4_ifdef([_m4_diverting([$1])], [-]), [-], [[m4_unquote(], [)]], + [[_m4_require_call([$1],], [, _m4_divert_dump)]]))])]) + +m4_define([_m4_defun_once], +[m4_pushdef([$1])$3[$2[]m4_provide([$1])]$4]) # m4_pattern_forbid(ERE, [WHY]) # ----------------------------- -# Declare that no token matching the forbidden extended regular +# Declare that no token matching the forbidden perl extended regular # expression ERE should be seen in the output unless... m4_define([m4_pattern_forbid], []) @@ -1602,7 +2008,7 @@ m4_define([m4_pattern_forbid], []) # m4_pattern_allow(ERE) # --------------------- # ... that token also matches the allowed extended regular expression ERE. -# Both used via traces. +# Both used via traces, by autom4te post-processing. m4_define([m4_pattern_allow], []) @@ -1623,18 +2029,19 @@ m4_define([m4_before], # ----------------------------------------------------------- # If NAME-TO-CHECK has never been expanded (actually, if it is not # m4_provide'd), expand BODY-TO-EXPAND *before* the current macro -# expansion. Once expanded, emit it in _m4_divert_dump. Keep track -# of the m4_require chain in m4_expansion_stack. +# expansion; follow the expansion with a newline. Once expanded, emit +# it in _m4_divert_dump. Keep track of the m4_require chain in +# _m4_expansion_stack. # # The normal cases are: # # - NAME-TO-CHECK == BODY-TO-EXPAND # Which you can use for regular macros with or without arguments, e.g., # m4_require([AC_PROG_CC], [AC_PROG_CC]) -# m4_require([AC_CHECK_HEADERS(limits.h)], [AC_CHECK_HEADERS(limits.h)]) +# m4_require([AC_CHECK_HEADERS(threads.h)], [AC_CHECK_HEADERS(threads.h)]) # which is just the same as # m4_require([AC_PROG_CC]) -# m4_require([AC_CHECK_HEADERS(limits.h)]) +# m4_require([AC_CHECK_HEADERS(threads.h)]) # # - BODY-TO-EXPAND == m4_indir([NAME-TO-CHECK]) # In the case of macros with irregular names. For instance: @@ -1655,34 +2062,53 @@ m4_define([m4_before], # This is called frequently, so minimize the number of macro invocations # by avoiding dnl and other overhead on the common path. m4_define([m4_require], -m4_do([[m4_ifdef([_m4_expanding($1)], - [m4_fatal([$0: circular dependency of $1])])]], - [[m4_ifdef([_m4_divert_dump], [], - [m4_fatal([$0($1): cannot be used outside of an ]dnl -m4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])]], - [[m4_provide_if([$1], - [], - [_m4_require_call([$1], [$2])])]])) - - -# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK]) +[m4_ifdef([_m4_expanding($1)], + [m4_fatal([$0: circular dependency of $1])])]dnl +[m4_if(_m4_divert_dump, [], + [m4_fatal([$0($1): cannot be used outside of an ]dnl +m4_if([$0], [m4_require], [[m4_defun]], [[AC_DEFUN]])['d macro])])]dnl +[m4_provide_if([$1], [m4_set_contains([_m4_provide], [$1], + [_m4_require_check([$1], _m4_defn([m4_provide($1)]), [$0])], [m4_ignore])], + [_m4_require_call])([$1], [$2], _m4_divert_dump)]) + + +# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK], +# DIVERSION-NUMBER) # ----------------------------------------------------------------- -# If m4_require decides to expand the body, it calls this macro. +# If m4_require decides to expand the body, it calls this macro. The +# expansion is placed in DIVERSION-NUMBER. # # This is called frequently, so minimize the number of macro invocations # by avoiding dnl and other overhead on the common path. +# The use of a witness macro protecting the warning allows aclocal +# to silence any warnings when probing for what macros are required +# and must therefore be located, when using the Autoconf-without-aclocal-m4 +# autom4te language. For more background, see: +# https://lists.gnu.org/archive/html/automake-patches/2012-11/msg00035.html m4_define([_m4_require_call], -m4_do([[m4_define([_m4_divert_grow], m4_decr(_m4_divert_grow))]], - [[m4_divert_push(_m4_divert_grow)]], - [[m4_default([$2], [$1]) -m4_provide_if([$1], - [], - [m4_warn([syntax], - [$1 is m4_require'd but not m4_defun'd])])]], - [[m4_divert(_m4_defn([_m4_divert_dump]))]], - [[m4_undivert(_m4_divert_grow)]], - [[m4_divert_pop(_m4_divert_grow)]], - [[m4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))]])) +[m4_pushdef([_m4_divert_grow], m4_decr(_m4_divert_grow))]dnl +[m4_pushdef([_m4_diverting([$1])])m4_pushdef([_m4_diverting], [$1])]dnl +[m4_divert_push(_m4_divert_grow, [-])]dnl +[m4_if([$2], [], [$1], [$2]) +m4_provide_if([$1], [m4_set_remove([_m4_provide], [$1])], + [m4_ifndef([m4_require_silent_probe], + [m4_warn([syntax], [$1 is m4_require'd but not m4_defun'd])])])]dnl +[_m4_divert_raw($3)_m4_undivert(_m4_divert_grow)]dnl +[m4_divert_pop(_m4_divert_grow)_m4_popdef([_m4_divert_grow], +[_m4_diverting([$1])], [_m4_diverting])]) + + +# _m4_require_check(NAME-TO-CHECK, OWNER, CALLER) +# ----------------------------------------------- +# NAME-TO-CHECK has been identified as previously expanded in the +# diversion owned by OWNER. If this is a problem, warn on behalf of +# CALLER and return _m4_require_call; otherwise return m4_ignore. +m4_define([_m4_require_check], +[m4_if(_m4_defn([_m4_diverting]), [$2], [m4_ignore], + m4_ifdef([_m4_diverting([$2])], [-]), [-], [m4_warn([syntax], + [$3: `$1' was expanded before it was required +https://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required])_m4_require_call], + [m4_ignore])]) # _m4_divert_grow @@ -1696,15 +2122,17 @@ m4_define([_m4_divert_grow], _m4_divert([GROW])) # If TEXT has never been expanded, expand it *here*. Use WITNESS as # as a memory that TEXT has already been expanded. m4_define([m4_expand_once], -[m4_provide_if(m4_ifval([$2], [[$2]], [[$1]]), +[m4_provide_if(m4_default_quoted([$2], [$1]), [], - [m4_provide(m4_ifval([$2], [[$2]], [[$1]]))[]$1])]) + [m4_provide(m4_default_quoted([$2], [$1]))[]$1])]) # m4_provide(MACRO-NAME) # ---------------------- m4_define([m4_provide], -[m4_define([m4_provide($1)])]) +[m4_ifdef([m4_provide($1)], [], +[m4_set_add([_m4_provide], [$1], [m4_define([m4_provide($1)], + m4_ifdef([_m4_diverting], [_m4_defn([_m4_diverting])]))])])]) # m4_provide_if(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) @@ -1750,7 +2178,7 @@ m4_defn([m4_cr_digits])dnl # m4_cr_symbols1 # m4_cr_symbols2 -# ------------------------------- +# -------------- m4_define([m4_cr_symbols1], m4_defn([m4_cr_Letters])dnl _) @@ -1771,13 +2199,16 @@ m4_defn([m4_cr_digits])dnl # characters via m4_translit must deal with the fact that m4_translit does # not add quotes to the output. # +# In EBCDIC, $ is immediately followed by *, which leads to problems +# if m4_cr_all is inlined into a macro definition; so swap them. +# # It is mainly useful in generating inverted character range maps, for use # in places where m4_translit is faster than an equivalent m4_bpatsubst; # the regex `[^a-z]' is equivalent to: # m4_translit(m4_dquote(m4_defn([m4_cr_all])), [a-z]) m4_define([m4_cr_all], m4_translit(m4_dquote(m4_format(m4_dquote(m4_for( - ,1,255,,[[%c]]))m4_for([i],1,255,,[,i]))), [-])-) + ,1,255,,[[%c]]))m4_for([i],1,255,,[,i]))), [$*-], [*$])-) # _m4_define_cr_not(CATEGORY) @@ -1807,11 +2238,12 @@ _m4_define_cr_not([symbols1]) _m4_define_cr_not([symbols2]) -# m4_newline -# ---------- -# Expands to a newline. Exists for formatting reasons. +# m4_newline([STRING]) +# -------------------- +# Expands to a newline, possibly followed by STRING. Exists mostly for +# formatting reasons. m4_define([m4_newline], [ -]) +$1]) # m4_re_escape(STRING) @@ -1848,16 +2280,15 @@ m4_defn([m4_re_string])dnl # # Rather than expand the m4_defn each time, we inline them up front. m4_define([m4_tolower], -[m4_translit([$1], ]m4_dquote(m4_defn([m4_cr_LETTERS]))[, - ]m4_dquote(m4_defn([m4_cr_letters]))[)]) +[m4_translit([[$1]], ]m4_dquote(m4_defn([m4_cr_LETTERS]))[, + ]m4_dquote(m4_defn([m4_cr_letters]))[)]) m4_define([m4_toupper], -[m4_translit([$1], ]m4_dquote(m4_defn([m4_cr_letters]))[, - ]m4_dquote(m4_defn([m4_cr_LETTERS]))[)]) +[m4_translit([[$1]], ]m4_dquote(m4_defn([m4_cr_letters]))[, + ]m4_dquote(m4_defn([m4_cr_LETTERS]))[)]) # m4_split(STRING, [REGEXP]) # -------------------------- -# # Split STRING into an m4 list of quoted elements. The elements are # quoted with [ and ]. Beginning spaces and end spaces *are kept*. # Use m4_strip to remove them. @@ -1886,16 +2317,38 @@ m4_define([m4_toupper], # so avoid unnecessary dnl inside the definition. m4_define([m4_split], [m4_if([$1], [], [], - [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], [_$0($@)])], - [$2], [], [_$0([$1], [[ ]+])], - [_$0($@)])]) + [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], + [_$0([$1], [$2], [, ])])], + [$2], [], [_$0([$1], [[ ]+], [, ])], + [_$0([$1], [$2], [, ])])]) m4_define([_m4_split], [m4_changequote([-=<{(],[)}>=-])]dnl [[m4_bpatsubst(-=<{(-=<{($1)}>=-)}>=-, -=<{($2)}>=-, - -=<{(], [)}>=-)]m4_changequote([, ])]) + -=<{(]$3[)}>=-)]m4_changequote([, ])]) +# m4_chomp(STRING) +# m4_chomp_all(STRING) +# -------------------- +# Return STRING quoted, but without a trailing newline. m4_chomp +# removes at most one newline, while m4_chomp_all removes all +# consecutive trailing newlines. Embedded newlines are not touched, +# and a trailing backslash-newline leaves just a trailing backslash. +# +# m4_bregexp is slower than m4_index, and we don't always want to +# remove all newlines; hence the two variants. We massage characters +# to give a nicer pattern to match, particularly since m4_bregexp is +# line-oriented. Both versions must guarantee a match, to avoid bugs +# with precision -1 in m4_format in older m4. +m4_define([m4_chomp], +[m4_format([[%.*s]], m4_index(m4_translit([[$1]], [ +/.], [/ ])[./.], [/.]), [$1])]) + +m4_define([m4_chomp_all], +[m4_format([[%.*s]], m4_bregexp(m4_translit([[$1]], [ +/], [/ ]), [/*$]), [$1])]) + # m4_flatten(STRING) # ------------------ @@ -2004,20 +2457,14 @@ m4_define([_m4_joinall], # m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3]) # => a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3 # -# In order to have the correct number of SEPARATORs, we use a temporary -# variable that redefines itself after the first use. We must use defn -# rather than overquoting in case PREFIX or SUFFIX contains $1, but use -# _m4_defn for speed. Likewise, we compute the m4_shift3 only once, -# rather than in each iteration of the outer m4_foreach. +# This definition is a bit hairy; the thing to realize is that we want +# to construct m4_map_args_sep([[prefix$3]], [], [[$1]], m4_shift3($@)) +# as the inner loop, using each prefix generated by the outer loop, +# and without recalculating m4_shift3 every outer iteration. m4_define([m4_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([m4_Separator], [m4_define([m4_Separator], - _m4_defn([m4_echo]))])]]dnl -[[m4_foreach([m4_Prefix], [$2], - [m4_foreach([m4_Suffix], ]m4_dquote(m4_dquote(m4_shift3($@)))[, - [m4_Separator([$1])[]_m4_defn([m4_Prefix])[$3]_m4_defn( - [m4_Suffix])])])]]dnl -[[_m4_popdef([m4_Separator])])]) +[m4_if([$2], [], [], m4_eval([$# > 3]), [1], +[m4_map_args_sep([m4_map_args_sep(m4_dquote(], [)[[$3]], [], [[$1]],]]]dnl +[m4_dquote(m4_dquote(m4_shift3($@)))[[)], [[$1]], $2)])]) # m4_append(MACRO-NAME, STRING, [SEPARATOR]) @@ -2106,8 +2553,37 @@ m4_define([_m4_append_uniq], # # Use _m4_defn for speed. m4_define([m4_append_uniq_w], -[m4_foreach_w([m4_Word], [$2], - [_m4_append_uniq([$1], _m4_defn([m4_Word]), [ ])])]) +[m4_map_args_w([$2], [_m4_append_uniq([$1],], [, [ ])])]) + + +# m4_escape(STRING) +# ----------------- +# Output quoted STRING, but with embedded #, $, [ and ] turned into +# quadrigraphs. +# +# It is faster to check if STRING is already good using m4_translit +# than to blindly perform four m4_bpatsubst. +# +# Because the translit is stripping quotes, it must also neutralize +# anything that might be in a macro name, as well as comments, commas, +# and parentheses. All the problem characters are unified so that a +# single m4_index can scan the result. +# +# Rather than expand m4_defn every time m4_escape is expanded, we +# inline its expansion up front. +m4_define([m4_escape], +[m4_if(m4_index(m4_translit([$1], + [[]#,()]]m4_dquote(m4_defn([m4_cr_symbols2]))[, [$$$]), [$]), + [-1], [m4_echo], [_$0])([$1])]) + +m4_define([_m4_escape], +[m4_changequote([-=<{(],[)}>=-])]dnl +[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst(m4_bpatsubst( + -=<{(-=<{(-=<{(-=<{(-=<{($1)}>=-)}>=-)}>=-)}>=-)}>=-, + -=<{(#)}>=-, -=<{(@%:@)}>=-), + -=<{(\[)}>=-, -=<{(@<:@)}>=-), + -=<{(\])}>=-, -=<{(@:>@)}>=-), + -=<{(\$)}>=-, -=<{(@S|@)}>=-)m4_changequote([,])]) # m4_text_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH]) @@ -2119,7 +2595,9 @@ m4_define([m4_append_uniq_w], # FIRST-PREFIX will be left alone on the first line. # # No expansion occurs on the contents STRING, PREFIX, or FIRST-PREFIX, -# although quadrigraphs are correctly recognized. +# although quadrigraphs are correctly recognized. More precisely, +# you may redefine m4_qlen to recognize whatever escape sequences that +# you will post-process. # # Typical outputs are: # @@ -2158,8 +2636,9 @@ m4_define([m4_append_uniq_w], # with m4_do, to avoid time wasted on dnl during expansion (since this is # already a time-consuming macro). m4_define([m4_text_wrap], -[_$0([$1], [$2], m4_if([$3], [], [[$2]], [[$3]]), - m4_if([$4], [], [79], [[$4]]))]) +[_$0(m4_escape([$1]), [$2], m4_default_quoted([$3], [$2]), + m4_default_quoted([$4], [79]))]) + m4_define([_m4_text_wrap], m4_do(dnl set up local variables, to avoid repeated calculations [[m4_pushdef([m4_Indent], m4_qlen([$2]))]], @@ -2174,22 +2653,21 @@ dnl prefix1 shorter: pad to length of prefix, and reset cursor [$2]m4_define([m4_Cursor], m4_Indent)], [m4_format([%*s], m4_max([0], m4_eval(m4_Indent - m4_Cursor)), [])m4_define([m4_Cursor], m4_Indent)])]], -dnl now, for each word, compute the curser after the word is output, then +dnl now, for each word, compute the cursor after the word is output, then dnl check if the cursor would exceed the wrap column dnl if so, reset cursor, and insert newline and prefix dnl if not, insert the separator (usually a space) dnl either way, insert the word -[[m4_foreach_w([m4_Word], [$1], - [m4_define([m4_Cursor], - m4_eval(m4_Cursor + m4_qlen(_m4_defn([m4_Word])) - + 1))m4_if(m4_eval(m4_Cursor > ([$4])), - [1], [m4_define([m4_Cursor], - m4_eval(m4_Indent + m4_qlen(_m4_defn([m4_Word])) + 1)) -[$2]], - [m4_Separator[]])_m4_defn([m4_Word])])]], -dnl finally, clean up the local variabls +[[m4_map_args_w([$1], [$0_word(], [, [$2], [$4])])]], +dnl finally, clean up the local variables [[_m4_popdef([m4_Separator], [m4_Cursor], [m4_Indent])]])) +m4_define([_m4_text_wrap_word], +[m4_define([m4_Cursor], m4_eval(m4_Cursor + m4_qlen([$1]) + 1))]dnl +[m4_if(m4_eval(m4_Cursor > ([$3])), + [1], [m4_define([m4_Cursor], m4_eval(m4_Indent + m4_qlen([$1]) + 1)) +[$2]], + [m4_Separator[]])[$1]]) # m4_text_box(MESSAGE, [FRAME-CHARACTER = `-']) # --------------------------------------------- @@ -2198,36 +2676,50 @@ dnl finally, clean up the local variabls # ## MESSAGE ## # ## ------- ## # using FRAME-CHARACTER in the border. +# +# Quadrigraphs are correctly recognized. More precisely, you may +# redefine m4_qlen to recognize whatever escape sequences that you +# will post-process. m4_define([m4_text_box], [m4_pushdef([m4_Border], - m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []), - [ ], m4_if([$2], [], [[-]], [[$2]])))dnl -@%:@@%:@ m4_Border @%:@@%:@ -@%:@@%:@ $1 @%:@@%:@ -@%:@@%:@ m4_Border @%:@@%:@_m4_popdef([m4_Border])dnl -]) + m4_translit(m4_format([[[%*s]]], m4_decr(m4_qlen(_m4_expand([$1 +]))), []), [ ], m4_default_quoted([$2], [-])))]dnl +[[##] _m4_defn([m4_Border]) [##] +[##] $1 [##] +[##] _m4_defn([m4_Border]) [##]_m4_popdef([m4_Border])]) # m4_qlen(STRING) # --------------- # Expands to the length of STRING after autom4te converts all quadrigraphs. # -# Avoid bpatsubsts for the common case of no quadrigraphs. +# If you use some other means of post-processing m4 output rather than +# autom4te, then you may redefine this macro to recognize whatever +# escape sequences your post-processor will handle. For that matter, +# m4_define([m4_qlen], m4_defn([m4_len])) is sufficient if you don't +# do any post-processing. +# +# Avoid bpatsubsts for the common case of no quadrigraphs. Cache +# results, as configure scripts tend to ask about lengths of common +# strings like `/*' and `*/' rather frequently. Minimize the number +# of times that $1 occurs in m4_qlen, so there is less text to parse +# on a cache hit. m4_define([m4_qlen], -[m4_if(m4_index([$1], [@]), [-1], [m4_len([$1])], - [m4_len(m4_bpatsubst([[$1]], - [@\(\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&t@\)], - [\3]))])]) - - -# m4_qdelta(STRING) -# ----------------- -# Expands to the net change in the length of STRING from autom4te converting the -# quadrigraphs in STRING. This number is always negative or zero. -m4_define([m4_qdelta], -[m4_eval(m4_qlen([$1]) - m4_len([$1]))]) - - +[m4_ifdef([$0-$1], [_m4_defn([$0-]], [_$0(])[$1])]) +m4_define([_m4_qlen], +[m4_define([m4_qlen-$1], +m4_if(m4_index([$1], [@]), [-1], [m4_len([$1])], + [m4_len(m4_bpatsubst([[$1]], + [@\(\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&t@\)], + [\3]))]))_m4_defn([m4_qlen-$1])]) + +# m4_copyright_condense(TEXT) +# --------------------------- +# Condense the copyright notice in TEXT to only display the final +# year, wrapping the results to fit in 80 columns. +m4_define([m4_copyright_condense], +[m4_text_wrap(m4_bpatsubst(m4_flatten([[$1]]), +[(C)[- ,0-9]*\([1-9][0-9][0-9][0-9]\)], [(C) \1]))]) ## ----------------------- ## ## 13. Number processing. ## @@ -2346,9 +2838,10 @@ m4_define([m4_sign], # Nl -> (N+1).-1.(l#) # # for example: -# [2.14a] -> [2.14+1.-1.[0r36:a]] -> 2.15.-1.10 -# [2.14b] -> [2.15+1.-1.[0r36:b]] -> 2.15.-1.11 -# [2.61aa.b] -> [2.61+1.-1.[0r36:aa],+1.-1.[0r36:b]] -> 2.62.-1.370.1.-1.11 +# [2.14a] -> [0,2,14+1,-1,[0r36:a]] -> 2.15.-1.10 +# [2.14b] -> [0,2,15+1,-1,[0r36:b]] -> 2.15.-1.11 +# [2.61aa.b] -> [0,2.61,1,-1,[0r36:aa],+1,-1,[0r36:b]] -> 2.62.-1.370.1.-1.11 +# [08] -> [0,[0r10:0]8] -> 8 # # This macro expects reasonable version numbers, but can handle double # letters and does not expand any macros. Original version strings can @@ -2356,15 +2849,14 @@ m4_define([m4_sign], # # Inline constant expansions, to avoid m4_defn overhead. # _m4_version_unletter is the real workhorse used by m4_version_compare, -# but since [0r36:a] is less readable than 10, we provide a wrapper for -# human use. +# but since [0r36:a] and commas are less readable than 10 and dots, we +# provide a wrapper for human use. m4_define([m4_version_unletter], -[m4_map_sep([m4_eval], [.], - m4_dquote(m4_dquote_elt(m4_unquote(_$0([$1])))))]) +[m4_substr(m4_map_args([.m4_eval], m4_unquote(_$0([$1]))), [3])]) m4_define([_m4_version_unletter], -[m4_bpatsubst(m4_translit([[[$1]]], [.-], [,,]),]dnl +[m4_bpatsubst(m4_bpatsubst(m4_translit([[[[0,$1]]]], [.-], [,,]),]dnl m4_dquote(m4_dquote(m4_defn([m4_cr_Letters])))[[+], - [+1,-1,[0r36:\&]])]) + [+1,-1,[0r36:\&]]), [,0], [,[0r10:0]])]) # m4_version_compare(VERSION-1, VERSION-2) @@ -2519,29 +3011,26 @@ m4_define([m4_set_contains], # Use _m4_popdef for speed. The existence of _m4_set_cleanup($1) # determines which version of _1 helper we use. m4_define([m4_set_contents], -[m4_ifdef([_m4_set_cleanup($1)], [_$0_1c], [_$0_1])([$1])_$0_2([$1], - [_m4_defn([_m4_set_($1)])], [[$2]])]) +[m4_set_map_sep([$1], [], [], [[$2]])]) # _m4_set_contents_1(SET) # _m4_set_contents_1c(SET) -# _m4_set_contents_2(SET, SEP, PREP) -# ---------------------------------- -# Expand to a list of quoted elements currently in the set, separated -# by SEP, and moving PREP in front of SEP on recursion. To avoid -# nesting limit restrictions, the algorithm must be broken into two -# parts; _1 destructively copies the stack in reverse into -# _m4_set_($1), producing no output; then _2 destructively copies -# _m4_set_($1) back into the stack in reverse. SEP is expanded while -# _m4_set_($1) contains the current element, so a SEP containing -# _m4_defn([_m4_set_($1)]) can produce output in the order the set was -# created. Behavior is undefined if SEP tries to recursively list or -# modify SET in any way other than calling m4_set_remove on the -# current element. Use _1 if all entries in the stack are guaranteed -# to be in the set, and _1c to prune removed entries. Uses _m4_defn -# and _m4_popdef for speed. +# _m4_set_contents_2(SET, [PRE], [POST], [SEP]) +# --------------------------------------------- +# Expand to a list of quoted elements currently in the set, each +# surrounded by PRE and POST, and moving SEP in front of PRE on +# recursion. To avoid nesting limit restrictions, the algorithm must +# be broken into two parts; _1 destructively copies the stack in +# reverse into _m4_set_($1), producing no output; then _2 +# destructively copies _m4_set_($1) back into the stack in reverse. +# If no elements were deleted, then this visits the set in the order +# that elements were inserted. Behavior is undefined if PRE/POST/SEP +# tries to recursively list or modify SET in any way other than +# calling m4_set_remove on the current element. Use _1 if all entries +# in the stack are guaranteed to be in the set, and _1c to prune +# removed entries. Uses _m4_defn and _m4_popdef for speed. m4_define([_m4_set_contents_1], -[m4_ifdef([_m4_set([$1])], [m4_pushdef([_m4_set_($1)], - _m4_defn([_m4_set([$1])]))_m4_popdef([_m4_set([$1])])$0([$1])])]) +[_m4_stack_reverse([_m4_set([$1])], [_m4_set_($1)])]) m4_define([_m4_set_contents_1c], [m4_ifdef([_m4_set([$1])], @@ -2552,8 +3041,8 @@ m4_define([_m4_set_contents_1c], [_m4_popdef([_m4_set_cleanup($1)])])]) m4_define([_m4_set_contents_2], -[m4_ifdef([_m4_set_($1)], [m4_pushdef([_m4_set([$1])], - _m4_defn([_m4_set_($1)]))$2[]_m4_popdef([_m4_set_($1)])$0([$1], [$3$2])])]) +[_m4_stack_reverse([_m4_set_($1)], [_m4_set([$1])], + [$2[]_m4_defn([_m4_set_($1)])$3], [$4[]])]) # m4_set_delete(SET) # ------------------ @@ -2578,12 +3067,12 @@ m4_define([m4_set_delete], # arguments, such as for m4_join, or wrapped inside quotes for use in # m4_foreach. Order of the output is not guaranteed. # -# Short-circuit the idempotence relation. Use _m4_defn for speed. +# Short-circuit the idempotence relation. m4_define([m4_set_difference], -[m4_if([$1], [$2], [], - [m4_set_foreach([$1], [_m4_element], - [m4_set_contains([$2], _m4_defn([_m4_element]), [], - [,_m4_defn([_m4_element])])])])]) +[m4_if([$1], [$2], [], [m4_set_map_sep([$1], [_$0([$2],], [)])])]) + +m4_define([_m4_set_difference], +[m4_set_contains([$1], [$2], [], [,[$2]])]) # m4_set_dump(SET, [SEP]) # ----------------------- @@ -2601,9 +3090,9 @@ m4_define([m4_set_dump], [_m4_popdef([_m4_set_size($1)])])m4_ifdef([_m4_set_cleanup($1)], [_$0_check], [_$0])([$1], [], [$2])]) -# _m4_set_dump(SET, SEP, PREP) -# _m4_set_dump_check(SET, SEP, PREP) -# ---------------------------------- +# _m4_set_dump(SET, [SEP], [PREP]) +# _m4_set_dump_check(SET, [SEP], [PREP]) +# -------------------------------------- # Print SEP and the current element, then delete the element and # recurse with empty SEP changed to PREP. The check variant checks # whether the element has been previously removed. Use _m4_defn and @@ -2637,9 +3126,8 @@ m4_define([m4_set_empty], # guaranteed. This is faster than the corresponding m4_foreach([VAR], # m4_indir([m4_dquote]m4_set_listc([SET])), [ACTION]) m4_define([m4_set_foreach], -[m4_pushdef([$2])m4_ifdef([_m4_set_cleanup($1)], - [_m4_set_contents_1c], [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [m4_define([$2], _m4_defn([_m4_set_($1)]))$3[]])m4_popdef([$2])]) +[m4_pushdef([$2])m4_set_map_sep([$1], +[m4_define([$2],], [)$3])m4_popdef([$2])]) # m4_set_intersection(SET1, SET2) # ------------------------------- @@ -2650,13 +3138,14 @@ m4_define([m4_set_foreach], # m4_foreach. Order of the output is not guaranteed. # # Iterate over the smaller set, and short-circuit the idempotence -# relation. Use _m4_defn for speed. +# relation. m4_define([m4_set_intersection], [m4_if([$1], [$2], [m4_set_listc([$1])], m4_eval(m4_set_size([$2]) < m4_set_size([$1])), [1], [$0([$2], [$1])], - [m4_set_foreach([$1], [_m4_element], - [m4_set_contains([$2], _m4_defn([_m4_element]), - [,_m4_defn([_m4_element])])])])]) + [m4_set_map_sep([$1], [_$0([$2],], [)])])]) + +m4_define([_m4_set_intersection], +[m4_set_contains([$1], [$2], [,[$2]])]) # m4_set_list(SET) # m4_set_listc(SET) @@ -2668,14 +3157,30 @@ m4_define([m4_set_intersection], # containing only the empty string; with m4_set_listc, a leading comma # is output if there are any elements. m4_define([m4_set_list], -[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c], - [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [_m4_defn([_m4_set_($1)])], [,])]) +[m4_set_map_sep([$1], [], [], [,])]) m4_define([m4_set_listc], +[m4_set_map_sep([$1], [,])]) + +# m4_set_map(SET, ACTION) +# ----------------------- +# For each element of SET, expand ACTION with a single argument of the +# current element. ACTION should not recursively list SET's contents, +# add elements to SET, nor delete any element from SET except the one +# passed as an argument. The order that the elements are visited in +# is not guaranteed. This is faster than either of the corresponding +# m4_map_args([ACTION]m4_set_listc([SET])) +# m4_set_foreach([SET], [VAR], [ACTION(m4_defn([VAR]))]) +m4_define([m4_set_map], +[m4_set_map_sep([$1], [$2(], [)])]) + +# m4_set_map_sep(SET, [PRE], [POST], [SEP]) +# ----------------------------------------- +# For each element of SET, expand PRE[value]POST[], and expand SEP +# between elements. +m4_define([m4_set_map_sep], [m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c], - [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [,_m4_defn([_m4_set_($1)])])]) + [_m4_set_contents_1])([$1])_m4_set_contents_2($@)]) # m4_set_remove(SET, VALUE, [IF-PRESENT], [IF-ABSENT]) # ---------------------------------------------------- @@ -2686,7 +3191,7 @@ m4_define([m4_set_listc], # # Optimize if the element being removed is the most recently added, # since defining _m4_set_cleanup($1) slows down so many other macros. -# In particular, this plays well with m4_set_foreach. +# In particular, this plays well with m4_set_foreach and m4_set_map. m4_define([m4_set_remove], [m4_set_contains([$1], [$2], [_m4_set_size([$1], [m4_decr])m4_if(_m4_defn([_m4_set([$1])]), [$2], @@ -2721,12 +3226,14 @@ m4_define([_m4_set_size], # not guaranteed. # # We can rely on the fact that m4_set_listc prunes SET1, so we don't -# need to check _m4_set([$1],element) for 0. Use _m4_defn for speed. -# Short-circuit the idempotence relation. +# need to check _m4_set([$1],element) for 0. Short-circuit the +# idempotence relation. m4_define([m4_set_union], -[m4_set_listc([$1])m4_if([$1], [$2], [], [m4_set_foreach([$2], [_m4_element], - [m4_ifdef([_m4_set([$1],]_m4_defn([_m4_element])[)], [], - [,_m4_defn([_m4_element])])])])]) +[m4_set_listc([$1])m4_if([$1], [$2], [], + [m4_set_map_sep([$2], [_$0([$1],], [)])])]) + +m4_define([_m4_set_union], +[m4_ifdef([_m4_set([$1],$2)], [], [,[$2]])]) ## ------------------- ## @@ -2755,6 +3262,8 @@ m4_if(m4_sysval, [0], [], ## 17. Setting M4sugar up. ## ## ------------------------ ## +# _m4_divert_diversion should be defined. +m4_divert_push([KILL]) # m4_init # ------- @@ -2766,24 +3275,34 @@ m4_pattern_forbid([^_?m4_]) m4_pattern_forbid([^dnl$]) # If __m4_version__ is defined, we assume that we are being run by M4 -# 1.6 or newer, and thus that $@ recursion is linear and debugmode(d) -# is available for faster checks of dereferencing undefined macros. +# 1.6 or newer, thus $@ recursion is linear, and debugmode(+do) +# is available for faster checks of dereferencing undefined macros +# and forcing dumpdef to print to stderr regardless of debugfile. # But if it is missing, we assume we are being run by M4 1.4.x, that # $@ recursion is quadratic, and that we need foreach-based -# replacement macros. Use the raw builtin to avoid tripping up -# include tracing. +# replacement macros. Also, m4 prior to 1.4.8 loses track of location +# during m4wrap text; __line__ should never be 0. +# +# Use the raw builtin to avoid tripping up include tracing. +# Meanwhile, avoid m4_copy, since it temporarily undefines m4_defn. m4_ifdef([__m4_version__], -[m4_debugmode([+d]) -m4_copy([_m4_defn], [m4_defn]) -m4_copy([_m4_popdef], [m4_popdef]) -m4_copy([_m4_undefine], [m4_undefine])], -[m4_builtin([include], [m4sugar/foreach.m4])]) - -# _m4_divert_diversion should be defined: -m4_divert_push([KILL]) +[m4_debugmode([+do]) +m4_define([m4_defn], _m4_defn([_m4_defn])) +m4_define([m4_dumpdef], _m4_defn([_m4_dumpdef])) +m4_define([m4_popdef], _m4_defn([_m4_popdef])) +m4_define([m4_undefine], _m4_defn([_m4_undefine]))], +[m4_builtin([include], [m4sugar/foreach.m4]) +m4_wrap_lifo([m4_if(__line__, [0], [m4_pushdef([m4_location], +]]m4_dquote(m4_dquote(m4_dquote(__file__:__line__)))[[)])])]) + +# Rewrite the first entry of the diversion stack. +m4_divert([KILL]) # Check the divert push/pop perfect balance. -m4_wrap([m4_divert_pop([]) - m4_ifdef([_m4_divert_diversion], - [m4_fatal([$0: unbalanced m4_divert_push:]_m4_divert_n_stack)])[]]) +# Some users are prone to also use m4_wrap to register last-minute +# m4_divert_text; so after our diversion cleanups, we restore +# KILL as the bottom of the diversion stack. +m4_wrap([m4_popdef([_m4_divert_diversion])m4_ifdef( + [_m4_divert_diversion], [m4_fatal([$0: unbalanced m4_divert_push: +]m4_divert_stack)])_m4_popdef([_m4_divert_stack])m4_divert_push([KILL])]) ]) diff --git a/msys2/usr/share/bison/skeletons/README-D.txt b/msys2/usr/share/bison/skeletons/README-D.txt new file mode 100644 index 0000000..214e309 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/README-D.txt @@ -0,0 +1,60 @@ +Some usage notes for the D Parser: + +- it is a port of the Java parser, so interface is very similar. + +- the lexer class needs to implement the interface 'Lexer' (similar to + java). It typically (depending on options) looks like this: + +public interface Lexer +{ + /** + * Method to retrieve the beginning position of the last scanned token. + * @return the position at which the last scanned token starts. */ + @property YYPosition startPos (); + + /** + * Method to retrieve the ending position of the last scanned token. + * @return the first position beyond the last scanned token. */ + @property YYPosition endPos (); + + /** + * Method to retrieve the semantic value of the last scanned token. + * @return the semantic value of the last scanned token. */ + @property YYSemanticType semanticVal (); + + /** + * Entry point for the scanner. Returns the token identifier corresponding + * to the next token and prepares to return the semantic value + * and beginning/ending positions of the token. + * @return the token identifier corresponding to the next token. */ + YYTokenType yylex (); + + /** + * Entry point for error reporting. Emits an error + * referring to the given location in a user-defined way. + * + * @param loc The location of the element to which the + * error message is related + * @param s The string for the error message. */ + void yyerror (YYLocation loc, string s); +} + +- semantic types are handled by D usions (same as for C/C++ parsers) + +- the following (non-standard) %defines are supported: + + %define package "" + %define api.parser.class "my_class_name>" + %define position_type "my_position_type" + %define location_type "my_location_type" + +- the following declarations basically work like in C/C++: + + %locations + %error-verbose + %parse-param + %initial-action + %code + %union + +- %destructor is not yet supported diff --git a/msys2/usr/share/bison/skeletons/bison.m4 b/msys2/usr/share/bison/skeletons/bison.m4 new file mode 100644 index 0000000..e359187 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/bison.m4 @@ -0,0 +1,1111 @@ + -*- Autoconf -*- + +# Language-independent M4 Macros for Bison. + +# Copyright (C) 2002, 2004-2015, 2018-2019 Free Software Foundation, +# Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +## ---------------- ## +## Identification. ## +## ---------------- ## + +# b4_generated_by +# --------------- +m4_define([b4_generated_by], +[b4_comment([A Bison parser, made by GNU Bison b4_version.]) +]) + +# b4_copyright(TITLE, [YEARS]) +# ---------------------------- +# If YEARS are not defined, use b4_copyright_years. +m4_define([b4_copyright], +[b4_generated_by +b4_comment([$1 + +]m4_dquote(m4_text_wrap([Copyright (C) +]m4_ifval([$2], [[$2]], [m4_defn([b4_copyright_years])])[ +Free Software Foundation, Inc.]))[ + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see .]) + +b4_comment([As a special exception, you may create a larger work that contains +part or all of the Bison parser skeleton and distribute that work +under terms of your choice, so long as that work isn't itself a +parser generator using the skeleton or a modified version thereof +as a parser skeleton. Alternatively, if you modify or redistribute +the parser skeleton itself, you may (at your option) remove this +special exception, which will cause the skeleton and the resulting +Bison output files to be licensed under the GNU General Public +License without this special exception. + +This special exception was added by the Free Software Foundation in +version 2.2 of Bison.]) +]) + + +# b4_disclaimer +# ------------- +# Issue a warning about private implementation details. +m4_define([b4_disclaimer], +[b4_comment([Undocumented macros, especially those whose name start with YY_, +are private implementation details. Do not rely on them.]) +]) + + + +# b4_required_version_if(VERSION, IF_NEWER, IF_OLDER) +# --------------------------------------------------- +# If the version %require'd by the user is VERSION (or newer) expand +# IF_NEWER, otherwise IF_OLDER. VERSION should be an integer, e.g., +# 302 for 3.2. +m4_define([b4_required_version_if], +[m4_if(m4_eval($1 <= b4_required_version), + [1], [$2], [$3])]) + + +## -------- ## +## Output. ## +## -------- ## + +# b4_output_begin(FILE1, FILE2) +# ----------------------------- +# Enable output, i.e., send to diversion 0, expand after "#", and +# generate the tag to output into FILE. Must be followed by EOL. +# FILE is FILE1 concatenated to FILE2. FILE2 can be empty, or be +# absolute: do the right thing. +m4_define([b4_output_begin], +[m4_changecom() +m4_divert_push(0)dnl +@output(m4_unquote([$1])@,m4_unquote([$2])@)@dnl +]) + + +# b4_output_end +# ------------- +# Output nothing, restore # as comment character (no expansions after #). +m4_define([b4_output_end], +[m4_divert_pop(0) +m4_changecom([#]) +]) + + +# b4_divert_kill(CODE) +# -------------------- +# Expand CODE for its side effects, discard its output. +m4_define([b4_divert_kill], +[m4_divert_text([KILL], [$1])]) + + +# b4_define_silent(MACRO, CODE) +# ----------------------------- +# Same as m4_define, but throw away the expansion of CODE. +m4_define([b4_define_silent], +[m4_define([$1], [b4_divert_kill([$2])])]) + + +## ---------------- ## +## Error handling. ## +## ---------------- ## + +# The following error handling macros print error directives that should not +# become arguments of other macro invocations since they would likely then be +# mangled. Thus, they print to stdout directly. + +# b4_cat(TEXT) +# ------------ +# Write TEXT to stdout. Precede the final newline with an @ so that it's +# escaped. For example: +# +# b4_cat([[@complain(invalid input@)]]) +m4_define([b4_cat], +[m4_syscmd([cat <<'_m4eof' +]m4_bpatsubst(m4_dquote($1), [_m4eof], [_m4@`eof])[@ +_m4eof +])dnl +m4_if(m4_sysval, [0], [], [m4_fatal([$0: cannot write to stdout])])]) + +# b4_error(KIND, START, END, FORMAT, [ARG1], [ARG2], ...) +# ------------------------------------------------------- +# Write @KIND(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout. +# +# For example: +# +# b4_error([[complain]], [[input.y:2.3]], [[input.y:5.4]], +# [[invalid %s]], [[foo]]) +m4_define([b4_error], +[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl +[m4_if([$#], [4], [], + [m4_foreach([b4_arg], + m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))), + [[@,]b4_arg])])[@)]])]) + +# b4_warn(FORMAT, [ARG1], [ARG2], ...) +# ------------------------------------ +# Write @warn(FORMAT@,ARG1@,ARG2@,...@) to stdout. +# +# For example: +# +# b4_warn([[invalid value for '%s': %s]], [[foo]], [[3]]) +# +# As a simple test suite, this: +# +# m4_divert(-1) +# m4_define([asdf], [ASDF]) +# m4_define([fsa], [FSA]) +# m4_define([fdsa], [FDSA]) +# b4_warn_at([[[asdf), asdf]]], [[[fsa), fsa]]], [[[fdsa), fdsa]]]) +# b4_warn_at([[asdf), asdf]], [[fsa), fsa]], [[fdsa), fdsa]]) +# b4_warn_at() +# b4_warn_at(1) +# b4_warn_at(1, 2) +# +# Should produce this without newlines: +# +# @warn_at([asdf), asdf]@,@,@,[fsa), fsa]@,[fdsa), fdsa]@) +# @warn(asdf), asdf@,@,@,fsa), fsa@,fdsa), fdsa@) +# @warn(@) +# @warn(1@) +# @warn(1@,2@) +m4_define([b4_warn], +[b4_error([[warn]], [], [], $@)]) + +# b4_warn_at(START, END, FORMAT, [ARG1], [ARG2], ...) +# --------------------------------------------------- +# Write @warn(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout. +# +# For example: +# +# b4_warn_at([[input.y:2.3]], [[input.y:5.4]], [[invalid %s]], [[foo]]) +m4_define([b4_warn_at], +[b4_error([[warn]], $@)]) + +# b4_complain(FORMAT, [ARG1], [ARG2], ...) +# ---------------------------------------- +# Bounce to b4_complain_at. +# +# See b4_warn example. +m4_define([b4_complain], +[b4_error([[complain]], [], [], $@)]) + +# b4_complain_at(START, END, FORMAT, [ARG1], [ARG2], ...) +# ------------------------------------------------------- +# Write @complain(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout. +# +# See b4_warn_at example. +m4_define([b4_complain_at], +[b4_error([[complain]], $@)]) + +# b4_fatal(FORMAT, [ARG1], [ARG2], ...) +# ------------------------------------- +# Bounce to b4_fatal_at. +# +# See b4_warn example. +m4_define([b4_fatal], +[b4_error([[fatal]], [], [], $@)dnl +m4_exit(1)]) + +# b4_fatal_at(START, END, FORMAT, [ARG1], [ARG2], ...) +# ---------------------------------------------------- +# Write @fatal(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout and exit. +# +# See b4_warn_at example. +m4_define([b4_fatal_at], +[b4_error([[fatal]], $@)dnl +m4_exit(1)]) + + +## ------------ ## +## Data Types. ## +## ------------ ## + +# b4_ints_in(INT1, INT2, LOW, HIGH) +# --------------------------------- +# Return 1 iff both INT1 and INT2 are in [LOW, HIGH], 0 otherwise. +m4_define([b4_ints_in], +[m4_eval([$3 <= $1 && $1 <= $4 && $3 <= $2 && $2 <= $4])]) + + +# b4_subtract(LHS, RHS) +# --------------------- +# Evaluate LHS - RHS if they are integer literals, otherwise expand +# to (LHS) - (RHS). +m4_define([b4_subtract], +[m4_bmatch([$1$2], [^[0123456789]*$], + [m4_eval([$1 - $2])], + [($1) - ($2)])]) + +# b4_join(ARG1, ...) +# _b4_join(ARG1, ...) +# ------------------- +# Join with comma, skipping empty arguments. +# b4_join calls itself recursively until it sees the first non-empty +# argument, then calls _b4_join (i.e., `_$0`) which prepends each +# non-empty argument with a comma. +m4_define([b4_join], +[m4_if([$#$1], + [1], [], + [m4_ifval([$1], + [$1[]_$0(m4_shift($@))], + [$0(m4_shift($@))])])]) + +# _b4_join(ARGS1, ...) +# -------------------- +m4_define([_b4_join], +[m4_if([$#$1], + [1], [], + [m4_ifval([$1], [, $1])[]$0(m4_shift($@))])]) + + + + +# b4_integral_parser_tables_map(MACRO) +# ------------------------------------- +# Map MACRO on all the integral tables. MACRO is expected to have +# the signature MACRO(TABLE-NAME, CONTENT, COMMENT). +m4_define([b4_integral_parser_tables_map], +[$1([pact], [b4_pact], + [[YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +STATE-NUM.]]) + +$1([defact], [b4_defact], + [[YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +Performed when YYTABLE does not specify something else to do. Zero +means the default is an error.]]) + +$1([pgoto], [b4_pgoto], [[YYPGOTO[NTERM-NUM].]]) + +$1([defgoto], [b4_defgoto], [[YYDEFGOTO[NTERM-NUM].]]) + +$1([table], [b4_table], + [[YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +positive, shift that token. If negative, reduce the rule whose +number is the opposite. If YYTABLE_NINF, syntax error.]]) + +$1([check], [b4_check]) + +$1([stos], [b4_stos], + [[YYSTOS[STATE-NUM] -- The (internal number of the) accessing +symbol of state STATE-NUM.]]) + +$1([r1], [b4_r1], + [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]]) + +$1([r2], [b4_r2], + [[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]]) +]) + + +# b4_parser_tables_declare +# b4_parser_tables_define +# ------------------------ +# Define/declare the (deterministic) parser tables. +m4_define([b4_parser_tables_declare], +[b4_integral_parser_tables_map([b4_integral_parser_table_declare])]) + +m4_define([b4_parser_tables_define], +[b4_integral_parser_tables_map([b4_integral_parser_table_define])]) + + + +## ------------------ ## +## Decoding options. ## +## ------------------ ## + +# b4_flag_if(FLAG, IF-TRUE, IF-FALSE) +# ----------------------------------- +# Run IF-TRUE if b4_FLAG_flag is 1, IF-FALSE if FLAG is 0, otherwise fail. +m4_define([b4_flag_if], +[m4_case(b4_$1_flag, + [0], [$3], + [1], [$2], + [m4_fatal([invalid $1 value: ]b4_$1_flag)])]) + + +# b4_define_flag_if(FLAG) +# ----------------------- +# Define "b4_FLAG_if(IF-TRUE, IF-FALSE)" that depends on the +# value of the Boolean FLAG. +m4_define([b4_define_flag_if], +[_b4_define_flag_if($[1], $[2], [$1])]) + +# _b4_define_flag_if($1, $2, FLAG) +# -------------------------------- +# Work around the impossibility to define macros inside macros, +# because issuing '[$1]' is not possible in M4. GNU M4 should provide +# $$1 a la M5/TeX. +m4_define([_b4_define_flag_if], +[m4_if([$1$2], $[1]$[2], [], + [m4_fatal([$0: Invalid arguments: $@])])dnl +m4_define([b4_$3_if], + [b4_flag_if([$3], [$1], [$2])])]) + + +# b4_FLAG_if(IF-TRUE, IF-FALSE) +# ----------------------------- +# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise. +b4_define_flag_if([defines]) # Whether headers are requested. +b4_define_flag_if([glr]) # Whether a GLR parser is requested. +b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled. +b4_define_flag_if([token_table]) # Whether yytoken_table is demanded. +b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated. + + +# b4_glr_cc_if([IF-TRUE], [IF-FALSE]) +# ----------------------------------- +m4_define([b4_glr_cc_if], + [m4_if(b4_skeleton, ["glr.cc"], $@)]) + + +## --------- ## +## Symbols. ## +## --------- ## + +# For a description of the Symbol handling, see README. +# +# The following macros provide access to symbol related values. + +# __b4_symbol(NUM, FIELD) +# ----------------------- +# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if +# undefined. +m4_define([__b4_symbol], +[m4_indir([b4_symbol($1, $2)])]) + + +# _b4_symbol(NUM, FIELD) +# ---------------------- +# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if +# undefined. +m4_define([_b4_symbol], +[m4_ifdef([b4_symbol($1, number)], + [__b4_symbol(m4_indir([b4_symbol($1, number)]), $2)], + [__b4_symbol([$1], [$2])])]) + + + +# b4_symbol(NUM, FIELD) +# --------------------- +# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if +# undefined. If FIELD = id, prepend the token prefix. +m4_define([b4_symbol], +[m4_case([$2], + [id], [m4_do([b4_percent_define_get([api.token.prefix])], + [_b4_symbol([$1], [id])])], + [_b4_symbol($@)])]) + + +# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE) +# ------------------------------------------- +# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE. +# Otherwise an error. +m4_define([b4_symbol_if], +[m4_case(b4_symbol([$1], [$2]), + [1], [$3], + [0], [$4], + [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])]) + + +# b4_symbol_tag_comment(SYMBOL-NUM) +# --------------------------------- +# Issue a comment giving the tag of symbol NUM. +m4_define([b4_symbol_tag_comment], +[b4_comment([b4_symbol([$1], [tag])]) +]) + + +# b4_symbol_action_location(SYMBOL-NUM, KIND) +# ------------------------------------------- +# Report the location of the KIND action as FILE:LINE. +m4_define([b4_symbol_action_location], +[b4_symbol([$1], [$2_file]):b4_syncline([b4_symbol([$1], [$2_line])])]) + + +# b4_symbol_action(SYMBOL-NUM, KIND) +# ---------------------------------- +# Run the action KIND (destructor or printer) for SYMBOL-NUM. +m4_define([b4_symbol_action], +[b4_symbol_if([$1], [has_$2], +[b4_dollar_pushdef([(*yyvaluep)], + [$1], + [], + [(*yylocationp)])dnl + _b4_symbol_case([$1])[]dnl +b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])]) + b4_symbol([$1], [$2]) +b4_syncline([@oline@], [@ofile@]) + break; + +b4_dollar_popdef[]dnl +])]) + + +# b4_symbol_destructor(SYMBOL-NUM) +# b4_symbol_printer(SYMBOL-NUM) +# -------------------------------- +m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])]) +m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])]) + + +# b4_symbol_actions(KIND, [TYPE = yytype]) +# ---------------------------------------- +# Emit the symbol actions for KIND ("printer" or "destructor"). +# Dispatch on TYPE. +m4_define([b4_symbol_actions], +[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl +m4_ifval(m4_defn([b4_actions_]), +[switch (m4_default([$2], [yytype])) + { +m4_defn([b4_actions_])[]dnl + default: + break; + }dnl +], +[YYUSE (m4_default([$2], [yytype]));])dnl +m4_popdef([b4_actions_])dnl +]) + +# _b4_symbol_case(SYMBOL-NUM) +# --------------------------- +# Issue a "case NUM" for SYMBOL-NUM. Ends with its EOL to make it +# easier to use with m4_map, but then, use []dnl to suppress the last +# one. +m4_define([_b4_symbol_case], +[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])]) +]) + + +# b4_symbol_foreach(MACRO) +# ------------------------ +# Invoke MACRO(SYMBOL-NUM) for each SYMBOL-NUM. +m4_define([b4_symbol_foreach], + [m4_map([$1], m4_defn([b4_symbol_numbers]))]) + +# b4_symbol_map(MACRO) +# -------------------- +# Return a list (possibly empty elements) of MACRO invoked for each +# SYMBOL-NUM. +m4_define([b4_symbol_map], +[m4_map_args_sep([$1(], [)], [,], b4_symbol_numbers)]) + + +# b4_token_visible_if(NUM, IF-TRUE, IF-FALSE) +# ------------------------------------------- +# Whether NUM denotes a token that has an exported definition (i.e., +# shows in enum yytokentype). +m4_define([b4_token_visible_if], +[b4_symbol_if([$1], [is_token], + [b4_symbol_if([$1], [has_id], [$2], [$3])], + [$3])]) + +# b4_token_has_definition(NUM) +# ---------------------------- +# 1 if NUM is visible, nothing otherwise. +m4_define([b4_token_has_definition], +[b4_token_visible_if([$1], [1])]) + +# b4_any_token_visible_if([IF-TRUE], [IF-FALSE]) +# ---------------------------------------------- +# Whether there is a token that needs to be defined. +m4_define([b4_any_token_visible_if], +[m4_ifval(b4_symbol_foreach([b4_token_has_definition]), + [$1], [$2])]) + + +# b4_token_format(FORMAT, NUM) +# ---------------------------- +m4_define([b4_token_format], +[b4_token_visible_if([$2], +[m4_quote(m4_format([$1], + [b4_symbol([$2], [id])], + [b4_symbol([$2], [user_number])]))])]) + + +## ------- ## +## Types. ## +## ------- ## + +# _b4_type_action(NUMS) +# --------------------- +# Run actions for the symbol NUMS that all have the same type-name. +# Skip NUMS that have no type-name. +# +# To specify the action to run, define b4_dollar_dollar(SYMBOL-NUM, +# TAG, TYPE). +m4_define([_b4_type_action], +[b4_symbol_if([$1], [has_type], +[m4_map([ _b4_symbol_case], [$@])[]dnl + b4_dollar_dollar([b4_symbol([$1], [number])], + [b4_symbol([$1], [tag])], + [b4_symbol([$1], [type])]); + break; + +])]) + +# b4_type_foreach(MACRO) +# ---------------------- +# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set. +m4_define([b4_type_foreach], + [m4_map([$1], m4_defn([b4_type_names]))]) + + + +## ----------- ## +## Synclines. ## +## ----------- ## + +# b4_basename(NAME) +# ----------------- +# Similar to POSIX basename; the differences don't matter here. +# Beware that NAME is not evaluated. +m4_define([b4_basename], +[m4_bpatsubst([$1], [^.*/\([^/]+\)/*$], [\1])]) + + +# b4_syncline(LINE, FILE) +# ----------------------- +m4_define([b4_syncline], +[b4_flag_if([synclines], +[b4_sync_start([$1], [$2]) b4_sync_end([__line__], + [b4_basename(m4_quote(__file__))])[]dnl +])]) + +# b4_sync_start(LINE, FILE) +# ----------------------- +# Syncline for the new place. Typically a directive for the compiler. +m4_define([b4_sync_start], [b4_comment([$2:$1])]) + +# b4_sync_end(LINE, FILE) +# ----------------------- +# Syncline for the current place, which ends. Typically a comment +# left for the reader. +m4_define([b4_sync_end], [b4_comment([$2:$1])]) + + +# b4_user_code(USER-CODE) +# ----------------------- +# Emit code from the user, ending it with synclines. +m4_define([b4_user_code], +[$1 +b4_syncline([@oline@], [@ofile@])]) + + +# b4_define_user_code(MACRO, COMMENT) +# ----------------------------------- +# From b4_MACRO, if defined, build b4_user_MACRO that includes the synclines. +m4_define([b4_define_user_code], +[m4_define([b4_user_$1], + [m4_ifdef([b4_$1], + [m4_ifval([$2], + [b4_comment([$2]) +])b4_user_code([b4_$1])])])]) + +# b4_user_actions +# b4_user_initial_action +# b4_user_post_prologue +# b4_user_pre_prologue +# b4_user_union_members +# ---------------------- +# Macros that issue user code, ending with synclines. +b4_define_user_code([actions]) +b4_define_user_code([initial_action], [User initialization code.]) +b4_define_user_code([post_prologue], [Second part of user prologue.]) +b4_define_user_code([pre_prologue], [First part of user prologue.]) +b4_define_user_code([union_members]) + + +# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE) +# ----------------------------------------------------- +# Complain if any name of type WHAT is used by the user (as recorded in +# USER-LIST) but is not used by Bison (as recorded by macros in the +# namespace BISON-NAMESPACE). +# +# USER-LIST must expand to a list specifying all user occurrences of all names +# of type WHAT. Each item in the list must be a triplet specifying one +# occurrence: name, start boundary, and end boundary. Empty string names are +# fine. An empty list is fine. +# +# For example, to define b4_foo_user_names to be used for USER-LIST with three +# name occurrences and with correct quoting: +# +# m4_define([b4_foo_user_names], +# [[[[[[bar]], [[parser.y:1.7]], [[parser.y:1.16]]]], +# [[[[bar]], [[parser.y:5.7]], [[parser.y:5.16]]]], +# [[[[baz]], [[parser.y:8.7]], [[parser.y:8.16]]]]]]) +# +# The macro BISON-NAMESPACE(bar) must be defined iff the name bar of type WHAT +# is used by Bison (in the front-end or in the skeleton). Empty string names +# are fine, but it would be ugly for Bison to actually use one. +# +# For example, to use b4_foo_bison_names for BISON-NAMESPACE and define that +# the names bar and baz are used by Bison: +# +# m4_define([b4_foo_bison_names(bar)]) +# m4_define([b4_foo_bison_names(baz)]) +# +# To invoke b4_check_user_names with TYPE foo, with USER-LIST +# b4_foo_user_names, with BISON-NAMESPACE b4_foo_bison_names, and with correct +# quoting: +# +# b4_check_user_names([[foo]], [b4_foo_user_names], +# [[b4_foo_bison_names]]) +m4_define([b4_check_user_names], +[m4_foreach([b4_occurrence], $2, +[m4_pushdef([b4_occurrence], b4_occurrence)dnl +m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl +m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl +m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl +m4_ifndef($3[(]m4_quote(b4_user_name)[)], + [b4_complain_at([b4_start], [b4_end], + [[%s '%s' is not used]], + [$1], [b4_user_name])])[]dnl +m4_popdef([b4_occurrence])dnl +m4_popdef([b4_user_name])dnl +m4_popdef([b4_start])dnl +m4_popdef([b4_end])dnl +])]) + + + +## --------------------- ## +## b4_percent_define_*. ## +## --------------------- ## + + +# b4_percent_define_use(VARIABLE) +# ------------------------------- +# Declare that VARIABLE was used. +m4_define([b4_percent_define_use], +[m4_define([b4_percent_define_bison_variables(]$1[)])dnl +]) + +# b4_percent_define_get(VARIABLE, [DEFAULT]) +# ------------------------------------------ +# Mimic muscle_percent_define_get in ../src/muscle-tab.h. That is, if +# the %define variable VARIABLE is defined, emit its value. Contrary +# to its C counterpart, return DEFAULT otherwise. Also, record +# Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). +# +# For example: +# +# b4_percent_define_get([[foo]]) +m4_define([b4_percent_define_get], +[b4_percent_define_use([$1])dnl +_b4_percent_define_ifdef([$1], + [m4_indir([b4_percent_define(]$1[)])], + [$2])]) + +# b4_percent_define_get_loc(VARIABLE) +# ----------------------------------- +# Mimic muscle_percent_define_get_loc in ../src/muscle-tab.h exactly. That is, +# if the %define variable VARIABLE is undefined, complain fatally since that's +# a Bison or skeleton error. Otherwise, return its definition location in a +# form appropriate for the first two arguments of b4_warn_at, b4_complain_at, or +# b4_fatal_at. Don't record this as a Bison usage of VARIABLE as there's no +# reason to suspect that the user-supplied value has yet influenced the output. +# +# For example: +# +# b4_complain_at(b4_percent_define_get_loc([[foo]]), [[invalid foo]]) +m4_define([b4_percent_define_get_loc], +[m4_ifdef([b4_percent_define_loc(]$1[)], + [m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl +b4_loc[]dnl +m4_popdef([b4_loc])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# b4_percent_define_get_kind(VARIABLE) +# ------------------------------------ +# Get the kind (code, keyword, string) of VARIABLE, i.e., how its +# value was defined (braces, not delimiters, quotes). +# +# If the %define variable VARIABLE is undefined, complain fatally +# since that's a Bison or skeleton error. Don't record this as a +# Bison usage of VARIABLE as there's no reason to suspect that the +# user-supplied value has yet influenced the output. +m4_define([b4_percent_define_get_kind], +[m4_ifdef([b4_percent_define_kind(]$1[)], + [m4_indir([b4_percent_define_kind(]$1[)])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# b4_percent_define_get_syncline(VARIABLE) +# ---------------------------------------- +# Mimic muscle_percent_define_get_syncline in ../src/muscle-tab.h exactly. +# That is, if the %define variable VARIABLE is undefined, complain fatally +# since that's a Bison or skeleton error. Otherwise, return its definition +# location as a b4_syncline invocation. Don't record this as a Bison usage of +# VARIABLE as there's no reason to suspect that the user-supplied value has yet +# influenced the output. +# +# For example: +# +# b4_percent_define_get_syncline([[foo]]) +m4_define([b4_percent_define_get_syncline], +[m4_ifdef([b4_percent_define_syncline(]$1[)], + [m4_indir([b4_percent_define_syncline(]$1[)])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# _b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE]) +# ------------------------------------------------------ +# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand +# IF-FALSE. Don't record usage of VARIABLE. +# +# For example: +# +# _b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]]) +m4_define([_b4_percent_define_ifdef], +[m4_ifdef([b4_percent_define(]$1[)], + [$2], + [$3])]) + +# b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE]) +# ------------------------------------------------------ +# Mimic muscle_percent_define_ifdef in ../src/muscle-tab.h exactly. That is, +# if the %define variable VARIABLE is defined, expand IF-TRUE, else expand +# IF-FALSE. Also, record Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). +# +# For example: +# +# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]]) +m4_define([b4_percent_define_ifdef], +[_b4_percent_define_ifdef([$1], + [b4_percent_define_use([$1])$2], + [$3])]) + + +# b4_percent_define_check_file_complain(VARIABLE) +# ----------------------------------------------- +# Warn about %define variable VARIABLE having an incorrect +# value. +m4_define([b4_percent_define_check_file_complain], +[b4_complain_at(b4_percent_define_get_loc([$1]), + [[%%define variable '%s' requires 'none' or '"..."' values]], + [$1])]) + + +# b4_percent_define_check_file(MACRO, VARIABLE, DEFAULT) +# ------------------------------------------------------ +# If the %define variable VARIABLE: +# - is undefined, then if DEFAULT is non-empty, define MACRO to DEFAULT +# - is a string, define MACRO to its value +# - is the keyword 'none', do nothing +# - otherwise, warn about the incorrect value. +m4_define([b4_percent_define_check_file], +[b4_percent_define_ifdef([$2], + [m4_case(b4_percent_define_get_kind([$2]), + [string], + [m4_define([$1], b4_percent_define_get([$2]))], + [keyword], + [m4_if(b4_percent_define_get([$2]), [none], [], + [b4_percent_define_check_file_complain([$2])])], + [b4_percent_define_check_file_complain([$2])]) + ], + [m4_ifval([$3], + [m4_define([$1], [$3])])]) +]) + + + +## --------- ## +## Options. ## +## --------- ## + + +# b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE]) +# -------------------------------------------------------- +# Mimic muscle_percent_define_flag_if in ../src/muscle-tab.h exactly. That is, +# if the %define variable VARIABLE is defined to "" or "true", expand IF-TRUE. +# If it is defined to "false", expand IF-FALSE. Complain if it is undefined +# (a Bison or skeleton error since the default value should have been set +# already) or defined to any other value (possibly a user error). Also, record +# Bison's usage of VARIABLE by defining +# b4_percent_define_bison_variables(VARIABLE). +# +# For example: +# +# b4_percent_define_flag_if([[foo]], [[it's true]], [[it's false]]) +m4_define([b4_percent_define_flag_if], +[b4_percent_define_ifdef([$1], + [m4_case(b4_percent_define_get([$1]), + [], [$2], [true], [$2], [false], [$3], + [m4_expand_once([b4_complain_at(b4_percent_define_get_loc([$1]), + [[invalid value for %%define Boolean variable '%s']], + [$1])], + [[b4_percent_define_flag_if($1)]])])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + + +# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword]) +# -------------------------------------------------------------- +# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is, +# if the %define variable VARIABLE is undefined, set its value to DEFAULT. +# Don't record this as a Bison usage of VARIABLE as there's no reason to +# suspect that the value has yet influenced the output. +# +# For example: +# +# b4_percent_define_default([[foo]], [[default value]]) +m4_define([b4_percent_define_default], +[_b4_percent_define_ifdef([$1], [], + [m4_define([b4_percent_define(]$1[)], [$2])dnl + m4_define([b4_percent_define_kind(]$1[)], + [m4_default([$3], [keyword])])dnl + m4_define([b4_percent_define_loc(]$1[)], + [[[[:-1.-1]], + [[:-1.-1]]]])dnl + m4_define([b4_percent_define_syncline(]$1[)], [[]])])]) + + +# b4_percent_define_if_define(NAME, [VARIABLE = NAME]) +# ---------------------------------------------------- +# Define b4_NAME_if that executes its $1 or $2 depending whether +# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped +# to '_'. +m4_define([_b4_percent_define_if_define], +[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]), + [b4_percent_define_flag_if(m4_default([$2], [$1]), + [$3], [$4])])]) +m4_define([b4_percent_define_if_define], +[b4_percent_define_default([m4_default([$2], [$1])], [[false]]) +_b4_percent_define_if_define([$1], [$2], $[1], $[2])]) + + +# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain]) +# --------------------------------------------------------------------- +m4_define([b4_percent_define_check_kind], +[_b4_percent_define_ifdef([$1], + [m4_if(b4_percent_define_get_kind([$1]), [$2], [], + [b4_error([m4_default([$3], [complain])], + b4_percent_define_get_loc([$1]), + [m4_case([$2], + [code], [[%%define variable '%s' requires '{...}' values]], + [keyword], [[%%define variable '%s' requires keyword values]], + [string], [[%%define variable '%s' requires '"..."' values]])], + [$1])])])dnl +]) + + +# b4_percent_define_check_values(VALUES) +# -------------------------------------- +# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly +# except that the VALUES structure is more appropriate for M4. That is, VALUES +# is a list of sublists of strings. For each sublist, the first string is the +# name of a %define variable, and all remaining strings in that sublist are the +# valid values for that variable. Complain if such a variable is undefined (a +# Bison error since the default value should have been set already) or defined +# to any other value (possibly a user error). Don't record this as a Bison +# usage of the variable as there's no reason to suspect that the value has yet +# influenced the output. +# +# For example: +# +# b4_percent_define_check_values([[[[foo]], [[foo-value1]], [[foo-value2]]]], +# [[[[bar]], [[bar-value1]]]]) +m4_define([b4_percent_define_check_values], +[m4_foreach([b4_sublist], m4_quote($@), + [_b4_percent_define_check_values(b4_sublist)])]) + +m4_define([_b4_percent_define_check_values], +[_b4_percent_define_ifdef([$1], + [b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl + m4_pushdef([b4_good_value], [0])dnl + m4_if($#, 1, [], + [m4_foreach([b4_value], m4_dquote(m4_shift($@)), + [m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value, + [m4_define([b4_good_value], [1])])])])dnl + m4_if(b4_good_value, [0], + [b4_complain_at(b4_percent_define_get_loc([$1]), + [[invalid value for %%define variable '%s': '%s']], + [$1], + m4_dquote(m4_indir([b4_percent_define(]$1[)]))) + m4_foreach([b4_value], m4_dquote(m4_shift($@)), + [b4_error([[note]], b4_percent_define_get_loc([$1]), [] + [[accepted value: '%s']], + m4_dquote(b4_value))])])dnl + m4_popdef([b4_good_value])], + [b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) + +# b4_percent_code_get([QUALIFIER]) +# -------------------------------- +# If any %code blocks for QUALIFIER are defined, emit them beginning with a +# comment and ending with synclines and a newline. If QUALIFIER is not +# specified or empty, do this for the unqualified %code blocks. Also, record +# Bison's usage of QUALIFIER (if specified) by defining +# b4_percent_code_bison_qualifiers(QUALIFIER). +# +# For example, to emit any unqualified %code blocks followed by any %code +# blocks for the qualifier foo: +# +# b4_percent_code_get +# b4_percent_code_get([[foo]]) +m4_define([b4_percent_code_get], +[m4_pushdef([b4_macro_name], [[b4_percent_code(]$1[)]])dnl +m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])dnl +m4_ifdef(b4_macro_name, +[b4_comment([m4_if([$#], [0], [[Unqualified %code]], + [["%code ]$1["]])[ blocks.]]) +b4_user_code([m4_indir(b4_macro_name)]) +])dnl +m4_popdef([b4_macro_name])]) + +# b4_percent_code_ifdef(QUALIFIER, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------- +# If any %code blocks for QUALIFIER (or unqualified %code blocks if +# QUALIFIER is empty) are defined, expand IF-TRUE, else expand IF-FALSE. +# Also, record Bison's usage of QUALIFIER (if specified) by defining +# b4_percent_code_bison_qualifiers(QUALIFIER). +m4_define([b4_percent_code_ifdef], +[m4_ifdef([b4_percent_code(]$1[)], + [m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2], + [$3])]) + + +## ------------------ ## +## Common variables. ## +## ------------------ ## + + +# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT]) +# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT]) +# b4_token_ctor_if([IF-YYLEX-RETURNS-A-TOKEN], [IF-NOT]) +# ---------------------------------------------------------- +b4_percent_define_if_define([token_ctor], [api.token.constructor]) +b4_percent_define_if_define([locations]) # Whether locations are tracked. +b4_percent_define_if_define([parse.assert]) +b4_percent_define_if_define([parse.trace]) + + +# b4_bison_locations_if([IF-TRUE]) +# -------------------------------- +# Expand IF-TRUE if using locations, and using the default location +# type. +m4_define([b4_bison_locations_if], +[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [], [$1])])]) + + +# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT]) +# ------------------------------------------------------ +# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and +# b4_error_verbose_flag. +b4_percent_define_default([[parse.error]], [[simple]]) +b4_percent_define_check_values([[[[parse.error]], + [[simple]], [[verbose]]]]) +m4_define([b4_error_verbose_flag], + [m4_case(b4_percent_define_get([[parse.error]]), + [simple], [[0]], + [verbose], [[1]])]) +b4_define_flag_if([error_verbose]) + +# yytoken_table is needed to support verbose errors. +b4_error_verbose_if([m4_define([b4_token_table_flag], [1])]) + + +# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT]) +# ---------------------------------------------- +b4_percent_define_if_define([variant]) +m4_define([b4_variant_flag], [[0]]) +b4_percent_define_ifdef([[api.value.type]], + [m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword], + [m4_case(b4_percent_define_get([[api.value.type]]), [variant], + [m4_define([b4_variant_flag], [[1]])])])]) +b4_define_flag_if([variant]) + + +## ----------------------------------------------------------- ## +## After processing the skeletons, check that all the user's ## +## %define variables and %code qualifiers were used by Bison. ## +## ----------------------------------------------------------- ## + +m4_define([b4_check_user_names_wrap], +[m4_ifdef([b4_percent_]$1[_user_]$2[s], + [b4_check_user_names([[%]$1 $2], + [b4_percent_]$1[_user_]$2[s], + [[b4_percent_]$1[_bison_]$2[s]])])]) + +m4_wrap_lifo([ +b4_check_user_names_wrap([[define]], [[variable]]) +b4_check_user_names_wrap([[code]], [[qualifier]]) +]) + + +## ---------------- ## +## Default values. ## +## ---------------- ## + +# m4_define_default([b4_lex_param], []) dnl breaks other skeletons +m4_define_default([b4_epilogue], []) +m4_define_default([b4_parse_param], []) + +# The initial column and line. +m4_define_default([b4_location_initial_column], [1]) +m4_define_default([b4_location_initial_line], [1]) + + +## --------------- ## +## Sanity checks. ## +## --------------- ## + +# api.location.prefix={...} (Java and C++). +b4_percent_define_check_kind([api.location.type], [code], [deprecated]) + +# api.position.prefix={...} (Java). +b4_percent_define_check_kind([api.position.type], [code], [deprecated]) + +# api.prefix >< %name-prefix. +b4_percent_define_check_kind([api.prefix], [code], [deprecated]) +b4_percent_define_ifdef([api.prefix], +[m4_ifdef([b4_prefix], +[b4_complain_at(b4_percent_define_get_loc([api.prefix]), + [['%s' and '%s' cannot be used together]], + [%name-prefix], + [%define api.prefix])])]) + +# api.token.prefix={...} +# Make it a warning for those who used betas of Bison 3.0. +b4_percent_define_check_kind([api.token.prefix], [code], [deprecated]) + +# api.value.type >< %union. +b4_percent_define_ifdef([api.value.type], +[m4_ifdef([b4_union_members], +[b4_complain_at(b4_percent_define_get_loc([api.value.type]), + [['%s' and '%s' cannot be used together]], + [%union], + [%define api.value.type])])]) + +# api.value.type=union >< %yacc. +b4_percent_define_ifdef([api.value.type], +[m4_if(b4_percent_define_get([api.value.type]), [union], +[b4_yacc_if(dnl +[b4_complain_at(b4_percent_define_get_loc([api.value.type]), + [['%s' and '%s' cannot be used together]], + [%yacc], + [%define api.value.type "union"])])])]) + +# api.value.union.name. +b4_percent_define_check_kind([api.value.union.name], [keyword]) diff --git a/share/bison/c++-skel.m4 b/msys2/usr/share/bison/skeletons/c++-skel.m4 similarity index 72% rename from share/bison/c++-skel.m4 rename to msys2/usr/share/bison/skeletons/c++-skel.m4 index b8089ff..1c3721c 100644 --- a/share/bison/c++-skel.m4 +++ b/msys2/usr/share/bison/skeletons/c++-skel.m4 @@ -1,7 +1,9 @@ -*- Autoconf -*- # C++ skeleton dispatching for Bison. -# Copyright (C) 2006, 2007 Free Software Foundation, Inc. + +# Copyright (C) 2006-2007, 2009-2015, 2018-2019 Free Software +# Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,10 +18,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])]) -b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])]) +b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])]) +b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])]) -m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.cc]]) +m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[lalr1.cc]]) m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) m4_include(b4_used_skeleton) diff --git a/msys2/usr/share/bison/skeletons/c++.m4 b/msys2/usr/share/bison/skeletons/c++.m4 new file mode 100644 index 0000000..35008f3 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/c++.m4 @@ -0,0 +1,663 @@ + -*- Autoconf -*- + +# C++ skeleton for Bison + +# Copyright (C) 2002-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Sanity checks, before defaults installed by c.m4. +b4_percent_define_ifdef([[api.value.union.name]], + [b4_complain_at(b4_percent_define_get_loc([[api.value.union.name]]), + [named %union is invalid in C++])]) + +m4_include(b4_skeletonsdir/[c.m4]) + +b4_percent_define_check_kind([api.namespace], [code], [deprecated]) +b4_percent_define_check_kind([api.parser.class], [code], [deprecated]) + + +## ----- ## +## C++. ## +## ----- ## + +# b4_comment(TEXT, [PREFIX]) +# -------------------------- +# Put TEXT in comment. Prefix all the output lines with PREFIX. +m4_define([b4_comment], +[_b4_comment([$1], [$2// ], [$2// ])]) + + +# b4_inline(hh|cc) +# ---------------- +# Expand to `inline\n ` if $1 is hh. +m4_define([b4_inline], +[m4_case([$1], + [cc], [], + [hh], [[inline + ]], + [m4_fatal([$0: invalid argument: $1])])]) + + +# b4_cxx_portability +# ------------------ +m4_define([b4_cxx_portability], +[#if defined __cplusplus +# define YY_CPLUSPLUS __cplusplus +#else +# define YY_CPLUSPLUS 199711L +#endif + +// Support move semantics when possible. +#if 201103L <= YY_CPLUSPLUS +# define YY_MOVE std::move +# define YY_MOVE_OR_COPY move +# define YY_MOVE_REF(Type) Type&& +# define YY_RVREF(Type) Type&& +# define YY_COPY(Type) Type +#else +# define YY_MOVE +# define YY_MOVE_OR_COPY copy +# define YY_MOVE_REF(Type) Type& +# define YY_RVREF(Type) const Type& +# define YY_COPY(Type) const Type& +#endif + +// Support noexcept when possible. +#if 201103L <= YY_CPLUSPLUS +# define YY_NOEXCEPT noexcept +# define YY_NOTHROW +#else +# define YY_NOEXCEPT +# define YY_NOTHROW throw () +#endif + +// Support constexpr when possible. +#if 201703 <= YY_CPLUSPLUS +# define YY_CONSTEXPR constexpr +#else +# define YY_CONSTEXPR +#endif[]dnl +]) + + +## ---------------- ## +## Default values. ## +## ---------------- ## + +b4_percent_define_default([[api.parser.class]], [[parser]]) + +# Don't do that so that we remember whether we're using a user +# request, or the default value. +# +# b4_percent_define_default([[api.location.type]], [[location]]) + +b4_percent_define_default([[filename_type]], [[std::string]]) +# Make it a warning for those who used betas of Bison 3.0. +b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix])) + +b4_percent_define_default([[global_tokens_and_yystype]], [[false]]) +b4_percent_define_default([[define_location_comparison]], + [m4_if(b4_percent_define_get([[filename_type]]), + [std::string], [[true]], [[false]])]) + + + +## ----------- ## +## Namespace. ## +## ----------- ## + +m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])]) + + +# Don't permit an empty b4_namespace_ref. Any '::parser::foo' appended to it +# would compile as an absolute reference with 'parser' in the global namespace. +# b4_namespace_open would open an anonymous namespace and thus establish +# internal linkage. This would compile. However, it's cryptic, and internal +# linkage for the parser would be specified in all translation units that +# include the header, which is always generated. If we ever need to permit +# internal linkage somehow, surely we can find a cleaner approach. +m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [], +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), + [[namespace reference is empty]])]) + +# Instead of assuming the C++ compiler will do it, Bison should reject any +# invalid b4_namespace_ref that would be converted to a valid +# b4_namespace_open. The problem is that Bison doesn't always output +# b4_namespace_ref to uncommented code but should reserve the ability to do so +# in future releases without risking breaking any existing user grammars. +# Specifically, don't allow empty names as b4_namespace_open would just convert +# those into anonymous namespaces, and that might tempt some users. +m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [], +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), + [[namespace reference has consecutive "::"]])]) +m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [], +[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]), + [[namespace reference has a trailing "::"]])]) + +m4_define([b4_namespace_open], +[b4_user_code([b4_percent_define_get_syncline([[api.namespace]]) +[namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref), + [^\(.\)[ ]*::], [\1])), + [::], [ { namespace ])[ {]])]) + +m4_define([b4_namespace_close], +[b4_user_code([b4_percent_define_get_syncline([[api.namespace]]) +m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]), + [^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*], + [\1])), + [::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])]) + + +# b4_token_enums +# -------------- +# Output the definition of the tokens as enums. +m4_define([b4_token_enums], +[[enum yytokentype + { + ]m4_join([, + ], + b4_symbol_map([b4_token_enum]))[ + };]dnl +]) + + + + +## ----------------- ## +## Semantic Values. ## +## ----------------- ## + + + +# b4_value_type_declare +# --------------------- +# Declare semantic_type. +m4_define([b4_value_type_declare], +[b4_value_type_setup[]dnl +[ /// Symbol semantic values. +]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), +[code], +[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]], +[m4_bmatch(b4_percent_define_get([[api.value.type]]), +[union\|union-directive], +[[ union semantic_type + { + ]b4_user_union_members[ + };]])])dnl +]) + + +# b4_public_types_declare +# ----------------------- +# Define the public types: token, semantic value, location, and so forth. +# Depending on %define token_lex, may be output in the header or source file. +m4_define([b4_public_types_declare], +[[#ifndef ]b4_api_PREFIX[STYPE +]b4_value_type_declare[ +#else + typedef ]b4_api_PREFIX[STYPE semantic_type; +#endif]b4_locations_if([ + /// Symbol locations. + typedef b4_percent_define_get([[api.location.type]], + [[location]]) location_type;])[ + + /// Syntax errors thrown from user actions. + struct syntax_error : std::runtime_error + { + syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m) + : std::runtime_error (m)]b4_locations_if([ + , location (l)])[ + {} + + syntax_error (const syntax_error& s) + : std::runtime_error (s.what ())]b4_locations_if([ + , location (s.location)])[ + {} + + ~syntax_error () YY_NOEXCEPT YY_NOTHROW;]b4_locations_if([ + + location_type location;])[ + }; + + /// Tokens. + struct token + { + ]b4_token_enums[ + }; + + /// (External) token type, as returned by yylex. + typedef token::yytokentype token_type; + + /// Symbol type: an internal symbol number. + typedef int symbol_number_type; + + /// The symbol type number to denote an empty symbol. + enum { empty_symbol = -2 }; + + /// Internal symbol number for tokens (subsumed by symbol_number_type). + typedef ]b4_int_type_for([b4_translate])[ token_number_type; +]]) + + +# b4_symbol_type_define +# --------------------- +# Define symbol_type, the external type for symbols used for symbol +# constructors. +m4_define([b4_symbol_type_define], +[[ /// A complete symbol. + /// + /// Expects its Base type to provide access to the symbol type + /// via type_get (). + /// + /// Provide access to semantic value]b4_locations_if([ and location])[. + template + struct basic_symbol : Base + { + /// Alias to Base. + typedef Base super_type; + + /// Default constructor. + basic_symbol () + : value ()]b4_locations_if([ + , location ()])[ + {} + +#if 201103L <= YY_CPLUSPLUS + /// Move constructor. + basic_symbol (basic_symbol&& that); +#endif + + /// Copy constructor. + basic_symbol (const basic_symbol& that);]b4_variant_if([[ + + /// Constructor for valueless symbols, and symbols from each type. +]b4_type_foreach([b4_basic_symbol_constructor_define])], [[ + /// Constructor for valueless symbols. + basic_symbol (typename Base::kind_type t]b4_locations_if([, + YY_MOVE_REF (location_type) l])[); + + /// Constructor for symbols with semantic value. + basic_symbol (typename Base::kind_type t, + YY_RVREF (semantic_type) v]b4_locations_if([, + YY_RVREF (location_type) l])[); +]])[ + /// Destroy the symbol. + ~basic_symbol () + { + clear (); + } + + /// Destroy contents, and record that is empty. + void clear () + {]b4_variant_if([[ + // User destructor. + symbol_number_type yytype = this->type_get (); + basic_symbol& yysym = *this; + (void) yysym; + switch (yytype) + { +]b4_symbol_foreach([b4_symbol_destructor])dnl +[ default: + break; + } + + // Type destructor. +]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[ + Base::clear (); + } + + /// Whether empty. + bool empty () const YY_NOEXCEPT; + + /// Destructive move, \a s is emptied into this. + void move (basic_symbol& s); + + /// The semantic value. + semantic_type value;]b4_locations_if([ + + /// The location. + location_type location;])[ + + private: +#if YY_CPLUSPLUS < 201103L + /// Assignment operator. + basic_symbol& operator= (const basic_symbol& that); +#endif + }; + + /// Type access provider for token (enum) based symbols. + struct by_type + { + /// Default constructor. + by_type (); + +#if 201103L <= YY_CPLUSPLUS + /// Move constructor. + by_type (by_type&& that); +#endif + + /// Copy constructor. + by_type (const by_type& that); + + /// The symbol type as needed by the constructor. + typedef token_type kind_type; + + /// Constructor from (external) token numbers. + by_type (kind_type t); + + /// Record that this symbol is empty. + void clear (); + + /// Steal the symbol type from \a that. + void move (by_type& that); + + /// The (internal) type number (corresponding to \a type). + /// \a empty when empty. + symbol_number_type type_get () const YY_NOEXCEPT; + + /// The token. + token_type token () const YY_NOEXCEPT; + + /// The symbol type. + /// \a empty_symbol when empty. + /// An int, not token_number_type, to be able to store empty_symbol. + int type; + }; + + /// "External" symbols: returned by the scanner. + struct symbol_type : basic_symbol + {]b4_variant_if([[ + /// Superclass. + typedef basic_symbol super_type; + + /// Empty symbol. + symbol_type () {} + + /// Constructor for valueless symbols, and symbols from each type. +]b4_type_foreach([_b4_token_constructor_define])dnl + ])[}; +]]) + + +# b4_public_types_define(hh|cc) +# ----------------------------- +# Provide the implementation needed by the public types. +m4_define([b4_public_types_define], +[[ // basic_symbol. +#if 201103L <= YY_CPLUSPLUS + template + ]b4_parser_class[::basic_symbol::basic_symbol (basic_symbol&& that) + : Base (std::move (that)) + , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([ + , location (std::move (that.location))])[ + {]b4_variant_if([ + b4_symbol_variant([this->type_get ()], [value], [move], + [std::move (that.value)]) + ])[} +#endif + + template + ]b4_parser_class[::basic_symbol::basic_symbol (const basic_symbol& that) + : Base (that) + , value (]b4_variant_if([], [that.value]))b4_locations_if([ + , location (that.location)])[ + {]b4_variant_if([ + b4_symbol_variant([this->type_get ()], [value], [copy], + [YY_MOVE (that.value)]) + ])[} + +]b4_variant_if([], [[ + /// Constructor for valueless symbols. + template + ]b4_parser_class[::basic_symbol::basic_symbol (]b4_join( + [typename Base::kind_type t], + b4_locations_if([YY_MOVE_REF (location_type) l]))[) + : Base (t) + , value ()]b4_locations_if([ + , location (l)])[ + {} + + template + ]b4_parser_class[::basic_symbol::basic_symbol (]b4_join( + [typename Base::kind_type t], + [YY_RVREF (semantic_type) v], + b4_locations_if([YY_RVREF (location_type) l]))[) + : Base (t) + , value (]b4_variant_if([], [YY_MOVE (v)])[)]b4_locations_if([ + , location (YY_MOVE (l))])[ + {]b4_variant_if([[ + (void) v; + ]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[ + + template + bool + ]b4_parser_class[::basic_symbol::empty () const YY_NOEXCEPT + { + return Base::type_get () == empty_symbol; + } + + template + void + ]b4_parser_class[::basic_symbol::move (basic_symbol& s) + { + super_type::move (s); + ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move], + [YY_MOVE (s.value)])], + [value = YY_MOVE (s.value);])[]b4_locations_if([ + location = YY_MOVE (s.location);])[ + } + + // by_type. + ]b4_inline([$1])b4_parser_class[::by_type::by_type () + : type (empty_symbol) + {} + +#if 201103L <= YY_CPLUSPLUS + ]b4_inline([$1])b4_parser_class[::by_type::by_type (by_type&& that) + : type (that.type) + { + that.clear (); + } +#endif + + ]b4_inline([$1])b4_parser_class[::by_type::by_type (const by_type& that) + : type (that.type) + {} + + ]b4_inline([$1])b4_parser_class[::by_type::by_type (token_type t) + : type (yytranslate_ (t)) + {} + + ]b4_inline([$1])[void + ]b4_parser_class[::by_type::clear () + { + type = empty_symbol; + } + + ]b4_inline([$1])[void + ]b4_parser_class[::by_type::move (by_type& that) + { + type = that.type; + that.clear (); + } + + ]b4_inline([$1])[int + ]b4_parser_class[::by_type::type_get () const YY_NOEXCEPT + { + return type; + } +]b4_token_ctor_if([[ + ]b4_inline([$1])b4_parser_class[::token_type + ]b4_parser_class[::by_type::token () const YY_NOEXCEPT + { + // YYTOKNUM[NUM] -- (External) token number corresponding to the + // (internal) symbol number NUM (which must be that of a token). */ + static + const ]b4_int_type_for([b4_toknum])[ + yytoken_number_[] = + { + ]b4_toknum[ + }; + return token_type (yytoken_number_[type]); + } +]])[]dnl +]) + + +# b4_token_constructor_define +# ---------------------------- +# Define symbol constructors for all the value types. +# Use at class-level. Redefined in variant.hh. +m4_define([b4_token_constructor_define], []) + + +# b4_yytranslate_define(cc|hh) +# ---------------------------- +# Define yytranslate_. Sometimes used in the header file ($1=hh), +# sometimes in the cc file. +m4_define([b4_yytranslate_define], +[ b4_inline([$1])b4_parser_class[::token_number_type + ]b4_parser_class[::yytranslate_ (]b4_token_ctor_if([token_type], + [int])[ t) + { + // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to + // TOKEN-NUM as returned by yylex. + static + const token_number_type + translate_table[] = + { + ]b4_translate[ + }; + const unsigned user_token_number_max_ = ]b4_user_token_number_max[; + const token_number_type undef_token_ = ]b4_undef_token_number[; + + if (static_cast (t) <= yyeof_) + return yyeof_; + else if (static_cast (t) <= user_token_number_max_) + return translate_table[t]; + else + return undef_token_; + } +]]) + + +# b4_lhs_value([TYPE]) +# -------------------- +m4_define([b4_lhs_value], +[b4_symbol_value([yyval], [$1])]) + + +# b4_rhs_value(RULE-LENGTH, POS, [TYPE]) +# -------------------------------------- +# FIXME: Dead code. +m4_define([b4_rhs_value], +[b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])]) + + +# b4_lhs_location() +# ----------------- +# Expansion of @$. +m4_define([b4_lhs_location], +[(yyloc)]) + + +# b4_rhs_location(RULE-LENGTH, POS) +# --------------------------------- +# Expansion of @POS, where the current rule has RULE-LENGTH symbols +# on RHS. +m4_define([b4_rhs_location], +[(yylocation_stack_@{($1) - ($2)@})]) + + +# b4_parse_param_decl +# ------------------- +# Extra formal arguments of the constructor. +# Change the parameter names from "foo" into "foo_yyarg", so that +# there is no collision bw the user chosen attribute name, and the +# argument name in the constructor. +m4_define([b4_parse_param_decl], +[m4_ifset([b4_parse_param], + [m4_map_sep([b4_parse_param_decl_1], [, ], [b4_parse_param])])]) + +m4_define([b4_parse_param_decl_1], +[$1_yyarg]) + + + +# b4_parse_param_cons +# ------------------- +# Extra initialisations of the constructor. +m4_define([b4_parse_param_cons], + [m4_ifset([b4_parse_param], + [ + b4_cc_constructor_calls(b4_parse_param)])]) +m4_define([b4_cc_constructor_calls], + [m4_map_sep([b4_cc_constructor_call], [, + ], [$@])]) +m4_define([b4_cc_constructor_call], + [$2 ($2_yyarg)]) + +# b4_parse_param_vars +# ------------------- +# Extra instance variables. +m4_define([b4_parse_param_vars], + [m4_ifset([b4_parse_param], + [ + // User arguments. +b4_cc_var_decls(b4_parse_param)])]) +m4_define([b4_cc_var_decls], + [m4_map_sep([b4_cc_var_decl], [ +], [$@])]) +m4_define([b4_cc_var_decl], + [ $1;]) + + +## ---------## +## Values. ## +## ---------## + +# b4_yylloc_default_define +# ------------------------ +# Define YYLLOC_DEFAULT. +m4_define([b4_yylloc_default_define], +[[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +# ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).begin = YYRHSLOC (Rhs, 1).begin; \ + (Current).end = YYRHSLOC (Rhs, N).end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \ + } \ + while (false) +# endif +]]) + +## -------- ## +## Checks. ## +## -------- ## + +b4_token_ctor_if([b4_variant_if([], + [b4_fatal_at(b4_percent_define_get_loc(api.token.constructor), + [cannot use '%s' without '%s'], + [%define api.token.constructor], + [%define api.value.type variant]))])]) diff --git a/msys2/usr/share/bison/skeletons/c-like.m4 b/msys2/usr/share/bison/skeletons/c-like.m4 new file mode 100644 index 0000000..8d891b6 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/c-like.m4 @@ -0,0 +1,66 @@ + -*- Autoconf -*- + +# Common code for C-like languages (C, C++, Java, etc.) + +# Copyright (C) 2012-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# _b4_comment(TEXT, OPEN, CONTINUE, END) +# -------------------------------------- +# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines. +# Avoid adding indentation to the first line, as the indentation comes +# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]). +# +# Prefix all the output lines with PREFIX. +m4_define([_b4_comment], +[$2[]m4_bpatsubst(m4_expand([[$1]]), [ +\(.\)], [ +$3\1])$4]) + + +# b4_comment(TEXT, [PREFIX]) +# -------------------------- +# Put TEXT in comment. Prefix all the output lines with PREFIX. +m4_define([b4_comment], +[_b4_comment([$1], [$2/* ], [$2 ], [ */])]) + + + + +# _b4_dollar_dollar(VALUE, SYMBOL-NUM, FIELD, DEFAULT-FIELD) +# ---------------------------------------------------------- +# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD", +# otherwise just VALUE. Be sure to pass "(VALUE)" if VALUE is a +# pointer. +m4_define([_b4_dollar_dollar], +[b4_symbol_value([$1], + [$2], + m4_if([$3], [[]], + [[$4]], [[$3]]))]) + +# b4_dollar_pushdef(VALUE-POINTER, SYMBOL-NUM, [TYPE_TAG], LOCATION) +# b4_dollar_popdef +# ------------------------------------------------------------------ +# Define b4_dollar_dollar for VALUE-POINTER and DEFAULT-FIELD, +# and b4_at_dollar for LOCATION. +m4_define([b4_dollar_pushdef], +[m4_pushdef([b4_dollar_dollar], + [_b4_dollar_dollar([$1], [$2], m4_dquote($][1), [$3])])dnl +m4_pushdef([b4_at_dollar], [$4])dnl +]) +m4_define([b4_dollar_popdef], +[m4_popdef([b4_at_dollar])dnl +m4_popdef([b4_dollar_dollar])dnl +]) diff --git a/share/bison/c-skel.m4 b/msys2/usr/share/bison/skeletons/c-skel.m4 similarity index 73% rename from share/bison/c-skel.m4 rename to msys2/usr/share/bison/skeletons/c-skel.m4 index 91f3c20..2a21cfc 100644 --- a/share/bison/c-skel.m4 +++ b/msys2/usr/share/bison/skeletons/c-skel.m4 @@ -1,7 +1,9 @@ -*- Autoconf -*- # C skeleton dispatching for Bison. -# Copyright (C) 2006, 2007 Free Software Foundation, Inc. + +# Copyright (C) 2006-2007, 2009-2015, 2018-2019 Free Software +# Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,10 +18,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])]) -b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])]) +b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])]) +b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])]) -m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[yacc.c]]) +m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[yacc.c]]) m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) m4_include(b4_used_skeleton) diff --git a/msys2/usr/share/bison/skeletons/c.m4 b/msys2/usr/share/bison/skeletons/c.m4 new file mode 100644 index 0000000..3cde04a --- /dev/null +++ b/msys2/usr/share/bison/skeletons/c.m4 @@ -0,0 +1,883 @@ + -*- Autoconf -*- + +# C M4 Macros for Bison. + +# Copyright (C) 2002, 2004-2015, 2018-2019 Free Software Foundation, +# Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_include(b4_skeletonsdir/[c-like.m4]) + +# b4_tocpp(STRING) +# ---------------- +# Convert STRING into a valid C macro name. +m4_define([b4_tocpp], +[m4_toupper(m4_bpatsubst(m4_quote($1), [[^a-zA-Z0-9]+], [_]))]) + + +# b4_cpp_guard(FILE) +# ------------------ +# A valid C macro name to use as a CPP header guard for FILE. +m4_define([b4_cpp_guard], +[[YY_]b4_tocpp(m4_defn([b4_prefix])/[$1])[_INCLUDED]]) + + +# b4_cpp_guard_open(FILE) +# b4_cpp_guard_close(FILE) +# ------------------------ +# If FILE does not expand to nothing, open/close CPP inclusion guards for FILE. +m4_define([b4_cpp_guard_open], +[m4_ifval(m4_quote($1), +[#ifndef b4_cpp_guard([$1]) +# define b4_cpp_guard([$1])])]) + +m4_define([b4_cpp_guard_close], +[m4_ifval(m4_quote($1), +[#endif b4_comment([!b4_cpp_guard([$1])])])]) + + +## ---------------- ## +## Identification. ## +## ---------------- ## + +# b4_identification +# ----------------- +# Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or +# b4_pull_flag if they use the values of the %define variables api.pure or +# api.push-pull. +m4_define([b4_identification], +[[/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "]b4_version[" + +/* Skeleton name. */ +#define YYSKELETON_NAME ]b4_skeleton[]m4_ifdef([b4_pure_flag], [[ + +/* Pure parsers. */ +#define YYPURE ]b4_pure_flag])[]m4_ifdef([b4_push_flag], [[ + +/* Push parsers. */ +#define YYPUSH ]b4_push_flag])[]m4_ifdef([b4_pull_flag], [[ + +/* Pull parsers. */ +#define YYPULL ]b4_pull_flag])[ +]]) + + +## ---------------- ## +## Default values. ## +## ---------------- ## + +# b4_api_prefix, b4_api_PREFIX +# ---------------------------- +# Corresponds to %define api.prefix +b4_percent_define_default([[api.prefix]], [[yy]]) +m4_define([b4_api_prefix], +[b4_percent_define_get([[api.prefix]])]) +m4_define([b4_api_PREFIX], +[m4_toupper(b4_api_prefix)]) + + +# b4_prefix +# --------- +# If the %name-prefix is not given, it is api.prefix. +m4_define_default([b4_prefix], [b4_api_prefix]) + +# If the %union is not named, its name is YYSTYPE. +b4_percent_define_default([[api.value.union.name]], + [b4_api_PREFIX[][STYPE]]) + + +## ------------------------ ## +## Pure/impure interfaces. ## +## ------------------------ ## + +# b4_lex_formals +# -------------- +# All the yylex formal arguments. +# b4_lex_param arrives quoted twice, but we want to keep only one level. +m4_define([b4_lex_formals], +[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl +b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl +m4_ifdef([b4_lex_param], [, ]b4_lex_param)]) + + +# b4_lex +# ------ +# Call yylex. +m4_define([b4_lex], +[b4_function_call([yylex], [int], b4_lex_formals)]) + + +# b4_user_args +# ------------ +m4_define([b4_user_args], +[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])]) + + +# b4_parse_param +# -------------- +# If defined, b4_parse_param arrives double quoted, but below we prefer +# it to be single quoted. +m4_define([b4_parse_param], +b4_parse_param) + + +# b4_parse_param_for(DECL, FORMAL, BODY) +# --------------------------------------- +# Iterate over the user parameters, binding the declaration to DECL, +# the formal name to FORMAL, and evaluating the BODY. +m4_define([b4_parse_param_for], +[m4_foreach([$1_$2], m4_defn([b4_parse_param]), +[m4_pushdef([$1], m4_unquote(m4_car($1_$2)))dnl +m4_pushdef([$2], m4_shift($1_$2))dnl +$3[]dnl +m4_popdef([$2])dnl +m4_popdef([$1])dnl +])]) + +# b4_parse_param_use([VAL], [LOC]) +# -------------------------------- +# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params. +m4_define([b4_parse_param_use], +[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl +b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl +b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal); +])dnl +]) + + +## ------------ ## +## Data Types. ## +## ------------ ## + +# b4_int_type(MIN, MAX) +# --------------------- +# Return the smallest int type able to handle numbers ranging from +# MIN to MAX (included). +m4_define([b4_int_type], +[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char], + b4_ints_in($@, [-128], [127]), [1], [signed char], + + b4_ints_in($@, [0], [65535]), [1], [unsigned short], + b4_ints_in($@, [-32768], [32767]), [1], [short], + + m4_eval([0 <= $1]), [1], [unsigned], + + [int])]) + + +# b4_int_type_for(NAME) +# --------------------- +# Return the smallest int type able to handle numbers ranging from +# 'NAME_min' to 'NAME_max' (included). +m4_define([b4_int_type_for], +[b4_int_type($1_min, $1_max)]) + + +# b4_table_value_equals(TABLE, VALUE, LITERAL) +# -------------------------------------------- +# Without inducing a comparison warning from the compiler, check if the +# literal value LITERAL equals VALUE from table TABLE, which must have +# TABLE_min and TABLE_max defined. +m4_define([b4_table_value_equals], +[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min]) + || m4_indir([b4_]$1[_max]) < $3), [1], + [[0]], + [(!!(($2) == ($3)))])]) + + +## ----------------- ## +## Compiler issues. ## +## ----------------- ## + +# b4_attribute_define([noreturn]) +# ------------------------------- +# Provide portable compiler "attributes". If "noreturn" is passed, define +# _Noreturn. +m4_define([b4_attribute_define], +[[#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */ +#if ! defined _Noreturn +# if defined __cplusplus && 201103L <= __cplusplus +# define _Noreturn [[noreturn]] +# elif !(defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__) +# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ + || 0x5110 <= __SUNPRO_C) +# define _Noreturn __attribute__ ((__noreturn__)) +# elif defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +# endif +#endif + +]])[/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif +]]) + + +# b4_null_define +# -------------- +# Portability issues: define a YY_NULLPTR appropriate for the current +# language (C, C++98, or C++11). +# +# In C++ pre C++11 it is standard practice to use 0 (not NULL) for the +# null pointer. In C, prefer ((void*)0) to avoid having to include stdlib.h. +m4_define([b4_null_define], +[# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif[]dnl +]) + + +# b4_null +# ------- +# Return a null pointer constant. +m4_define([b4_null], [YY_NULLPTR]) + + + +## ---------## +## Values. ## +## ---------## + +# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT) +# ------------------------------------------------------------- +# Define "yy" whose contents is CONTENT. +m4_define([b4_integral_parser_table_define], +[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl +static const b4_int_type_for([$2]) yy$1[[]] = +{ + $2 +};dnl +]) + + +## ------------------------- ## +## Assigning token numbers. ## +## ------------------------- ## + +# b4_token_define(TOKEN-NUM) +# -------------------------- +# Output the definition of this token as #define. +m4_define([b4_token_define], +[b4_token_format([#define %s %s], [$1])]) + +# b4_token_defines +# ---------------- +# Output the definition of the tokens. +m4_define([b4_token_defines], +[b4_any_token_visible_if([/* Tokens. */ +m4_join([ +], b4_symbol_map([b4_token_define])) +])]) + + +# b4_token_enum(TOKEN-NUM) +# ------------------------ +# Output the definition of this token as an enum. +m4_define([b4_token_enum], +[b4_token_format([%s = %s], [$1])]) + + +# b4_token_enums +# -------------- +# Output the definition of the tokens (if there are) as enums. +m4_define([b4_token_enums], +[b4_any_token_visible_if([[/* Token type. */ +#ifndef ]b4_api_PREFIX[TOKENTYPE +# define ]b4_api_PREFIX[TOKENTYPE + enum ]b4_api_prefix[tokentype + { + ]m4_join([, + ], + b4_symbol_map([b4_token_enum]))[ + }; +#endif +]])]) + + +# b4_token_enums_defines +# ---------------------- +# Output the definition of the tokens (if there are any) as enums and, +# if POSIX Yacc is enabled, as #defines. +m4_define([b4_token_enums_defines], +[b4_token_enums[]b4_yacc_if([b4_token_defines])]) + + +## ----------------- ## +## Semantic Values. ## +## ----------------- ## + + +# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG]) +# ---------------------------------------------- +# See README. +m4_define([b4_symbol_value], +[m4_ifval([$3], + [($1.$3)], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [($1.b4_symbol([$2], [type]))], + [$1])], + [$1])])]) + + +## ---------------------- ## +## Defining C functions. ## +## ---------------------- ## + + +# b4_function_define(NAME, RETURN-VALUE, [DECL1, NAME1], ...) +# ----------------------------------------------------------- +# Declare the function NAME in C. +m4_define([b4_function_define], +[$2 +$1 (b4_formals(m4_shift2($@)))[]dnl +]) + + +# b4_formals([DECL1, NAME1], ...) +# ------------------------------- +# The formal arguments of a C function definition. +m4_define([b4_formals], +[m4_if([$#], [0], [void], + [$#$1], [1], [void], + [m4_map_sep([b4_formal], [, ], [$@])])]) + +m4_define([b4_formal], +[$1]) + + + +## ----------------------- ## +## Declaring C functions. ## +## ----------------------- ## + + +# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...) +# ------------------------------------------------------------ +# Declare the function NAME. +m4_define([b4_function_declare], +[$2 $1 (b4_formals(m4_shift2($@)));[]dnl +]) + + + + +## --------------------- ## +## Calling C functions. ## +## --------------------- ## + + +# b4_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...) +# ----------------------------------------------------------- +# Call the function NAME with arguments NAME1, NAME2 etc. +m4_define([b4_function_call], +[$1 (b4_args(m4_shift2($@)))[]dnl +]) + + +# b4_args([DECL1, NAME1], ...) +# ---------------------------- +# Output the arguments NAME1, NAME2... +m4_define([b4_args], +[m4_map_sep([b4_arg], [, ], [$@])]) + +m4_define([b4_arg], +[$2]) + + +## ----------- ## +## Synclines. ## +## ----------- ## + +# b4_sync_start(LINE, FILE) +# ------------------------- +m4_define([b4_sync_start], [[#]line $1 $2]) + + +## -------------- ## +## User actions. ## +## -------------- ## + +# b4_case(LABEL, STATEMENTS) +# -------------------------- +m4_define([b4_case], +[ case $1: +$2 +b4_syncline([@oline@], [@ofile@]) + break;]) + + +# b4_predicate_case(LABEL, CONDITIONS) +# ------------------------------------ +m4_define([b4_predicate_case], +[ case $1: + if (! ( +$2)) YYERROR; +b4_syncline([@oline@], [@ofile@]) + break;]) + + +# b4_yydestruct_define +# -------------------- +# Define the "yydestruct" function. +m4_define_default([b4_yydestruct_define], +[[/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +]b4_function_define([yydestruct], + [static void], + [[const char *yymsg], [yymsg]], + [[int yytype], [yytype]], + [[YYSTYPE *yyvaluep], [yyvaluep]][]dnl +b4_locations_if( [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl +m4_ifset([b4_parse_param], [, b4_parse_param]))[ +{ +]b4_parse_param_use([yyvaluep], [yylocationp])dnl +[ if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + ]b4_symbol_actions([destructor])[ + YY_IGNORE_MAYBE_UNINITIALIZED_END +}]dnl +]) + + +# b4_yy_symbol_print_define +# ------------------------- +# Define the "yy_symbol_print" function. +m4_define_default([b4_yy_symbol_print_define], +[[ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +]b4_function_define([yy_symbol_value_print], + [static void], + [[FILE *yyo], [yyo]], + [[int yytype], [yytype]], + [[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl +b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl +m4_ifset([b4_parse_param], [, b4_parse_param]))[ +{ + FILE *yyoutput = yyo; +]b4_parse_param_use([yyoutput], [yylocationp])dnl +[ if (!yyvaluep) + return;] +dnl glr.c does not feature yytoknum. +m4_if(b4_skeleton, ["yacc.c"], +[[# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif +]])dnl + b4_symbol_actions([printer])[ +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +]b4_function_define([yy_symbol_print], + [static void], + [[FILE *yyo], [yyo]], + [[int yytype], [yytype]], + [[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl +b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl +m4_ifset([b4_parse_param], [, b4_parse_param]))[ +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + +]b4_locations_if([ YY_LOCATION_PRINT (yyo, *yylocationp); + YYFPRINTF (yyo, ": "); +])dnl +[ yy_symbol_value_print (yyo, yytype, yyvaluep]dnl +b4_locations_if([, yylocationp])[]b4_user_args[); + YYFPRINTF (yyo, ")"); +}]dnl +]) + + +## ---------------- ## +## api.value.type. ## +## ---------------- ## + + +# ---------------------- # +# api.value.type=union. # +# ---------------------- # + +# b4_symbol_type_register(SYMBOL-NUM) +# ----------------------------------- +# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag. +# Extend the definition of %union's body (b4_union_members) with a +# field of that type, and extend the symbol's "type" field to point to +# the field name, instead of the type name. +m4_define([b4_symbol_type_register], +[m4_define([b4_symbol($1, type_tag)], + [b4_symbol_if([$1], [has_id], + [b4_symbol([$1], [id])], + [yytype_[]b4_symbol([$1], [number])])])dnl +m4_append([b4_union_members], +m4_expand([ + b4_symbol_tag_comment([$1])dnl + b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);])) +]) + + +# b4_type_define_tag(SYMBOL1-NUM, ...) +# ------------------------------------ +# For the batch of symbols SYMBOL1-NUM... (which all have the same +# type), enhance the %union definition for each of them, and set +# there "type" field to the field tag name, instead of the type name. +m4_define([b4_type_define_tag], +[b4_symbol_if([$1], [has_type], + [m4_map([b4_symbol_type_register], [$@])]) +]) + + +# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE]) +# ---------------------------------------------- +# Same of b4_symbol_value, but when api.value.type=union. +m4_define([b4_symbol_value_union], +[m4_ifval([$3], + [(*($3*)(&$1))], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [($1.b4_symbol([$2], [type_tag]))], + [$1])], + [$1])])]) + + +# b4_value_type_setup_union +# ------------------------- +# Setup support for api.value.type=union. Symbols are defined with a +# type instead of a union member name: build the corresponding union, +# and give the symbols their tag. +m4_define([b4_value_type_setup_union], +[m4_define([b4_union_members]) +b4_type_foreach([b4_type_define_tag]) +m4_copy_force([b4_symbol_value_union], [b4_symbol_value]) +]) + + +# -------------------------- # +# api.value.type = variant. # +# -------------------------- # + +# b4_value_type_setup_variant +# --------------------------- +# Setup support for api.value.type=variant. By default, fail, specialized +# by other skeletons. +m4_define([b4_value_type_setup_variant], +[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]), + [['%s' does not support '%s']], + [b4_skeleton], + [%define api.value.type variant])]) + + +# _b4_value_type_setup_keyword +# ---------------------------- +# api.value.type is defined with a keyword/string syntax. Check if +# that is properly defined, and prepare its use. +m4_define([_b4_value_type_setup_keyword], +[b4_percent_define_check_values([[[[api.value.type]], + [[none]], + [[union]], + [[union-directive]], + [[variant]], + [[yystype]]]])dnl +m4_case(b4_percent_define_get([[api.value.type]]), + [union], [b4_value_type_setup_union], + [variant], [b4_value_type_setup_variant])]) + + +# b4_value_type_setup +# ------------------- +# Check if api.value.type is properly defined, and possibly prepare +# its use. +b4_define_silent([b4_value_type_setup], +[# Define default value. +b4_percent_define_ifdef([[api.value.type]], [], +[# %union => api.value.type=union-directive +m4_ifdef([b4_union_members], +[m4_define([b4_percent_define_kind(api.value.type)], [keyword]) +m4_define([b4_percent_define(api.value.type)], [union-directive])], +[# no tag seen => api.value.type={int} +m4_if(b4_tag_seen_flag, 0, +[m4_define([b4_percent_define_kind(api.value.type)], [code]) +m4_define([b4_percent_define(api.value.type)], [int])], +[# otherwise api.value.type=yystype +m4_define([b4_percent_define_kind(api.value.type)], [keyword]) +m4_define([b4_percent_define(api.value.type)], [yystype])])])]) + +# Set up. +m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), + [keyword\|string], [_b4_value_type_setup_keyword]) +]) + + +## -------------- ## +## Declarations. ## +## -------------- ## + + +# b4_value_type_define +# -------------------- +m4_define([b4_value_type_define], +[b4_value_type_setup[]dnl +/* Value type. */ +m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), +[code], +[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED +typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE; +# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1 +# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1 +#endif +]], +[m4_bmatch(b4_percent_define_get([[api.value.type]]), +[union\|union-directive], +[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED +]b4_percent_define_get_syncline([[api.value.union.name]])[ +union ]b4_percent_define_get([[api.value.union.name]])[ +{ +]b4_user_union_members[ +}; +]b4_percent_define_get_syncline([[api.value.union.name]])[ +typedef union ]b4_percent_define_get([[api.value.union.name]])[ ]b4_api_PREFIX[STYPE; +# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1 +# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1 +#endif +]])])]) + + +# b4_location_type_define +# ----------------------- +m4_define([b4_location_type_define], +[[/* Location type. */ +#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED +typedef struct ]b4_api_PREFIX[LTYPE ]b4_api_PREFIX[LTYPE; +struct ]b4_api_PREFIX[LTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1 +# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1 +#endif +]]) + + +# b4_declare_yylstype +# ------------------- +# Declarations that might either go into the header (if --defines) or +# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc. +m4_define([b4_declare_yylstype], +[b4_value_type_define[]b4_locations_if([ +b4_location_type_define]) + +b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval; +]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl +]) + + +# b4_YYDEBUG_define +# ----------------- +m4_define([b4_YYDEBUG_define], +[[/* Debug traces. */ +]m4_if(b4_api_prefix, [yy], +[[#ifndef YYDEBUG +# define YYDEBUG ]b4_parse_trace_if([1], [0])[ +#endif]], +[[#ifndef ]b4_api_PREFIX[DEBUG +# if defined YYDEBUG +#if YYDEBUG +# define ]b4_api_PREFIX[DEBUG 1 +# else +# define ]b4_api_PREFIX[DEBUG 0 +# endif +# else /* ! defined YYDEBUG */ +# define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[ +# endif /* ! defined YYDEBUG */ +#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl +]) + +# b4_declare_yydebug +# ------------------ +m4_define([b4_declare_yydebug], +[b4_YYDEBUG_define[ +#if ]b4_api_PREFIX[DEBUG +extern int ]b4_prefix[debug; +#endif][]dnl +]) + +# b4_yylloc_default_define +# ------------------------ +# Define YYLLOC_DEFAULT. +m4_define([b4_yylloc_default_define], +[[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) +#endif +]]) + +# b4_yy_location_print_define +# --------------------------- +# Define YY_LOCATION_PRINT. +m4_define([b4_yy_location_print_define], +[b4_locations_if([[ +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL + +/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +YY_ATTRIBUTE_UNUSED +]b4_function_define([yy_location_print_], + [static int], + [[FILE *yyo], [yyo]], + [[YYLTYPE const * const yylocp], [yylocp]])[ +{ + int res = 0; + int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; + if (0 <= yylocp->first_line) + { + res += YYFPRINTF (yyo, "%d", yylocp->first_line); + if (0 <= yylocp->first_column) + res += YYFPRINTF (yyo, ".%d", yylocp->first_column); + } + if (0 <= yylocp->last_line) + { + if (yylocp->first_line < yylocp->last_line) + { + res += YYFPRINTF (yyo, "-%d", yylocp->last_line); + if (0 <= end_col) + res += YYFPRINTF (yyo, ".%d", end_col); + } + else if (0 <= end_col && yylocp->first_column < end_col) + res += YYFPRINTF (yyo, "-%d", end_col); + } + return res; + } + +# define YY_LOCATION_PRINT(File, Loc) \ + yy_location_print_ (File, &(Loc)) + +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif]], +[[/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif]]) +]) + +# b4_yyloc_default +# ---------------- +# Expand to a possible default value for yylloc. +m4_define([b4_yyloc_default], +[[ +# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL + = { ]m4_join([, ], + m4_defn([b4_location_initial_line]), + m4_defn([b4_location_initial_column]), + m4_defn([b4_location_initial_line]), + m4_defn([b4_location_initial_column]))[ } +# endif +]]) diff --git a/msys2/usr/share/bison/skeletons/d-skel.m4 b/msys2/usr/share/bison/skeletons/d-skel.m4 new file mode 100644 index 0000000..1705d84 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/d-skel.m4 @@ -0,0 +1,26 @@ + -*- Autoconf -*- + +# D skeleton dispatching for Bison. + +# Copyright (C) 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +b4_glr_if( [b4_complain([%%glr-parser not supported for D])]) +b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for D])]) + +m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[lalr1.d]]) +m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) + +m4_include(b4_used_skeleton) diff --git a/share/bison/java.m4 b/msys2/usr/share/bison/skeletons/d.m4 similarity index 51% rename from share/bison/java.m4 rename to msys2/usr/share/bison/skeletons/d.m4 index b3dbd3b..946f013 100644 --- a/share/bison/java.m4 +++ b/msys2/usr/share/bison/skeletons/d.m4 @@ -1,8 +1,8 @@ -*- Autoconf -*- -# Java language support for Bison +# D language support for Bison -# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2018-2019 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,10 +26,10 @@ m4_define([b4_comment], [/* m4_bpatsubst([$1], [ # b4_list2(LIST1, LIST2) -# -------------------------- +# ---------------------- # Join two lists with a comma if necessary. m4_define([b4_list2], - [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2]) + [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2]) # b4_percent_define_get3(DEF, PRE, POST, NOT) @@ -37,9 +37,8 @@ m4_define([b4_list2], # Expand to the value of DEF surrounded by PRE and POST if it's %define'ed, # otherwise NOT. m4_define([b4_percent_define_get3], - [m4_ifval(m4_quote(b4_percent_define_get([$1])), - [$2[]b4_percent_define_get([$1])[]$3], [$4])]) - + [m4_ifval(m4_quote(b4_percent_define_get([$1])), + [$2[]b4_percent_define_get([$1])[]$3], [$4])]) # b4_flag_value(BOOLEAN-FLAG) @@ -47,48 +46,56 @@ m4_define([b4_percent_define_get3], m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])]) -# b4_public_if(TRUE, FALSE) -# ------------------------- -b4_percent_define_default([[public]], [[false]]) -m4_define([b4_public_if], -[b4_percent_define_flag_if([public], [$1], [$2])]) +# b4_parser_class_declaration +# --------------------------- +# The declaration of the parser class ("class YYParser"), with all its +# qualifiers/annotations. +b4_percent_define_default([[api.parser.abstract]], [[false]]) +b4_percent_define_default([[api.parser.final]], [[false]]) +b4_percent_define_default([[api.parser.public]], [[false]]) + +m4_define([b4_parser_class_declaration], +[b4_percent_define_get3([api.parser.annotations], [], [ ])dnl +b4_percent_define_flag_if([api.parser.public], [public ])dnl +b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl +b4_percent_define_flag_if([api.parser.final], [final ])dnl +[class ]b4_parser_class[]dnl +b4_percent_define_get3([api.parser.extends], [ extends ])dnl +b4_percent_define_get3([api.parser.implements], [ implements ])]) -# b4_abstract_if(TRUE, FALSE) -# --------------------------- -b4_percent_define_default([[abstract]], [[false]]) -m4_define([b4_abstract_if], -[b4_percent_define_flag_if([abstract], [$1], [$2])]) +# b4_lexer_if(TRUE, FALSE) +# ------------------------ +m4_define([b4_lexer_if], +[b4_percent_code_ifdef([[lexer]], [$1], [$2])]) -# b4_final_if(TRUE, FALSE) -# --------------------------- -b4_percent_define_default([[final]], [[false]]) -m4_define([b4_final_if], -[b4_percent_define_flag_if([final], [$1], [$2])]) +# b4_position_type_if(TRUE, FALSE) +# -------------------------------- +m4_define([b4_position_type_if], +[b4_percent_define_ifdef([[position_type]], [$1], [$2])]) -# b4_strictfp_if(TRUE, FALSE) -# --------------------------- -b4_percent_define_default([[strictfp]], [[false]]) -m4_define([b4_strictfp_if], -[b4_percent_define_flag_if([strictfp], [$1], [$2])]) +# b4_location_type_if(TRUE, FALSE) +# -------------------------------- +m4_define([b4_location_type_if], +[b4_percent_define_ifdef([[location_type]], [$1], [$2])]) -# b4_lexer_if(TRUE, FALSE) -# ------------------------ -m4_define([b4_lexer_if], -[b4_percent_code_ifdef([[lexer]], [$1], [$2])]) +# b4_locations_if(TRUE, FALSE) +# ---------------------------- +m4_define([b4_locations_if], +[m4_if(b4_locations_flag, 1, [$1], [$2])]) # b4_identification # ----------------- m4_define([b4_identification], -[ /** Version number for the Bison executable that generated this parser. */ - public static final String bisonVersion = "b4_version"; +[/** Version number for the Bison executable that generated this parser. */ + public static immutable string yy_bison_version = "b4_version"; /** Name of the skeleton that generated this parser. */ - public static final String bisonSkeleton = b4_skeleton; + public static immutable string yy_bison_skeleton = b4_skeleton; ]) @@ -103,7 +110,7 @@ m4_define([b4_identification], m4_define([b4_int_type], [m4_if(b4_ints_in($@, [-128], [127]), [1], [byte], b4_ints_in($@, [-32768], [32767]), [1], [short], - [int])]) + [int])]) # b4_int_type_for(NAME) # --------------------- @@ -117,6 +124,18 @@ m4_define([b4_int_type_for], m4_define([b4_null], [null]) +# b4_integral_parser_table_define(NAME, DATA, COMMENT) +#----------------------------------------------------- +# Define "yy" whose contents is CONTENT. +m4_define([b4_integral_parser_table_define], +[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl +private static immutable b4_int_type_for([$2])[[]] yy$1_ = +@{ + $2 +@};dnl +]) + + ## ------------------------- ## ## Assigning token numbers. ## ## ------------------------- ## @@ -125,28 +144,27 @@ m4_define([b4_null], [null]) # --------------------------------------- # Output the definition of this token as an enum. m4_define([b4_token_enum], -[ /** Token number, to be returned by the scanner. */ - public static final int $1 = $2; -]) - +[b4_token_format([ %s = %s, +], [$1])]) # b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER) # ----------------------------------------------------- -# Output the definition of the tokens (if there are) as enums. +# Output the definition of the tokens as enums. m4_define([b4_token_enums], -[m4_if([$#$1], [1], [], [/* Tokens. */ -m4_map([b4_token_enum], [$@])]) +public enum YYTokenType { + + /** Token returned by the scanner to signal the end of its input. */ + EOF = 0, +b4_symbol_foreach([b4_token_enum]) +} ]) # b4-case(ID, CODE) # ----------------- -# We need to fool Java's stupid unreachable code detection. -m4_define([b4_case], [ case $1: - if (yyn == $1) - $2; - break; - ]) +m4_define([b4_case], [ case $1: +$2 + break;]) ## ---------------- ## @@ -154,25 +172,19 @@ m4_define([b4_case], [ case $1: ## ---------------- ## m4_define([b4_yystype], [b4_percent_define_get([[stype]])]) -b4_percent_define_default([[stype]], [[Object]])]) +b4_percent_define_default([[stype]], [[YYSemanticType]])]) # %name-prefix m4_define_default([b4_prefix], [[YY]]) -b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])]) -m4_define([b4_parser_class_name], [b4_percent_define_get([[parser_class_name]])]) - -b4_percent_define_default([[lex_throws]], [[java.io.IOException]])]) -m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])]) - -b4_percent_define_default([[throws]], [])]) -m4_define([b4_throws], [b4_percent_define_get([[throws]])]) +b4_percent_define_default([[api.parser.class]], [b4_prefix[]YYParser])]) +m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])]) -b4_percent_define_default([[location_type]], [Location])]) -m4_define([b4_location_type], [b4_percent_define_get([[location_type]])]) +#b4_percent_define_default([[location_type]], [Location])]) +m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_percent_define_get([[location_type]])],[YYLocation])) -b4_percent_define_default([[position_type]], [Position])]) -m4_define([b4_position_type], [b4_percent_define_get([[position_type]])]) +#b4_percent_define_default([[position_type]], [Position])]) +m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition])) ## ----------------- ## @@ -180,21 +192,34 @@ m4_define([b4_position_type], [b4_percent_define_get([[position_type]])]) ## ----------------- ## -# b4_lhs_value([TYPE]) -# -------------------- -# Expansion of $$. -m4_define([b4_lhs_value], [yyval]) - - -# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) -# -------------------------------------- -# Expansion of $NUM, where the current rule has RULE-LENGTH -# symbols on RHS. +# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG]) +# ---------------------------------------------- +# See README. FIXME: factor in c-like? +m4_define([b4_symbol_value], +[m4_ifval([$3], + [($1.$3)], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [($1.b4_symbol([$2], [type]))], + [$1])], + [$1])])]) + +# b4_lhs_value(SYMBOL-NUM, [TYPE]) +# -------------------------------- +# See README. +m4_define([b4_lhs_value], +[b4_symbol_value([yyval], [$1], [$2])]) + + +# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE]) +# -------------------------------------------------- +# See README. # # In this simple implementation, %token and %type have class names # between the angle brackets. m4_define([b4_rhs_value], -[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))]) +[b4_symbol_value([(yystack.valueAt (b4_subtract([$1], [$2])))], [$3], [$4])]) + # b4_lhs_location() # ----------------- @@ -203,12 +228,12 @@ m4_define([b4_lhs_location], [(yyloc)]) -# b4_rhs_location(RULE-LENGTH, NUM) +# b4_rhs_location(RULE-LENGTH, POS) # --------------------------------- -# Expansion of @NUM, where the current rule has RULE-LENGTH symbols +# Expansion of @POS, where the current rule has RULE-LENGTH symbols # on RHS. m4_define([b4_rhs_location], -[yystack.locationAt ($1-($2))]) +[yystack.locationAt ([$1], [$2])]) # b4_lex_param @@ -228,11 +253,11 @@ m4_define([b4_parse_param], b4_parse_param)) m4_define([b4_lex_param_decl], [m4_ifset([b4_lex_param], [b4_remove_comma([$1], - b4_param_decls(b4_lex_param))], - [$1])]) + b4_param_decls(b4_lex_param))], + [$1])]) m4_define([b4_param_decls], - [m4_map([b4_param_decl], [$@])]) + [m4_map([b4_param_decl], [$@])]) m4_define([b4_param_decl], [, $1]) m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)]) @@ -245,8 +270,8 @@ m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)]) m4_define([b4_parse_param_decl], [m4_ifset([b4_parse_param], [b4_remove_comma([$1], - b4_param_decls(b4_parse_param))], - [$1])]) + b4_param_decls(b4_parse_param))], + [$1])]) @@ -255,11 +280,11 @@ m4_define([b4_parse_param_decl], # Delegating the lexer parameters to the lexer constructor. m4_define([b4_lex_param_call], [m4_ifset([b4_lex_param], - [b4_remove_comma([$1], - b4_param_calls(b4_lex_param))], - [$1])]) + [b4_remove_comma([$1], + b4_param_calls(b4_lex_param))], + [$1])]) m4_define([b4_param_calls], - [m4_map([b4_param_call], [$@])]) + [m4_map([b4_param_call], [$@])]) m4_define([b4_param_call], [, $2]) @@ -269,13 +294,13 @@ m4_define([b4_param_call], [, $2]) # Extra initialisations of the constructor. m4_define([b4_parse_param_cons], [m4_ifset([b4_parse_param], - [b4_constructor_calls(b4_parse_param)])]) + [b4_constructor_calls(b4_parse_param)])]) m4_define([b4_constructor_calls], - [m4_map([b4_constructor_call], [$@])]) + [m4_map([b4_constructor_call], [$@])]) m4_define([b4_constructor_call], - [this.$2 = $2; - ]) + [this.$2 = $2; + ]) @@ -284,20 +309,12 @@ m4_define([b4_constructor_call], # Extra instance variables. m4_define([b4_parse_param_vars], [m4_ifset([b4_parse_param], - [ + [ /* User arguments. */ b4_var_decls(b4_parse_param)])]) m4_define([b4_var_decls], - [m4_map_sep([b4_var_decl], [ + [m4_map_sep([b4_var_decl], [ ], [$@])]) m4_define([b4_var_decl], - [ protected final $1;]) - - - -# b4_maybe_throws(THROWS) -# ----------------------- -# Expand to either an empty string or "throws THROWS". -m4_define([b4_maybe_throws], - [m4_ifval($1, [throws $1])]) + [ protected $1;]) diff --git a/msys2/usr/share/bison/skeletons/glr.c b/msys2/usr/share/bison/skeletons/glr.c new file mode 100644 index 0000000..87f2830 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/glr.c @@ -0,0 +1,2604 @@ + -*- C -*- + +# GLR skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# If we are loaded by glr.cc, do not override c++.m4 definitions by +# those of c.m4. +m4_if(b4_skeleton, ["glr.c"], + [m4_include(b4_skeletonsdir/[c.m4])]) + + +## ---------------- ## +## Default values. ## +## ---------------- ## + +# Stack parameters. +m4_define_default([b4_stack_depth_max], [10000]) +m4_define_default([b4_stack_depth_init], [200]) + + + +## ------------------------ ## +## Pure/impure interfaces. ## +## ------------------------ ## + +b4_define_flag_if([pure]) +# If glr.cc is including this file and thus has already set b4_pure_flag, +# do not change the value of b4_pure_flag, and do not record a use of api.pure. +m4_ifndef([b4_pure_flag], +[b4_percent_define_default([[api.pure]], [[false]]) + m4_define([b4_pure_flag], + [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])])]) + +# b4_user_formals +# --------------- +# The possible parse-params formal arguments preceded by a comma. +# +# This is not shared with yacc.c in c.m4 because GLR relies on ISO C +# formal argument declarations. +m4_define([b4_user_formals], +[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])]) + + +# b4_yyerror_args +# --------------- +# Optional effective arguments passed to yyerror: user args plus yylloc, and +# a trailing comma. +m4_define([b4_yyerror_args], +[b4_pure_if([b4_locations_if([yylocp, ])])dnl +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])]) + + +# b4_lyyerror_args +# ---------------- +# Same as above, but on the lookahead, hence &yylloc instead of yylocp. +m4_define([b4_lyyerror_args], +[b4_pure_if([b4_locations_if([&yylloc, ])])dnl +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])]) + + +# b4_pure_args +# ------------ +# Same as b4_yyerror_args, but with a leading comma. +m4_define([b4_pure_args], +[b4_pure_if([b4_locations_if([, yylocp])])[]b4_user_args]) + + +# b4_lpure_args +# ------------- +# Same as above, but on the lookahead, hence &yylloc instead of yylocp. +m4_define([b4_lpure_args], +[b4_pure_if([b4_locations_if([, &yylloc])])[]b4_user_args]) + + + +# b4_pure_formals +# --------------- +# Arguments passed to yyerror: user formals plus yylocp with leading comma. +m4_define([b4_pure_formals], +[b4_pure_if([b4_locations_if([, YYLTYPE *yylocp])])[]b4_user_formals]) + + +# b4_locuser_formals(LOC = yylocp) +# -------------------------------- +# User formal arguments, possibly preceded by location argument. +m4_define([b4_locuser_formals], +[b4_locations_if([, YYLTYPE *m4_default([$1], [yylocp])])[]b4_user_formals]) + + +# b4_locuser_args(LOC = yylocp) +# ----------------------------- +m4_define([b4_locuser_args], +[b4_locations_if([, m4_default([$1], [yylocp])])[]b4_user_args]) + + + +## ----------------- ## +## Semantic Values. ## +## ----------------- ## + + +# b4_lhs_value(SYMBOL-NUM, [TYPE]) +# -------------------------------- +# See README. +m4_define([b4_lhs_value], +[b4_symbol_value([(*yyvalp)], [$1], [$2])]) + + +# b4_rhs_data(RULE-LENGTH, POS) +# ----------------------------- +# See README. +m4_define([b4_rhs_data], +[((yyGLRStackItem const *)yyvsp)@{YYFILL (b4_subtract([$2], [$1]))@}.yystate]) + + +# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE]) +# -------------------------------------------------- +# Expansion of $$ or $$, for symbol SYMBOL-NUM. +m4_define([b4_rhs_value], +[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])]) + + + +## ----------- ## +## Locations. ## +## ----------- ## + +# b4_lhs_location() +# ----------------- +# Expansion of @$. +m4_define([b4_lhs_location], +[(*yylocp)]) + + +# b4_rhs_location(RULE-LENGTH, NUM) +# --------------------------------- +# Expansion of @NUM, where the current rule has RULE-LENGTH symbols +# on RHS. +m4_define([b4_rhs_location], +[(b4_rhs_data([$1], [$2]).yyloc)]) + + +## -------------- ## +## Declarations. ## +## -------------- ## + +# b4_shared_declarations +# ---------------------- +# Declaration that might either go into the header (if --defines) +# or open coded in the parser body. glr.cc has its own definition. +m4_if(b4_skeleton, ["glr.c"], +[m4_define([b4_shared_declarations], +[b4_declare_yydebug[ +]b4_percent_code_get([[requires]])[ +]b4_token_enums[ +]b4_declare_yylstype[ +]b4_function_declare(b4_prefix[parse], [int], b4_parse_param)[ +]b4_percent_code_get([[provides]])[]dnl +]) +]) + +## -------------- ## +## Output files. ## +## -------------- ## + +# Unfortunately the order of generation between the header and the +# implementation file matters (for glr.c) because of the current +# implementation of api.value.type=union. In that case we still use a +# union for YYSTYPE, but we generate the contents of this union when +# setting up YYSTYPE. This is needed for other aspects, such as +# defining yy_symbol_value_print, since we need to now the name of the +# members of this union. +# +# To avoid this issue, just generate the header before the +# implementation file. But we should also make them more independant. + +# ----------------- # +# The header file. # +# ----------------- # + +# glr.cc produces its own header. +b4_glr_cc_if([], +[b4_defines_if( +[b4_output_begin([b4_spec_defines_file]) +b4_copyright([Skeleton interface for Bison GLR parsers in C], + [2002-2015, 2018-2019])[ +]b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_shared_declarations[ +]b4_cpp_guard_close([b4_spec_defines_file])[ +]b4_output_end +])]) + + +# ------------------------- # +# The implementation file. # +# ------------------------- # + +b4_output_begin([b4_parser_file_name]) +b4_copyright([Skeleton implementation for Bison GLR parsers in C], + [2002-2015, 2018-2019])[ +/* C GLR parser skeleton written by Paul Hilfinger. */ + +]b4_disclaimer[ +]b4_identification[ + +]b4_percent_code_get([[top]])[ +]m4_if(b4_api_prefix, [yy], [], +[[/* Substitute the type names. */ +#define YYSTYPE ]b4_api_PREFIX[STYPE]b4_locations_if([[ +#define YYLTYPE ]b4_api_PREFIX[LTYPE]])])[ +]m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yydebug ]b4_prefix[debug]]b4_pure_if([], [[ +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])]))[ + +]b4_user_pre_prologue[ + +]b4_null_define[ + +]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]], + [b4_shared_declarations])[ + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[ +#endif + +/* Default (constant) value used for initialization for null + right-hand sides. Unlike the standard yacc.c template, here we set + the default value of $$ to a zeroed-out value. Since the default + value is undefined, this behavior is technically correct. */ +static YYSTYPE yyval_default;]b4_locations_if([[ +static YYLTYPE yyloc_default][]b4_yyloc_default;])[ + +]b4_user_post_prologue[ +]b4_percent_code_get[]dnl + +[#include +#include +#include + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YYFREE +# define YYFREE free +#endif +#ifndef YYMALLOC +# define YYMALLOC malloc +#endif +#ifndef YYREALLOC +# define YYREALLOC realloc +#endif + +#define YYSIZEMAX ((size_t) -1) + +#ifdef __cplusplus + typedef bool yybool; +# define yytrue true +# define yyfalse false +#else + /* When we move to stdbool, get rid of the various casts to yybool. */ + typedef unsigned char yybool; +# define yytrue 1 +# define yyfalse 0 +#endif + +#ifndef YYSETJMP +# include +# define YYJMP_BUF jmp_buf +# define YYSETJMP(Env) setjmp (Env) +/* Pacify Clang and ICC. */ +# define YYLONGJMP(Env, Val) \ + do { \ + longjmp (Env, Val); \ + YYASSERT (0); \ + } while (yyfalse) +#endif + +]b4_attribute_define([noreturn])[ + +#ifndef YYASSERT +# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0))) +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL ]b4_final_state_number[ +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST ]b4_last[ + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS ]b4_tokens_number[ +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS ]b4_nterms_number[ +/* YYNRULES -- Number of rules. */ +#define YYNRULES ]b4_rules_number[ +/* YYNSTATES -- Number of states. */ +#define YYNSTATES ]b4_states_number[ +/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */ +#define YYMAXRHS ]b4_r2_max[ +/* YYMAXLEFT -- Maximum number of symbols to the left of a handle + accessed by $0, $-1, etc., in any rule. */ +#define YYMAXLEFT ]b4_max_left_semantic_context[ + +/* YYMAXUTOK -- Last valid token number (for yychar). */ +#define YYMAXUTOK ]b4_user_token_number_max[]b4_glr_cc_if([[ +/* YYFAULTYTOK -- Token number (for yychar) that denotes a + syntax_error thrown from the scanner. */ +#define YYFAULTYTOK (YYMAXUTOK + 1)]])[ +/* YYUNDEFTOK -- Symbol number (for yytoken) that denotes an unknown + token. */ +#define YYUNDEFTOK ]b4_undef_token_number[ + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const ]b4_int_type_for([b4_translate])[ yytranslate[] = +{ + ]b4_translate[ +}; + +#if ]b4_api_PREFIX[DEBUG +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const ]b4_int_type_for([b4_rline])[ yyrline[] = +{ + ]b4_rline[ +}; +#endif + +#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[ +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + ]b4_tname[ +}; +#endif + +#define YYPACT_NINF ]b4_pact_ninf[ +#define YYTABLE_NINF ]b4_table_ninf[ + +]b4_parser_tables_define[ + +/* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none). */ +static const ]b4_int_type_for([b4_dprec])[ yydprec[] = +{ + ]b4_dprec[ +}; + +/* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM. */ +static const ]b4_int_type_for([b4_merger])[ yymerger[] = +{ + ]b4_merger[ +}; + +/* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as + in the case of predicates. */ +static const yybool yyimmediate[] = +{ + ]b4_immediate[ +}; + +/* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of + list of conflicting reductions corresponding to action entry for + state STATE-NUM in yytable. 0 means no conflicts. The list in + yyconfl is terminated by a rule number of 0. */ +static const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] = +{ + ]b4_conflict_list_heads[ +}; + +/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by + 0, pointed into by YYCONFLP. */ +]dnl Do not use b4_int_type_for here, since there are places where +dnl pointers onto yyconfl are taken, whose type is "short*". +dnl We probably ought to introduce a type for confl. +[static const short yyconfl[] = +{ + ]b4_conflicting_rules[ +}; + +/* Error token number */ +#define YYTERROR 1 + +]b4_locations_if([[ +]b4_yylloc_default_define[ +# define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc) +]])[ + +]b4_pure_if( +[ +#undef yynerrs +#define yynerrs (yystackp->yyerrcnt) +#undef yychar +#define yychar (yystackp->yyrawchar) +#undef yylval +#define yylval (yystackp->yyval) +#undef yylloc +#define yylloc (yystackp->yyloc) +m4_if(b4_prefix[], [yy], [], +[#define b4_prefix[]nerrs yynerrs +#define b4_prefix[]char yychar +#define b4_prefix[]lval yylval +#define b4_prefix[]lloc yylloc])], +[YYSTYPE yylval;]b4_locations_if([[ +YYLTYPE yylloc;]])[ + +int yynerrs; +int yychar;])[ + +static const int YYEOF = 0; +static const int YYEMPTY = -2; + +typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG; + +#define YYCHK(YYE) \ + do { \ + YYRESULTTAG yychk_flag = YYE; \ + if (yychk_flag != yyok) \ + return yychk_flag; \ + } while (0) + +#if ]b4_api_PREFIX[DEBUG + +# ifndef YYFPRINTF +# define YYFPRINTF fprintf +# endif + +]b4_yy_location_print_define[ + +# define YYDPRINTF(Args) \ + do { \ + if (yydebug) \ + YYFPRINTF Args; \ + } while (0) + +]b4_yy_symbol_print_define[ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ + do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, Type, Value]b4_locuser_args([Location])[); \ + YYFPRINTF (stderr, "\n"); \ + } \ + } while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; + +struct yyGLRStack; +static void yypstack (struct yyGLRStack* yystackp, size_t yyk) + YY_ATTRIBUTE_UNUSED; +static void yypdumpstack (struct yyGLRStack* yystackp) + YY_ATTRIBUTE_UNUSED; + +#else /* !]b4_api_PREFIX[DEBUG */ + +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) + +#endif /* !]b4_api_PREFIX[DEBUG */ + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH ]b4_stack_depth_init[ +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYMAXDEPTH * sizeof (GLRStackItem) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH ]b4_stack_depth_max[ +#endif + +/* Minimum number of free items on the stack allowed after an + allocation. This is to allow allocation and initialization + to be completed by functions that call yyexpandGLRStack before the + stack is expanded, thus insuring that all necessary pointers get + properly redirected to new data. */ +#define YYHEADROOM 2 + +#ifndef YYSTACKEXPANDABLE +# define YYSTACKEXPANDABLE 1 +#endif + +#if YYSTACKEXPANDABLE +# define YY_RESERVE_GLRSTACK(Yystack) \ + do { \ + if (Yystack->yyspaceLeft < YYHEADROOM) \ + yyexpandGLRStack (Yystack); \ + } while (0) +#else +# define YY_RESERVE_GLRSTACK(Yystack) \ + do { \ + if (Yystack->yyspaceLeft < YYHEADROOM) \ + yyMemoryExhausted (Yystack); \ + } while (0) +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static size_t +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + size_t yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return strlen (yystr); + + return (size_t) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +#endif /* !YYERROR_VERBOSE */ + +/** State numbers, as in LALR(1) machine */ +typedef int yyStateNum; + +/** Rule numbers, as in LALR(1) machine */ +typedef int yyRuleNum; + +/** Grammar symbol */ +typedef int yySymbol; + +/** Item references, as in LALR(1) machine */ +typedef short yyItemNum; + +typedef struct yyGLRState yyGLRState; +typedef struct yyGLRStateSet yyGLRStateSet; +typedef struct yySemanticOption yySemanticOption; +typedef union yyGLRStackItem yyGLRStackItem; +typedef struct yyGLRStack yyGLRStack; + +struct yyGLRState { + /** Type tag: always true. */ + yybool yyisState; + /** Type tag for yysemantics. If true, yysval applies, otherwise + * yyfirstVal applies. */ + yybool yyresolved; + /** Number of corresponding LALR(1) machine state. */ + yyStateNum yylrState; + /** Preceding state in this stack */ + yyGLRState* yypred; + /** Source position of the last token produced by my symbol */ + size_t yyposn; + union { + /** First in a chain of alternative reductions producing the + * nonterminal corresponding to this state, threaded through + * yynext. */ + yySemanticOption* yyfirstVal; + /** Semantic value for this state. */ + YYSTYPE yysval; + } yysemantics;]b4_locations_if([[ + /** Source location for this state. */ + YYLTYPE yyloc;]])[ +}; + +struct yyGLRStateSet { + yyGLRState** yystates; + /** During nondeterministic operation, yylookaheadNeeds tracks which + * stacks have actually needed the current lookahead. During deterministic + * operation, yylookaheadNeeds[0] is not maintained since it would merely + * duplicate yychar != YYEMPTY. */ + yybool* yylookaheadNeeds; + size_t yysize, yycapacity; +}; + +struct yySemanticOption { + /** Type tag: always false. */ + yybool yyisState; + /** Rule number for this reduction */ + yyRuleNum yyrule; + /** The last RHS state in the list of states to be reduced. */ + yyGLRState* yystate; + /** The lookahead for this reduction. */ + int yyrawchar; + YYSTYPE yyval;]b4_locations_if([[ + YYLTYPE yyloc;]])[ + /** Next sibling in chain of options. To facilitate merging, + * options are chained in decreasing order by address. */ + yySemanticOption* yynext; +}; + +/** Type of the items in the GLR stack. The yyisState field + * indicates which item of the union is valid. */ +union yyGLRStackItem { + yyGLRState yystate; + yySemanticOption yyoption; +}; + +struct yyGLRStack { + int yyerrState; +]b4_locations_if([[ /* To compute the location of the error token. */ + yyGLRStackItem yyerror_range[3];]])[ +]b4_pure_if( +[ + int yyerrcnt; + int yyrawchar; + YYSTYPE yyval;]b4_locations_if([[ + YYLTYPE yyloc;]])[ +])[ + YYJMP_BUF yyexception_buffer; + yyGLRStackItem* yyitems; + yyGLRStackItem* yynextFree; + size_t yyspaceLeft; + yyGLRState* yysplitPoint; + yyGLRState* yylastDeleted; + yyGLRStateSet yytops; +}; + +#if YYSTACKEXPANDABLE +static void yyexpandGLRStack (yyGLRStack* yystackp); +#endif + +_Noreturn static void +yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg) +{ + if (yymsg != YY_NULLPTR) + yyerror (]b4_yyerror_args[yymsg); + YYLONGJMP (yystackp->yyexception_buffer, 1); +} + +_Noreturn static void +yyMemoryExhausted (yyGLRStack* yystackp) +{ + YYLONGJMP (yystackp->yyexception_buffer, 2); +} + +#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE +/** A printable representation of TOKEN. */ +static inline const char* +yytokenName (yySymbol yytoken) +{ + if (yytoken == YYEMPTY) + return ""; + + return yytname[yytoken]; +} +#endif + +/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting + * at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred + * containing the pointer to the next state in the chain. */ +static void yyfillin (yyGLRStackItem *, int, int) YY_ATTRIBUTE_UNUSED; +static void +yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1) +{ + int i; + yyGLRState *s = yyvsp[yylow0].yystate.yypred; + for (i = yylow0-1; i >= yylow1; i -= 1) + { +#if ]b4_api_PREFIX[DEBUG + yyvsp[i].yystate.yylrState = s->yylrState; +#endif + yyvsp[i].yystate.yyresolved = s->yyresolved; + if (s->yyresolved) + yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval; + else + /* The effect of using yysval or yyloc (in an immediate rule) is + * undefined. */ + yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[ + yyvsp[i].yystate.yyloc = s->yyloc;]])[ + s = yyvsp[i].yystate.yypred = s->yypred; + } +} + +]m4_define([b4_yygetToken_call], + [[yygetToken (&yychar][]b4_pure_if([, yystackp])[]b4_user_args[)]])[ +/** If yychar is empty, fetch the next token. */ +static inline yySymbol +yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals[) +{ + yySymbol yytoken; +]b4_parse_param_use()dnl +[ if (*yycharp == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: "));]b4_glr_cc_if([[ +#if YY_EXCEPTIONS + try + { +#endif // YY_EXCEPTIONS + *yycharp = ]b4_lex[; +#if YY_EXCEPTIONS + } + catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc) + { + YYDPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([ + yylloc = yyexc.location;])[ + yyerror (]b4_lyyerror_args[yyexc.what ()); + // Map errors caught in the scanner to the undefined token + // (YYUNDEFTOK), so that error handling is started. + // However, record this with this special value of yychar. + *yycharp = YYFAULTYTOK; + } +#endif // YY_EXCEPTIONS]], [[ + *yycharp = ]b4_lex[;]])[ + } + if (*yycharp <= YYEOF) + { + *yycharp = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (*yycharp); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + return yytoken; +} + +/* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1. Otherwise, fill in + * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1. + * For convenience, always return YYLOW1. */ +static inline int yyfill (yyGLRStackItem *, int *, int, yybool) + YY_ATTRIBUTE_UNUSED; +static inline int +yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal) +{ + if (!yynormal && yylow1 < *yylow) + { + yyfillin (yyvsp, *yylow, yylow1); + *yylow = yylow1; + } + return yylow1; +} + +/** Perform user action for rule number YYN, with RHS length YYRHSLEN, + * and top stack item YYVSP. YYLVALP points to place to put semantic + * value ($$), and yylocp points to place for location information + * (@@$). Returns yyok for normal return, yyaccept for YYACCEPT, + * yyerr for YYERROR, yyabort for YYABORT. */ +static YYRESULTTAG +yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, + yyGLRStack* yystackp, + YYSTYPE* yyvalp]b4_locuser_formals[) +{ + yybool yynormal YY_ATTRIBUTE_UNUSED = (yybool) (yystackp->yysplitPoint == YY_NULLPTR); + int yylow; +]b4_parse_param_use([yyvalp], [yylocp])dnl +[ YYUSE (yyrhslen); +# undef yyerrok +# define yyerrok (yystackp->yyerrState = 0) +# undef YYACCEPT +# define YYACCEPT return yyaccept +# undef YYABORT +# define YYABORT return yyabort +# undef YYERROR +# define YYERROR return yyerrok, yyerr +# undef YYRECOVERING +# define YYRECOVERING() (yystackp->yyerrState != 0) +# undef yyclearin +# define yyclearin (yychar = YYEMPTY) +# undef YYFILL +# define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal) +# undef YYBACKUP +# define YYBACKUP(Token, Value) \ + return yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")), \ + yyerrok, yyerr + + yylow = 1; + if (yyrhslen == 0) + *yyvalp = yyval_default; + else + *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;]b4_locations_if([[ + /* Default location. */ + YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen); + yystackp->yyerror_range[1].yystate.yyloc = *yylocp; +]])[]b4_glr_cc_if([[ +#if YY_EXCEPTIONS + typedef ]b4_namespace_ref[::]b4_parser_class[::syntax_error syntax_error; + try + { +#endif // YY_EXCEPTIONS]])[ + switch (yyn) + { +]b4_user_actions[ + default: break; + }]b4_glr_cc_if([[ +#if YY_EXCEPTIONS + } + catch (const syntax_error& yyexc) + { + YYDPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));]b4_locations_if([ + *yylocp = yyexc.location;])[ + yyerror (]b4_yyerror_args[yyexc.what ()); + YYERROR; + } +#endif // YY_EXCEPTIONS]])[ + + return yyok; +# undef yyerrok +# undef YYABORT +# undef YYACCEPT +# undef YYERROR +# undef YYBACKUP +# undef yyclearin +# undef YYRECOVERING +} + + +static void +yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1) +{ + YYUSE (yy0); + YYUSE (yy1); + + switch (yyn) + { +]b4_mergers[ + default: break; + } +} + + /* Bison grammar-table manipulation. */ + +]b4_yydestruct_define[ + +/** Number of symbols composing the right hand side of rule #RULE. */ +static inline int +yyrhsLength (yyRuleNum yyrule) +{ + return yyr2[yyrule]; +} + +static void +yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[) +{ + if (yys->yyresolved) + yydestruct (yymsg, yystos[yys->yylrState], + &yys->yysemantics.yysval]b4_locuser_args([&yys->yyloc])[); + else + { +#if ]b4_api_PREFIX[DEBUG + if (yydebug) + { + if (yys->yysemantics.yyfirstVal) + YYFPRINTF (stderr, "%s unresolved", yymsg); + else + YYFPRINTF (stderr, "%s incomplete", yymsg); + YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc); + } +#endif + + if (yys->yysemantics.yyfirstVal) + { + yySemanticOption *yyoption = yys->yysemantics.yyfirstVal; + yyGLRState *yyrh; + int yyn; + for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule); + yyn > 0; + yyrh = yyrh->yypred, yyn -= 1) + yydestroyGLRState (yymsg, yyrh]b4_user_args[); + } + } +} + +/** Left-hand-side symbol for rule #YYRULE. */ +static inline yySymbol +yylhsNonterm (yyRuleNum yyrule) +{ + return yyr1[yyrule]; +} + +#define yypact_value_is_default(Yystate) \ + ]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[ + +/** True iff LR state YYSTATE has only a default reduction (regardless + * of token). */ +static inline yybool +yyisDefaultedState (yyStateNum yystate) +{ + return (yybool) yypact_value_is_default (yypact[yystate]); +} + +/** The default reduction for YYSTATE, assuming it has one. */ +static inline yyRuleNum +yydefaultAction (yyStateNum yystate) +{ + return yydefact[yystate]; +} + +#define yytable_value_is_error(Yytable_value) \ + ]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[ + +/** The action to take in YYSTATE on seeing YYTOKEN. + * Result R means + * R < 0: Reduce on rule -R. + * R = 0: Error. + * R > 0: Shift to state R. + * Set *YYCONFLICTS to a pointer into yyconfl to a 0-terminated list + * of conflicting reductions. + */ +static inline int +yygetLRActions (yyStateNum yystate, yySymbol yytoken, const short** yyconflicts) +{ + int yyindex = yypact[yystate] + yytoken; + if (yyisDefaultedState (yystate) + || yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken) + { + *yyconflicts = yyconfl; + return -yydefact[yystate]; + } + else if (! yytable_value_is_error (yytable[yyindex])) + { + *yyconflicts = yyconfl + yyconflp[yyindex]; + return yytable[yyindex]; + } + else + { + *yyconflicts = yyconfl + yyconflp[yyindex]; + return 0; + } +} + +/** Compute post-reduction state. + * \param yystate the current state + * \param yysym the nonterminal to push on the stack + */ +static inline yyStateNum +yyLRgotoState (yyStateNum yystate, yySymbol yysym) +{ + int yyr = yypgoto[yysym - YYNTOKENS] + yystate; + if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate) + return yytable[yyr]; + else + return yydefgoto[yysym - YYNTOKENS]; +} + +static inline yybool +yyisShiftAction (int yyaction) +{ + return (yybool) (0 < yyaction); +} + +static inline yybool +yyisErrorAction (int yyaction) +{ + return (yybool) (yyaction == 0); +} + + /* GLRStates */ + +/** Return a fresh GLRStackItem in YYSTACKP. The item is an LR state + * if YYISSTATE, and otherwise a semantic option. Callers should call + * YY_RESERVE_GLRSTACK afterwards to make sure there is sufficient + * headroom. */ + +static inline yyGLRStackItem* +yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState) +{ + yyGLRStackItem* yynewItem = yystackp->yynextFree; + yystackp->yyspaceLeft -= 1; + yystackp->yynextFree += 1; + yynewItem->yystate.yyisState = yyisState; + return yynewItem; +} + +/** Add a new semantic action that will execute the action for rule + * YYRULE on the semantic values in YYRHS to the list of + * alternative actions for YYSTATE. Assumes that YYRHS comes from + * stack #YYK of *YYSTACKP. */ +static void +yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate, + yyGLRState* yyrhs, yyRuleNum yyrule) +{ + yySemanticOption* yynewOption = + &yynewGLRStackItem (yystackp, yyfalse)->yyoption; + YYASSERT (!yynewOption->yyisState); + yynewOption->yystate = yyrhs; + yynewOption->yyrule = yyrule; + if (yystackp->yytops.yylookaheadNeeds[yyk]) + { + yynewOption->yyrawchar = yychar; + yynewOption->yyval = yylval;]b4_locations_if([ + yynewOption->yyloc = yylloc;])[ + } + else + yynewOption->yyrawchar = YYEMPTY; + yynewOption->yynext = yystate->yysemantics.yyfirstVal; + yystate->yysemantics.yyfirstVal = yynewOption; + + YY_RESERVE_GLRSTACK (yystackp); +} + + /* GLRStacks */ + +/** Initialize YYSET to a singleton set containing an empty stack. */ +static yybool +yyinitStateSet (yyGLRStateSet* yyset) +{ + yyset->yysize = 1; + yyset->yycapacity = 16; + yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]); + if (! yyset->yystates) + return yyfalse; + yyset->yystates[0] = YY_NULLPTR; + yyset->yylookaheadNeeds = + (yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]); + if (! yyset->yylookaheadNeeds) + { + YYFREE (yyset->yystates); + return yyfalse; + } + return yytrue; +} + +static void yyfreeStateSet (yyGLRStateSet* yyset) +{ + YYFREE (yyset->yystates); + YYFREE (yyset->yylookaheadNeeds); +} + +/** Initialize *YYSTACKP to a single empty stack, with total maximum + * capacity for all stacks of YYSIZE. */ +static yybool +yyinitGLRStack (yyGLRStack* yystackp, size_t yysize) +{ + yystackp->yyerrState = 0; + yynerrs = 0; + yystackp->yyspaceLeft = yysize; + yystackp->yyitems = + (yyGLRStackItem*) YYMALLOC (yysize * sizeof yystackp->yynextFree[0]); + if (!yystackp->yyitems) + return yyfalse; + yystackp->yynextFree = yystackp->yyitems; + yystackp->yysplitPoint = YY_NULLPTR; + yystackp->yylastDeleted = YY_NULLPTR; + return yyinitStateSet (&yystackp->yytops); +} + + +#if YYSTACKEXPANDABLE +# define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \ + &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE + +/** If *YYSTACKP is expandable, extend it. WARNING: Pointers into the + stack from outside should be considered invalid after this call. + We always expand when there are 1 or fewer items left AFTER an + allocation, so that we can avoid having external pointers exist + across an allocation. */ +static void +yyexpandGLRStack (yyGLRStack* yystackp) +{ + yyGLRStackItem* yynewItems; + yyGLRStackItem* yyp0, *yyp1; + size_t yynewSize; + size_t yyn; + size_t yysize = (size_t) (yystackp->yynextFree - yystackp->yyitems); + if (YYMAXDEPTH - YYHEADROOM < yysize) + yyMemoryExhausted (yystackp); + yynewSize = 2*yysize; + if (YYMAXDEPTH < yynewSize) + yynewSize = YYMAXDEPTH; + yynewItems = (yyGLRStackItem*) YYMALLOC (yynewSize * sizeof yynewItems[0]); + if (! yynewItems) + yyMemoryExhausted (yystackp); + for (yyp0 = yystackp->yyitems, yyp1 = yynewItems, yyn = yysize; + 0 < yyn; + yyn -= 1, yyp0 += 1, yyp1 += 1) + { + *yyp1 = *yyp0; + if (*(yybool *) yyp0) + { + yyGLRState* yys0 = &yyp0->yystate; + yyGLRState* yys1 = &yyp1->yystate; + if (yys0->yypred != YY_NULLPTR) + yys1->yypred = + YYRELOC (yyp0, yyp1, yys0->yypred, yystate); + if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULLPTR) + yys1->yysemantics.yyfirstVal = + YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption); + } + else + { + yySemanticOption* yyv0 = &yyp0->yyoption; + yySemanticOption* yyv1 = &yyp1->yyoption; + if (yyv0->yystate != YY_NULLPTR) + yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate); + if (yyv0->yynext != YY_NULLPTR) + yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption); + } + } + if (yystackp->yysplitPoint != YY_NULLPTR) + yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems, + yystackp->yysplitPoint, yystate); + + for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1) + if (yystackp->yytops.yystates[yyn] != YY_NULLPTR) + yystackp->yytops.yystates[yyn] = + YYRELOC (yystackp->yyitems, yynewItems, + yystackp->yytops.yystates[yyn], yystate); + YYFREE (yystackp->yyitems); + yystackp->yyitems = yynewItems; + yystackp->yynextFree = yynewItems + yysize; + yystackp->yyspaceLeft = yynewSize - yysize; +} +#endif + +static void +yyfreeGLRStack (yyGLRStack* yystackp) +{ + YYFREE (yystackp->yyitems); + yyfreeStateSet (&yystackp->yytops); +} + +/** Assuming that YYS is a GLRState somewhere on *YYSTACKP, update the + * splitpoint of *YYSTACKP, if needed, so that it is at least as deep as + * YYS. */ +static inline void +yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys) +{ + if (yystackp->yysplitPoint != YY_NULLPTR && yystackp->yysplitPoint > yys) + yystackp->yysplitPoint = yys; +} + +/** Invalidate stack #YYK in *YYSTACKP. */ +static inline void +yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk) +{ + if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) + yystackp->yylastDeleted = yystackp->yytops.yystates[yyk]; + yystackp->yytops.yystates[yyk] = YY_NULLPTR; +} + +/** Undelete the last stack in *YYSTACKP that was marked as deleted. Can + only be done once after a deletion, and only when all other stacks have + been deleted. */ +static void +yyundeleteLastStack (yyGLRStack* yystackp) +{ + if (yystackp->yylastDeleted == YY_NULLPTR || yystackp->yytops.yysize != 0) + return; + yystackp->yytops.yystates[0] = yystackp->yylastDeleted; + yystackp->yytops.yysize = 1; + YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n")); + yystackp->yylastDeleted = YY_NULLPTR; +} + +static inline void +yyremoveDeletes (yyGLRStack* yystackp) +{ + size_t yyi, yyj; + yyi = yyj = 0; + while (yyj < yystackp->yytops.yysize) + { + if (yystackp->yytops.yystates[yyi] == YY_NULLPTR) + { + if (yyi == yyj) + { + YYDPRINTF ((stderr, "Removing dead stacks.\n")); + } + yystackp->yytops.yysize -= 1; + } + else + { + yystackp->yytops.yystates[yyj] = yystackp->yytops.yystates[yyi]; + /* In the current implementation, it's unnecessary to copy + yystackp->yytops.yylookaheadNeeds[yyi] since, after + yyremoveDeletes returns, the parser immediately either enters + deterministic operation or shifts a token. However, it doesn't + hurt, and the code might evolve to need it. */ + yystackp->yytops.yylookaheadNeeds[yyj] = + yystackp->yytops.yylookaheadNeeds[yyi]; + if (yyj != yyi) + { + YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n", + (unsigned long) yyi, (unsigned long) yyj)); + } + yyj += 1; + } + yyi += 1; + } +} + +/** Shift to a new state on stack #YYK of *YYSTACKP, corresponding to LR + * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic + * value *YYVALP and source location *YYLOCP. */ +static inline void +yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState, + size_t yyposn, + YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[) +{ + yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate; + + yynewState->yylrState = yylrState; + yynewState->yyposn = yyposn; + yynewState->yyresolved = yytrue; + yynewState->yypred = yystackp->yytops.yystates[yyk]; + yynewState->yysemantics.yysval = *yyvalp;]b4_locations_if([ + yynewState->yyloc = *yylocp;])[ + yystackp->yytops.yystates[yyk] = yynewState; + + YY_RESERVE_GLRSTACK (yystackp); +} + +/** Shift stack #YYK of *YYSTACKP, to a new state corresponding to LR + * state YYLRSTATE, at input position YYPOSN, with the (unresolved) + * semantic value of YYRHS under the action for YYRULE. */ +static inline void +yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState, + size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule) +{ + yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate; + YYASSERT (yynewState->yyisState); + + yynewState->yylrState = yylrState; + yynewState->yyposn = yyposn; + yynewState->yyresolved = yyfalse; + yynewState->yypred = yystackp->yytops.yystates[yyk]; + yynewState->yysemantics.yyfirstVal = YY_NULLPTR; + yystackp->yytops.yystates[yyk] = yynewState; + + /* Invokes YY_RESERVE_GLRSTACK. */ + yyaddDeferredAction (yystackp, yyk, yynewState, yyrhs, yyrule); +} + +#if !]b4_api_PREFIX[DEBUG +# define YY_REDUCE_PRINT(Args) +#else +# define YY_REDUCE_PRINT(Args) \ + do { \ + if (yydebug) \ + yy_reduce_print Args; \ + } while (0) + +/*----------------------------------------------------------------------. +| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. | +`----------------------------------------------------------------------*/ + +static inline void +yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, size_t yyk, + yyRuleNum yyrule]b4_user_formals[) +{ + int yynrhs = yyrhsLength (yyrule);]b4_locations_if([ + int yylow = 1;])[ + int yyi; + YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n", + (unsigned long) yyk, yyrule - 1, + (unsigned long) yyrline[yyrule]); + if (! yynormal) + yyfillin (yyvsp, 1, -yynrhs); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyvsp[yyi - yynrhs + 1].yystate.yylrState], + &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval]b4_locations_if([, + &]b4_rhs_location(yynrhs, yyi + 1))[]dnl + b4_user_args[); + if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved) + YYFPRINTF (stderr, " (unresolved)"); + YYFPRINTF (stderr, "\n"); + } +} +#endif + +/** Pop the symbols consumed by reduction #YYRULE from the top of stack + * #YYK of *YYSTACKP, and perform the appropriate semantic action on their + * semantic values. Assumes that all ambiguities in semantic values + * have been previously resolved. Set *YYVALP to the resulting value, + * and *YYLOCP to the computed location (if any). Return value is as + * for userAction. */ +static inline YYRESULTTAG +yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule, + YYSTYPE* yyvalp]b4_locuser_formals[) +{ + int yynrhs = yyrhsLength (yyrule); + + if (yystackp->yysplitPoint == YY_NULLPTR) + { + /* Standard special case: single stack. */ + yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk]; + YYASSERT (yyk == 0); + yystackp->yynextFree -= yynrhs; + yystackp->yyspaceLeft += (size_t) yynrhs; + yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate; + YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule]b4_user_args[)); + return yyuserAction (yyrule, yynrhs, yyrhs, yystackp, + yyvalp]b4_locuser_args[); + } + else + { + int yyi; + yyGLRState* yys; + yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; + yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred + = yystackp->yytops.yystates[yyk];]b4_locations_if([[ + if (yynrhs == 0) + /* Set default location. */ + yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[ + for (yyi = 0; yyi < yynrhs; yyi += 1) + { + yys = yys->yypred; + YYASSERT (yys); + } + yyupdateSplit (yystackp, yys); + yystackp->yytops.yystates[yyk] = yys; + YY_REDUCE_PRINT ((yyfalse, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule]b4_user_args[)); + return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, + yystackp, yyvalp]b4_locuser_args[); + } +} + +/** Pop items off stack #YYK of *YYSTACKP according to grammar rule YYRULE, + * and push back on the resulting nonterminal symbol. Perform the + * semantic action associated with YYRULE and store its value with the + * newly pushed state, if YYFORCEEVAL or if *YYSTACKP is currently + * unambiguous. Otherwise, store the deferred semantic action with + * the new state. If the new state would have an identical input + * position, LR state, and predecessor to an existing state on the stack, + * it is identified with that existing state, eliminating stack #YYK from + * *YYSTACKP. In this case, the semantic value is + * added to the options for the existing state's semantic value. + */ +static inline YYRESULTTAG +yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule, + yybool yyforceEval]b4_user_formals[) +{ + size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn; + + if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR) + { + YYSTYPE yysval;]b4_locations_if([[ + YYLTYPE yyloc;]])[ + + YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[); + if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR) + { + YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n", + (unsigned long) yyk, yyrule - 1)); + } + if (yyflag != yyok) + return yyflag; + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc); + yyglrShift (yystackp, yyk, + yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState, + yylhsNonterm (yyrule)), + yyposn, &yysval]b4_locations_if([, &yyloc])[); + } + else + { + size_t yyi; + int yyn; + yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk]; + yyStateNum yynewLRState; + + for (yys = yystackp->yytops.yystates[yyk], yyn = yyrhsLength (yyrule); + 0 < yyn; yyn -= 1) + { + yys = yys->yypred; + YYASSERT (yys); + } + yyupdateSplit (yystackp, yys); + yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule)); + YYDPRINTF ((stderr, + "Reduced stack %lu by rule #%d; action deferred. " + "Now in state %d.\n", + (unsigned long) yyk, yyrule - 1, yynewLRState)); + for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1) + if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR) + { + yyGLRState *yysplit = yystackp->yysplitPoint; + yyGLRState *yyp = yystackp->yytops.yystates[yyi]; + while (yyp != yys && yyp != yysplit && yyp->yyposn >= yyposn) + { + if (yyp->yylrState == yynewLRState && yyp->yypred == yys) + { + yyaddDeferredAction (yystackp, yyk, yyp, yys0, yyrule); + yymarkStackDeleted (yystackp, yyk); + YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n", + (unsigned long) yyk, + (unsigned long) yyi)); + return yyok; + } + yyp = yyp->yypred; + } + } + yystackp->yytops.yystates[yyk] = yys; + yyglrShiftDefer (yystackp, yyk, yynewLRState, yyposn, yys0, yyrule); + } + return yyok; +} + +static size_t +yysplitStack (yyGLRStack* yystackp, size_t yyk) +{ + if (yystackp->yysplitPoint == YY_NULLPTR) + { + YYASSERT (yyk == 0); + yystackp->yysplitPoint = yystackp->yytops.yystates[yyk]; + } + if (yystackp->yytops.yysize >= yystackp->yytops.yycapacity) + { + yyGLRState** yynewStates = YY_NULLPTR; + yybool* yynewLookaheadNeeds; + + if (yystackp->yytops.yycapacity + > (YYSIZEMAX / (2 * sizeof yynewStates[0]))) + yyMemoryExhausted (yystackp); + yystackp->yytops.yycapacity *= 2; + + yynewStates = + (yyGLRState**) YYREALLOC (yystackp->yytops.yystates, + (yystackp->yytops.yycapacity + * sizeof yynewStates[0])); + if (yynewStates == YY_NULLPTR) + yyMemoryExhausted (yystackp); + yystackp->yytops.yystates = yynewStates; + + yynewLookaheadNeeds = + (yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds, + (yystackp->yytops.yycapacity + * sizeof yynewLookaheadNeeds[0])); + if (yynewLookaheadNeeds == YY_NULLPTR) + yyMemoryExhausted (yystackp); + yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds; + } + yystackp->yytops.yystates[yystackp->yytops.yysize] + = yystackp->yytops.yystates[yyk]; + yystackp->yytops.yylookaheadNeeds[yystackp->yytops.yysize] + = yystackp->yytops.yylookaheadNeeds[yyk]; + yystackp->yytops.yysize += 1; + return yystackp->yytops.yysize-1; +} + +/** True iff YYY0 and YYY1 represent identical options at the top level. + * That is, they represent the same rule applied to RHS symbols + * that produce the same terminal symbols. */ +static yybool +yyidenticalOptions (yySemanticOption* yyy0, yySemanticOption* yyy1) +{ + if (yyy0->yyrule == yyy1->yyrule) + { + yyGLRState *yys0, *yys1; + int yyn; + for (yys0 = yyy0->yystate, yys1 = yyy1->yystate, + yyn = yyrhsLength (yyy0->yyrule); + yyn > 0; + yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1) + if (yys0->yyposn != yys1->yyposn) + return yyfalse; + return yytrue; + } + else + return yyfalse; +} + +/** Assuming identicalOptions (YYY0,YYY1), destructively merge the + * alternative semantic values for the RHS-symbols of YYY1 and YYY0. */ +static void +yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1) +{ + yyGLRState *yys0, *yys1; + int yyn; + for (yys0 = yyy0->yystate, yys1 = yyy1->yystate, + yyn = yyrhsLength (yyy0->yyrule); + yyn > 0; + yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1) + { + if (yys0 == yys1) + break; + else if (yys0->yyresolved) + { + yys1->yyresolved = yytrue; + yys1->yysemantics.yysval = yys0->yysemantics.yysval; + } + else if (yys1->yyresolved) + { + yys0->yyresolved = yytrue; + yys0->yysemantics.yysval = yys1->yysemantics.yysval; + } + else + { + yySemanticOption** yyz0p = &yys0->yysemantics.yyfirstVal; + yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal; + while (yytrue) + { + if (yyz1 == *yyz0p || yyz1 == YY_NULLPTR) + break; + else if (*yyz0p == YY_NULLPTR) + { + *yyz0p = yyz1; + break; + } + else if (*yyz0p < yyz1) + { + yySemanticOption* yyz = *yyz0p; + *yyz0p = yyz1; + yyz1 = yyz1->yynext; + (*yyz0p)->yynext = yyz; + } + yyz0p = &(*yyz0p)->yynext; + } + yys1->yysemantics.yyfirstVal = yys0->yysemantics.yyfirstVal; + } + } +} + +/** Y0 and Y1 represent two possible actions to take in a given + * parsing state; return 0 if no combination is possible, + * 1 if user-mergeable, 2 if Y0 is preferred, 3 if Y1 is preferred. */ +static int +yypreference (yySemanticOption* y0, yySemanticOption* y1) +{ + yyRuleNum r0 = y0->yyrule, r1 = y1->yyrule; + int p0 = yydprec[r0], p1 = yydprec[r1]; + + if (p0 == p1) + { + if (yymerger[r0] == 0 || yymerger[r0] != yymerger[r1]) + return 0; + else + return 1; + } + if (p0 == 0 || p1 == 0) + return 0; + if (p0 < p1) + return 3; + if (p1 < p0) + return 2; + return 0; +} + +static YYRESULTTAG yyresolveValue (yyGLRState* yys, + yyGLRStack* yystackp]b4_user_formals[); + + +/** Resolve the previous YYN states starting at and including state YYS + * on *YYSTACKP. If result != yyok, some states may have been left + * unresolved possibly with empty semantic option chains. Regardless + * of whether result = yyok, each state has been left with consistent + * data so that yydestroyGLRState can be invoked if necessary. */ +static YYRESULTTAG +yyresolveStates (yyGLRState* yys, int yyn, + yyGLRStack* yystackp]b4_user_formals[) +{ + if (0 < yyn) + { + YYASSERT (yys->yypred); + YYCHK (yyresolveStates (yys->yypred, yyn-1, yystackp]b4_user_args[)); + if (! yys->yyresolved) + YYCHK (yyresolveValue (yys, yystackp]b4_user_args[)); + } + return yyok; +} + +/** Resolve the states for the RHS of YYOPT on *YYSTACKP, perform its + * user action, and return the semantic value and location in *YYVALP + * and *YYLOCP. Regardless of whether result = yyok, all RHS states + * have been destroyed (assuming the user action destroys all RHS + * semantic values if invoked). */ +static YYRESULTTAG +yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp, + YYSTYPE* yyvalp]b4_locuser_formals[) +{ + yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; + int yynrhs = yyrhsLength (yyopt->yyrule); + YYRESULTTAG yyflag = + yyresolveStates (yyopt->yystate, yynrhs, yystackp]b4_user_args[); + if (yyflag != yyok) + { + yyGLRState *yys; + for (yys = yyopt->yystate; yynrhs > 0; yys = yys->yypred, yynrhs -= 1) + yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[); + return yyflag; + } + + yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;]b4_locations_if([[ + if (yynrhs == 0) + /* Set default location. */ + yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yyopt->yystate->yyloc;]])[ + { + int yychar_current = yychar; + YYSTYPE yylval_current = yylval;]b4_locations_if([ + YYLTYPE yylloc_current = yylloc;])[ + yychar = yyopt->yyrawchar; + yylval = yyopt->yyval;]b4_locations_if([ + yylloc = yyopt->yyloc;])[ + yyflag = yyuserAction (yyopt->yyrule, yynrhs, + yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, + yystackp, yyvalp]b4_locuser_args[); + yychar = yychar_current; + yylval = yylval_current;]b4_locations_if([ + yylloc = yylloc_current;])[ + } + return yyflag; +} + +#if ]b4_api_PREFIX[DEBUG +static void +yyreportTree (yySemanticOption* yyx, int yyindent) +{ + int yynrhs = yyrhsLength (yyx->yyrule); + int yyi; + yyGLRState* yys; + yyGLRState* yystates[1 + YYMAXRHS]; + yyGLRState yyleftmost_state; + + for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred) + yystates[yyi] = yys; + if (yys == YY_NULLPTR) + { + yyleftmost_state.yyposn = 0; + yystates[0] = &yyleftmost_state; + } + else + yystates[0] = yys; + + if (yyx->yystate->yyposn < yys->yyposn + 1) + YYFPRINTF (stderr, "%*s%s -> \n", + yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)), + yyx->yyrule - 1); + else + YYFPRINTF (stderr, "%*s%s -> \n", + yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)), + yyx->yyrule - 1, (unsigned long) (yys->yyposn + 1), + (unsigned long) yyx->yystate->yyposn); + for (yyi = 1; yyi <= yynrhs; yyi += 1) + { + if (yystates[yyi]->yyresolved) + { + if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn) + YYFPRINTF (stderr, "%*s%s \n", yyindent+2, "", + yytokenName (yystos[yystates[yyi]->yylrState])); + else + YYFPRINTF (stderr, "%*s%s \n", yyindent+2, "", + yytokenName (yystos[yystates[yyi]->yylrState]), + (unsigned long) (yystates[yyi-1]->yyposn + 1), + (unsigned long) yystates[yyi]->yyposn); + } + else + yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2); + } +} +#endif + +static YYRESULTTAG +yyreportAmbiguity (yySemanticOption* yyx0, + yySemanticOption* yyx1]b4_pure_formals[) +{ + YYUSE (yyx0); + YYUSE (yyx1); + +#if ]b4_api_PREFIX[DEBUG + YYFPRINTF (stderr, "Ambiguity detected.\n"); + YYFPRINTF (stderr, "Option 1,\n"); + yyreportTree (yyx0, 2); + YYFPRINTF (stderr, "\nOption 2,\n"); + yyreportTree (yyx1, 2); + YYFPRINTF (stderr, "\n"); +#endif + + yyerror (]b4_yyerror_args[YY_("syntax is ambiguous")); + return yyabort; +}]b4_locations_if([[ + +/** Resolve the locations for each of the YYN1 states in *YYSTACKP, + * ending at YYS1. Has no effect on previously resolved states. + * The first semantic option of a state is always chosen. */ +static void +yyresolveLocations (yyGLRState *yys1, int yyn1, + yyGLRStack *yystackp]b4_user_formals[) +{ + if (0 < yyn1) + { + yyresolveLocations (yys1->yypred, yyn1 - 1, yystackp]b4_user_args[); + if (!yys1->yyresolved) + { + yyGLRStackItem yyrhsloc[1 + YYMAXRHS]; + int yynrhs; + yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal; + YYASSERT (yyoption); + yynrhs = yyrhsLength (yyoption->yyrule); + if (0 < yynrhs) + { + yyGLRState *yys; + int yyn; + yyresolveLocations (yyoption->yystate, yynrhs, + yystackp]b4_user_args[); + for (yys = yyoption->yystate, yyn = yynrhs; + yyn > 0; + yys = yys->yypred, yyn -= 1) + yyrhsloc[yyn].yystate.yyloc = yys->yyloc; + } + else + { + /* Both yyresolveAction and yyresolveLocations traverse the GSS + in reverse rightmost order. It is only necessary to invoke + yyresolveLocations on a subforest for which yyresolveAction + would have been invoked next had an ambiguity not been + detected. Thus the location of the previous state (but not + necessarily the previous state itself) is guaranteed to be + resolved already. */ + yyGLRState *yyprevious = yyoption->yystate; + yyrhsloc[0].yystate.yyloc = yyprevious->yyloc; + } + YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs); + } + } +}]])[ + +/** Resolve the ambiguity represented in state YYS in *YYSTACKP, + * perform the indicated actions, and set the semantic value of YYS. + * If result != yyok, the chain of semantic options in YYS has been + * cleared instead or it has been left unmodified except that + * redundant options may have been removed. Regardless of whether + * result = yyok, YYS has been left with consistent data so that + * yydestroyGLRState can be invoked if necessary. */ +static YYRESULTTAG +yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[) +{ + yySemanticOption* yyoptionList = yys->yysemantics.yyfirstVal; + yySemanticOption* yybest = yyoptionList; + yySemanticOption** yypp; + yybool yymerge = yyfalse; + YYSTYPE yysval; + YYRESULTTAG yyflag;]b4_locations_if([ + YYLTYPE *yylocp = &yys->yyloc;])[ + + for (yypp = &yyoptionList->yynext; *yypp != YY_NULLPTR; ) + { + yySemanticOption* yyp = *yypp; + + if (yyidenticalOptions (yybest, yyp)) + { + yymergeOptionSets (yybest, yyp); + *yypp = yyp->yynext; + } + else + { + switch (yypreference (yybest, yyp)) + { + case 0:]b4_locations_if([[ + yyresolveLocations (yys, 1, yystackp]b4_user_args[);]])[ + return yyreportAmbiguity (yybest, yyp]b4_pure_args[); + break; + case 1: + yymerge = yytrue; + break; + case 2: + break; + case 3: + yybest = yyp; + yymerge = yyfalse; + break; + default: + /* This cannot happen so it is not worth a YYASSERT (yyfalse), + but some compilers complain if the default case is + omitted. */ + break; + } + yypp = &yyp->yynext; + } + } + + if (yymerge) + { + yySemanticOption* yyp; + int yyprec = yydprec[yybest->yyrule]; + yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[); + if (yyflag == yyok) + for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext) + { + if (yyprec == yydprec[yyp->yyrule]) + { + YYSTYPE yysval_other;]b4_locations_if([ + YYLTYPE yydummy;])[ + yyflag = yyresolveAction (yyp, yystackp, &yysval_other]b4_locuser_args([&yydummy])[); + if (yyflag != yyok) + { + yydestruct ("Cleanup: discarding incompletely merged value for", + yystos[yys->yylrState], + &yysval]b4_locuser_args[); + break; + } + yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other); + } + } + } + else + yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args([yylocp])[); + + if (yyflag == yyok) + { + yys->yyresolved = yytrue; + yys->yysemantics.yysval = yysval; + } + else + yys->yysemantics.yyfirstVal = YY_NULLPTR; + return yyflag; +} + +static YYRESULTTAG +yyresolveStack (yyGLRStack* yystackp]b4_user_formals[) +{ + if (yystackp->yysplitPoint != YY_NULLPTR) + { + yyGLRState* yys; + int yyn; + + for (yyn = 0, yys = yystackp->yytops.yystates[0]; + yys != yystackp->yysplitPoint; + yys = yys->yypred, yyn += 1) + continue; + YYCHK (yyresolveStates (yystackp->yytops.yystates[0], yyn, yystackp + ]b4_user_args[)); + } + return yyok; +} + +static void +yycompressStack (yyGLRStack* yystackp) +{ + yyGLRState* yyp, *yyq, *yyr; + + if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR) + return; + + for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR; + yyp != yystackp->yysplitPoint; + yyr = yyp, yyp = yyq, yyq = yyp->yypred) + yyp->yypred = yyr; + + yystackp->yyspaceLeft += (size_t) (yystackp->yynextFree - yystackp->yyitems); + yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1; + yystackp->yyspaceLeft -= (size_t) (yystackp->yynextFree - yystackp->yyitems); + yystackp->yysplitPoint = YY_NULLPTR; + yystackp->yylastDeleted = YY_NULLPTR; + + while (yyr != YY_NULLPTR) + { + yystackp->yynextFree->yystate = *yyr; + yyr = yyr->yypred; + yystackp->yynextFree->yystate.yypred = &yystackp->yynextFree[-1].yystate; + yystackp->yytops.yystates[0] = &yystackp->yynextFree->yystate; + yystackp->yynextFree += 1; + yystackp->yyspaceLeft -= 1; + } +} + +static YYRESULTTAG +yyprocessOneStack (yyGLRStack* yystackp, size_t yyk, + size_t yyposn]b4_pure_formals[) +{ + while (yystackp->yytops.yystates[yyk] != YY_NULLPTR) + { + yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState; + YYDPRINTF ((stderr, "Stack %lu Entering state %d\n", + (unsigned long) yyk, yystate)); + + YYASSERT (yystate != YYFINAL); + + if (yyisDefaultedState (yystate)) + { + YYRESULTTAG yyflag; + yyRuleNum yyrule = yydefaultAction (yystate); + if (yyrule == 0) + { + YYDPRINTF ((stderr, "Stack %lu dies.\n", + (unsigned long) yyk)); + yymarkStackDeleted (yystackp, yyk); + return yyok; + } + yyflag = yyglrReduce (yystackp, yyk, yyrule, yyimmediate[yyrule]]b4_user_args[); + if (yyflag == yyerr) + { + YYDPRINTF ((stderr, + "Stack %lu dies " + "(predicate failure or explicit user error).\n", + (unsigned long) yyk)); + yymarkStackDeleted (yystackp, yyk); + return yyok; + } + if (yyflag != yyok) + return yyflag; + } + else + { + yySymbol yytoken; + int yyaction; + const short* yyconflicts; + + yystackp->yytops.yylookaheadNeeds[yyk] = yytrue; + yytoken = ]b4_yygetToken_call[; + yyaction = yygetLRActions (yystate, yytoken, &yyconflicts); + + while (*yyconflicts != 0) + { + YYRESULTTAG yyflag; + size_t yynewStack = yysplitStack (yystackp, yyk); + YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n", + (unsigned long) yynewStack, + (unsigned long) yyk)); + yyflag = yyglrReduce (yystackp, yynewStack, + *yyconflicts, + yyimmediate[*yyconflicts]]b4_user_args[); + if (yyflag == yyok) + YYCHK (yyprocessOneStack (yystackp, yynewStack, + yyposn]b4_pure_args[)); + else if (yyflag == yyerr) + { + YYDPRINTF ((stderr, "Stack %lu dies.\n", + (unsigned long) yynewStack)); + yymarkStackDeleted (yystackp, yynewStack); + } + else + return yyflag; + yyconflicts += 1; + } + + if (yyisShiftAction (yyaction)) + break; + else if (yyisErrorAction (yyaction)) + { + YYDPRINTF ((stderr, "Stack %lu dies.\n", + (unsigned long) yyk)); + yymarkStackDeleted (yystackp, yyk); + break; + } + else + { + YYRESULTTAG yyflag = yyglrReduce (yystackp, yyk, -yyaction, + yyimmediate[-yyaction]]b4_user_args[); + if (yyflag == yyerr) + { + YYDPRINTF ((stderr, + "Stack %lu dies " + "(predicate failure or explicit user error).\n", + (unsigned long) yyk)); + yymarkStackDeleted (yystackp, yyk); + break; + } + else if (yyflag != yyok) + return yyflag; + } + } + } + return yyok; +} + +static void +yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[) +{ + if (yystackp->yyerrState != 0) + return; +#if ! YYERROR_VERBOSE + yyerror (]b4_lyyerror_args[YY_("syntax error")); +#else + { + yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken)); + size_t yysize = yysize0; + yybool yysize_overflow = yyfalse; + char* yymsg = YY_NULLPTR; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[yystackp->yytops.yystates[0]->yylrState]; + yyarg[yycount++] = yytokenName (yytoken); + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for this + state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytokenName (yyx); + { + size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx)); + if (yysz < yysize) + yysize_overflow = yytrue; + yysize = yysz; + } + } + } + } + + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + { + size_t yysz = yysize + strlen (yyformat); + if (yysz < yysize) + yysize_overflow = yytrue; + yysize = yysz; + } + + if (!yysize_overflow) + yymsg = (char *) YYMALLOC (yysize); + + if (yymsg) + { + char *yyp = yymsg; + int yyi = 0; + while ((*yyp = *yyformat)) + { + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + yyerror (]b4_lyyerror_args[yymsg); + YYFREE (yymsg); + } + else + { + yyerror (]b4_lyyerror_args[YY_("syntax error")); + yyMemoryExhausted (yystackp); + } + } +#endif /* YYERROR_VERBOSE */ + yynerrs += 1; +} + +/* Recover from a syntax error on *YYSTACKP, assuming that *YYSTACKP->YYTOKENP, + yylval, and yylloc are the syntactic category, semantic value, and location + of the lookahead. */ +static void +yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[) +{ + if (yystackp->yyerrState == 3) + /* We just shifted the error token and (perhaps) took some + reductions. Skip tokens until we can proceed. */ + while (yytrue) + { + yySymbol yytoken; + int yyj; + if (yychar == YYEOF) + yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); + if (yychar != YYEMPTY) + {]b4_locations_if([[ + /* We throw away the lookahead, but the error range + of the shifted error token must take it into account. */ + yyGLRState *yys = yystackp->yytops.yystates[0]; + yyGLRStackItem yyerror_range[3]; + yyerror_range[1].yystate.yyloc = yys->yyloc; + yyerror_range[2].yystate.yyloc = yylloc; + YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Error: discarding", + yytoken, &yylval]b4_locuser_args([&yylloc])[); + yychar = YYEMPTY; + } + yytoken = ]b4_yygetToken_call[; + yyj = yypact[yystackp->yytops.yystates[0]->yylrState]; + if (yypact_value_is_default (yyj)) + return; + yyj += yytoken; + if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != yytoken) + { + if (yydefact[yystackp->yytops.yystates[0]->yylrState] != 0) + return; + } + else if (! yytable_value_is_error (yytable[yyj])) + return; + } + + /* Reduce to one stack. */ + { + size_t yyk; + for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1) + if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) + break; + if (yyk >= yystackp->yytops.yysize) + yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); + for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1) + yymarkStackDeleted (yystackp, yyk); + yyremoveDeletes (yystackp); + yycompressStack (yystackp); + } + + /* Now pop stack until we find a state that shifts the error token. */ + yystackp->yyerrState = 3; + while (yystackp->yytops.yystates[0] != YY_NULLPTR) + { + yyGLRState *yys = yystackp->yytops.yystates[0]; + int yyj = yypact[yys->yylrState]; + if (! yypact_value_is_default (yyj)) + { + yyj += YYTERROR; + if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR + && yyisShiftAction (yytable[yyj])) + { + /* Shift the error token. */]b4_locations_if([[ + /* First adjust its location.*/ + YYLTYPE yyerrloc; + yystackp->yyerror_range[2].yystate.yyloc = yylloc; + YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);]])[ + YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]], + &yylval, &yyerrloc); + yyglrShift (yystackp, 0, yytable[yyj], + yys->yyposn, &yylval]b4_locations_if([, &yyerrloc])[); + yys = yystackp->yytops.yystates[0]; + break; + } + }]b4_locations_if([[ + yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[ + if (yys->yypred != YY_NULLPTR) + yydestroyGLRState ("Error: popping", yys]b4_user_args[); + yystackp->yytops.yystates[0] = yys->yypred; + yystackp->yynextFree -= 1; + yystackp->yyspaceLeft += 1; + } + if (yystackp->yytops.yystates[0] == YY_NULLPTR) + yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); +} + +#define YYCHK1(YYE) \ + do { \ + switch (YYE) { \ + case yyok: \ + break; \ + case yyabort: \ + goto yyabortlab; \ + case yyaccept: \ + goto yyacceptlab; \ + case yyerr: \ + goto yyuser_error; \ + default: \ + goto yybuglab; \ + } \ + } while (0) + +/*----------. +| yyparse. | +`----------*/ + +]b4_function_define([yyparse], [int], b4_parse_param)[ +{ + int yyresult; + yyGLRStack yystack; + yyGLRStack* const yystackp = &yystack; + size_t yyposn; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; + yylval = yyval_default;]b4_locations_if([ + yylloc = yyloc_default;])[ +]m4_ifdef([b4_initial_action], [ +b4_dollar_pushdef([yylval], [], [], [yylloc])dnl + b4_user_initial_action +b4_dollar_popdef])[]dnl +[ + if (! yyinitGLRStack (yystackp, YYINITDEPTH)) + goto yyexhaustedlab; + switch (YYSETJMP (yystack.yyexception_buffer)) + { + case 0: break; + case 1: goto yyabortlab; + case 2: goto yyexhaustedlab; + default: goto yybuglab; + } + yyglrShift (&yystack, 0, 0, 0, &yylval]b4_locations_if([, &yylloc])[); + yyposn = 0; + + while (yytrue) + { + /* For efficiency, we have two loops, the first of which is + specialized to deterministic operation (single stack, no + potential ambiguity). */ + /* Standard mode */ + while (yytrue) + { + yyStateNum yystate = yystack.yytops.yystates[0]->yylrState; + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + goto yyacceptlab; + if (yyisDefaultedState (yystate)) + { + yyRuleNum yyrule = yydefaultAction (yystate); + if (yyrule == 0) + {]b4_locations_if([[ + yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[ + yyreportSyntaxError (&yystack]b4_user_args[); + goto yyuser_error; + } + YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue]b4_user_args[)); + } + else + { + yySymbol yytoken = ]b4_yygetToken_call;[ + const short* yyconflicts; + int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts); + if (*yyconflicts != 0) + break; + if (yyisShiftAction (yyaction)) + { + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yychar = YYEMPTY; + yyposn += 1; + yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[); + if (0 < yystack.yyerrState) + yystack.yyerrState -= 1; + } + else if (yyisErrorAction (yyaction)) + {]b4_locations_if([[ + yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[]b4_glr_cc_if([[ + /* Don't issue an error message again for exceptions + thrown from the scanner. */ + if (yychar != YYFAULTYTOK) + ]])[ yyreportSyntaxError (&yystack]b4_user_args[); + goto yyuser_error; + } + else + YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue]b4_user_args[)); + } + } + + while (yytrue) + { + yySymbol yytoken_to_shift; + size_t yys; + + for (yys = 0; yys < yystack.yytops.yysize; yys += 1) + yystackp->yytops.yylookaheadNeeds[yys] = (yybool) (yychar != YYEMPTY); + + /* yyprocessOneStack returns one of three things: + + - An error flag. If the caller is yyprocessOneStack, it + immediately returns as well. When the caller is finally + yyparse, it jumps to an error label via YYCHK1. + + - yyok, but yyprocessOneStack has invoked yymarkStackDeleted + (&yystack, yys), which sets the top state of yys to NULL. Thus, + yyparse's following invocation of yyremoveDeletes will remove + the stack. + + - yyok, when ready to shift a token. + + Except in the first case, yyparse will invoke yyremoveDeletes and + then shift the next token onto all remaining stacks. This + synchronization of the shift (that is, after all preceding + reductions on all stacks) helps prevent double destructor calls + on yylval in the event of memory exhaustion. */ + + for (yys = 0; yys < yystack.yytops.yysize; yys += 1) + YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn]b4_lpure_args[)); + yyremoveDeletes (&yystack); + if (yystack.yytops.yysize == 0) + { + yyundeleteLastStack (&yystack); + if (yystack.yytops.yysize == 0) + yyFail (&yystack][]b4_lpure_args[, YY_("syntax error")); + YYCHK1 (yyresolveStack (&yystack]b4_user_args[)); + YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));]b4_locations_if([[ + yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[ + yyreportSyntaxError (&yystack]b4_user_args[); + goto yyuser_error; + } + + /* If any yyglrShift call fails, it will fail after shifting. Thus, + a copy of yylval will already be on stack 0 in the event of a + failure in the following loop. Thus, yychar is set to YYEMPTY + before the loop to make sure the user destructor for yylval isn't + called twice. */ + yytoken_to_shift = YYTRANSLATE (yychar); + yychar = YYEMPTY; + yyposn += 1; + for (yys = 0; yys < yystack.yytops.yysize; yys += 1) + { + yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState; + const short* yyconflicts; + int yyaction = yygetLRActions (yystate, yytoken_to_shift, + &yyconflicts); + /* Note that yyconflicts were handled by yyprocessOneStack. */ + YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long) yys)); + YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc); + yyglrShift (&yystack, yys, yyaction, yyposn, + &yylval]b4_locations_if([, &yylloc])[); + YYDPRINTF ((stderr, "Stack %lu now in state #%d\n", + (unsigned long) yys, + yystack.yytops.yystates[yys]->yylrState)); + } + + if (yystack.yytops.yysize == 1) + { + YYCHK1 (yyresolveStack (&yystack]b4_user_args[)); + YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); + yycompressStack (&yystack); + break; + } + } + continue; + yyuser_error: + yyrecoverSyntaxError (&yystack]b4_user_args[); + yyposn = yystack.yytops.yystates[0]->yyposn; + } + + yyacceptlab: + yyresult = 0; + goto yyreturn; + + yybuglab: + YYASSERT (yyfalse); + goto yyabortlab; + + yyabortlab: + yyresult = 1; + goto yyreturn; + + yyexhaustedlab: + yyerror (]b4_lyyerror_args[YY_("memory exhausted")); + yyresult = 2; + goto yyreturn; + + yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[); + + /* If the stack is well-formed, pop the stack until it is empty, + destroying its entries as we go. But free the stack regardless + of whether it is well-formed. */ + if (yystack.yyitems) + { + yyGLRState** yystates = yystack.yytops.yystates; + if (yystates) + { + size_t yysize = yystack.yytops.yysize; + size_t yyk; + for (yyk = 0; yyk < yysize; yyk += 1) + if (yystates[yyk]) + { + while (yystates[yyk]) + { + yyGLRState *yys = yystates[yyk];]b4_locations_if([[ + yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]])[ + if (yys->yypred != YY_NULLPTR) + yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[); + yystates[yyk] = yys->yypred; + yystack.yynextFree -= 1; + yystack.yyspaceLeft += 1; + } + break; + } + } + yyfreeGLRStack (&yystack); + } + + return yyresult; +} + +/* DEBUGGING ONLY */ +#if ]b4_api_PREFIX[DEBUG +static void +yy_yypstack (yyGLRState* yys) +{ + if (yys->yypred) + { + yy_yypstack (yys->yypred); + YYFPRINTF (stderr, " -> "); + } + YYFPRINTF (stderr, "%d@@%lu", yys->yylrState, + (unsigned long) yys->yyposn); +} + +static void +yypstates (yyGLRState* yyst) +{ + if (yyst == YY_NULLPTR) + YYFPRINTF (stderr, ""); + else + yy_yypstack (yyst); + YYFPRINTF (stderr, "\n"); +} + +static void +yypstack (yyGLRStack* yystackp, size_t yyk) +{ + yypstates (yystackp->yytops.yystates[yyk]); +} + +#define YYINDEX(YYX) \ + ((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems) + + +static void +yypdumpstack (yyGLRStack* yystackp) +{ + yyGLRStackItem* yyp; + size_t yyi; + for (yyp = yystackp->yyitems; yyp < yystackp->yynextFree; yyp += 1) + { + YYFPRINTF (stderr, "%3lu. ", + (unsigned long) (yyp - yystackp->yyitems)); + if (*(yybool *) yyp) + { + YYASSERT (yyp->yystate.yyisState); + YYASSERT (yyp->yyoption.yyisState); + YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld", + yyp->yystate.yyresolved, yyp->yystate.yylrState, + (unsigned long) yyp->yystate.yyposn, + (long) YYINDEX (yyp->yystate.yypred)); + if (! yyp->yystate.yyresolved) + YYFPRINTF (stderr, ", firstVal: %ld", + (long) YYINDEX (yyp->yystate + .yysemantics.yyfirstVal)); + } + else + { + YYASSERT (!yyp->yystate.yyisState); + YYASSERT (!yyp->yyoption.yyisState); + YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld", + yyp->yyoption.yyrule - 1, + (long) YYINDEX (yyp->yyoption.yystate), + (long) YYINDEX (yyp->yyoption.yynext)); + } + YYFPRINTF (stderr, "\n"); + } + YYFPRINTF (stderr, "Tops:"); + for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1) + YYFPRINTF (stderr, "%lu: %ld; ", (unsigned long) yyi, + (long) YYINDEX (yystackp->yytops.yystates[yyi])); + YYFPRINTF (stderr, "\n"); +} +#endif + +#undef yylval +#undef yychar +#undef yynerrs]b4_locations_if([ +#undef yylloc]) + +m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yydebug ]b4_prefix[debug +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])[ + +]b4_epilogue[]dnl +b4_output_end diff --git a/msys2/usr/share/bison/skeletons/glr.cc b/msys2/usr/share/bison/skeletons/glr.cc new file mode 100644 index 0000000..5621734 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/glr.cc @@ -0,0 +1,369 @@ +# C++ GLR skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# This skeleton produces a C++ class that encapsulates a C glr parser. +# This is in order to reduce the maintenance burden. The glr.c +# skeleton is clean and pure enough so that there are no real +# problems. The C++ interface is the same as that of lalr1.cc. In +# fact, glr.c can replace yacc.c without the user noticing any +# difference, and similarly for glr.cc replacing lalr1.cc. +# +# The passing of parse-params +# +# The additional arguments are stored as members of the parser +# object, yyparser. The C routines need to carry yyparser +# throughout the C parser; that's easy: make yyparser an +# additional parse-param. But because the C++ skeleton needs to +# know the "real" original parse-param, we save them +# (b4_parse_param_orig). Note that b4_parse_param is overquoted +# (and c.m4 strips one level of quotes). This is a PITA, and +# explains why there are so many levels of quotes. +# +# The locations +# +# We use location.cc just like lalr1.cc, but because glr.c stores +# the locations in a union, the position and location classes +# must not have a constructor. Therefore, contrary to lalr1.cc, we +# must not define "b4_location_constructors". As a consequence the +# user must initialize the first positions (in particular the +# filename member). + +# We require a pure interface. +m4_define([b4_pure_flag], [1]) + +m4_include(b4_skeletonsdir/[c++.m4]) +b4_bison_locations_if([m4_include(b4_skeletonsdir/[location.cc])]) + +m4_define([b4_parser_class], + [b4_percent_define_get([[api.parser.class]])]) + +# Save the parse parameters. +m4_define([b4_parse_param_orig], m4_defn([b4_parse_param])) + +# b4_parse_param_wrap +# ------------------- +# New ones. +m4_ifset([b4_parse_param], +[m4_define([b4_parse_param_wrap], + [[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]],] +m4_defn([b4_parse_param]))], +[m4_define([b4_parse_param_wrap], + [[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]]) +]) + + +# b4_yy_symbol_print_define +# ------------------------- +# Bypass the default implementation to generate the "yy_symbol_print" +# and "yy_symbol_value_print" functions. +m4_define([b4_yy_symbol_print_define], +[[ +/*--------------------. +| Print this symbol. | +`--------------------*/ + +]b4_function_define([yy_symbol_print], + [static void], + [[FILE *], []], + [[int yytype], [yytype]], + [[const ]b4_namespace_ref::b4_parser_class[::semantic_type *yyvaluep], + [yyvaluep]][]dnl +b4_locations_if([, + [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp], + [yylocationp]]]), + b4_parse_param)[ +{ +]b4_parse_param_use[]dnl +[ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[); +} +]])[ + +# Hijack the initial action to initialize the locations. +]b4_bison_locations_if([m4_define([b4_initial_action], +[yylloc.initialize ();]m4_ifdef([b4_initial_action], [ +m4_defn([b4_initial_action])]))])[ + +# Hijack the post prologue to declare yyerror. +]m4_append([b4_post_prologue], +[b4_syncline([@oline@], [@ofile@])[ +]b4_function_declare([yyerror], + [static void],b4_locations_if([ + [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp], + [yylocationp]],]) + b4_parse_param, + [[const char* msg], [msg]])])[ + + +#undef yynerrs +#undef yychar +#undef yylval]b4_locations_if([ +#undef yylloc]) + +m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yydebug ]b4_prefix[debug]]b4_pure_if([], [[ +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])) + +# Hijack the epilogue to define implementations (yyerror, parser member +# functions etc.). +m4_append([b4_epilogue], +[b4_syncline([@oline@], [@ofile@])[ + +/*------------------. +| Report an error. | +`------------------*/ + +]b4_function_define([yyerror], + [static void],b4_locations_if([ + [[const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp], + [yylocationp]],]) + b4_parse_param, + [[const char* msg], [msg]])[ +{ +]b4_parse_param_use[]dnl +[ yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg); +} + + +]b4_namespace_open[ +]dnl In this section, the parse params are the original parse_params. +m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl +[ /// Build a parser object. + ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ + :])[ +#if ]b4_api_PREFIX[DEBUG + ]m4_ifset([b4_parse_param], [ ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[ +#endif]b4_parse_param_cons[ + {} + + ]b4_parser_class::~b4_parser_class[ () + {} + + ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW + {} + + int + ]b4_parser_class[::operator() () + { + return parse (); + } + + int + ]b4_parser_class[::parse () + { + return ::yyparse (*this]b4_user_args[); + } + +#if ]b4_api_PREFIX[DEBUG + /*--------------------. + | Print this symbol. | + `--------------------*/ + + void + ]b4_parser_class[::yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep]b4_locations_if([[, + const location_type* yylocationp]])[) + {]b4_locations_if([[ + YYUSE (yylocationp);]])[ + YYUSE (yyvaluep); + std::ostream& yyo = debug_stream (); + std::ostream& yyoutput = yyo; + YYUSE (yyoutput); + ]b4_symbol_actions([printer])[ + } + + + void + ]b4_parser_class[::yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep]b4_locations_if([[, + const location_type* yylocationp]])[) + { + *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm") + << ' ' << yytname[yytype] << " ("]b4_locations_if([[ + << *yylocationp << ": "]])[; + yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[); + *yycdebug_ << ')'; + } + + std::ostream& + ]b4_parser_class[::debug_stream () const + { + return *yycdebug_; + } + + void + ]b4_parser_class[::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + ]b4_parser_class[::debug_level_type + ]b4_parser_class[::debug_level () const + { + return yydebug; + } + + void + ]b4_parser_class[::set_debug_level (debug_level_type l) + { + // Actually, it is yydebug which is really used. + yydebug = l; + } + +#endif +]m4_popdef([b4_parse_param])dnl +b4_namespace_close +]) + + +# b4_shared_declarations(hh|cc) +# ----------------------------- +# Declaration that might either go into the header (if --defines, $1 = hh) +# or in the implementation file. +m4_define([b4_shared_declarations], +[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl +b4_percent_code_get([[requires]])[ +#include +#include +#include + +]b4_cxx_portability[ +]m4_ifdef([b4_location_include], + [[# include ]b4_location_include])[ +]b4_variant_if([b4_variant_includes])[ + +]b4_attribute_define[ +]b4_null_define[ + +// Whether we are compiled with exception support. +#ifndef YY_EXCEPTIONS +# if defined __GNUC__ && !defined __EXCEPTIONS +# define YY_EXCEPTIONS 0 +# else +# define YY_EXCEPTIONS 1 +# endif +#endif + +]b4_YYDEBUG_define[ + +]b4_namespace_open[ + +]b4_bison_locations_if([m4_ifndef([b4_location_file], + [b4_location_define])])[ + + /// A Bison parser. + class ]b4_parser_class[ + { + public: +]b4_public_types_declare[ + + /// Build a parser object. + ]b4_parser_class[ (]b4_parse_param_decl[); + virtual ~]b4_parser_class[ (); + + /// Parse. An alias for parse (). + /// \returns 0 iff parsing succeeded. + int operator() (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + +#if ]b4_api_PREFIX[DEBUG + /// The current debugging stream. + std::ostream& debug_stream () const; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); +#endif + + /// Report a syntax error.]b4_locations_if([[ + /// \param loc where the syntax error is found.]])[ + /// \param msg a description of the syntax error. + virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg); + +# if ]b4_api_PREFIX[DEBUG + public: + /// \brief Report a symbol value on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value.]b4_locations_if([[ + /// \param yylocationp Its location.]])[ + virtual void yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep]b4_locations_if([[, + const location_type* yylocationp]])[); + /// \brief Report a symbol on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value.]b4_locations_if([[ + /// \param yylocationp Its location.]])[ + virtual void yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep]b4_locations_if([[, + const location_type* yylocationp]])[); + private: + // Debugging. + std::ostream* yycdebug_; +#endif + +]b4_parse_param_vars[ + }; + +]dnl Redirections for glr.c. +b4_percent_define_flag_if([[global_tokens_and_yystype]], +[b4_token_defines]) +[ +#ifndef ]b4_api_PREFIX[STYPE +# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type +#endif +#ifndef ]b4_api_PREFIX[LTYPE +# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type +#endif + +]b4_namespace_close[ +]b4_percent_code_get([[provides]])[ +]m4_popdef([b4_parse_param])dnl +]) + +b4_defines_if( +[b4_output_begin([b4_spec_defines_file]) +b4_copyright([Skeleton interface for Bison GLR parsers in C++], + [2002-2015, 2018-2019])[ +// C++ GLR parser skeleton written by Akim Demaille. + +]b4_disclaimer[ +]b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_shared_declarations[ +]b4_cpp_guard_close([b4_spec_defines_file])[ +]b4_output_end]) + +# Let glr.c (and b4_shared_declarations) believe that the user +# arguments include the parser itself. +m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_wrap])) +m4_include(b4_skeletonsdir/[glr.c]) +m4_popdef([b4_parse_param]) diff --git a/share/bison/java-skel.m4 b/msys2/usr/share/bison/skeletons/java-skel.m4 similarity index 87% rename from share/bison/java-skel.m4 rename to msys2/usr/share/bison/skeletons/java-skel.m4 index 7c4aa10..922f1a8 100644 --- a/share/bison/java-skel.m4 +++ b/msys2/usr/share/bison/skeletons/java-skel.m4 @@ -1,7 +1,9 @@ -*- Autoconf -*- # Java skeleton dispatching for Bison. -# Copyright (C) 2007 Free Software Foundation, Inc. + +# Copyright (C) 2007, 2009-2015, 2018-2019 Free Software Foundation, +# Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,7 +21,7 @@ b4_glr_if( [b4_complain([%%glr-parser not supported for Java])]) b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for Java])]) -m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.java]]) +m4_define_default([b4_used_skeleton], [b4_skeletonsdir/[lalr1.java]]) m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"]) m4_include(b4_used_skeleton) diff --git a/msys2/usr/share/bison/skeletons/java.m4 b/msys2/usr/share/bison/skeletons/java.m4 new file mode 100644 index 0000000..a62a52e --- /dev/null +++ b/msys2/usr/share/bison/skeletons/java.m4 @@ -0,0 +1,353 @@ + -*- Autoconf -*- + +# Java language support for Bison + +# Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_include(b4_skeletonsdir/[c-like.m4]) + + +# b4_list2(LIST1, LIST2) +# ---------------------- +# Join two lists with a comma if necessary. +m4_define([b4_list2], + [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2]) + + +# b4_percent_define_get3(DEF, PRE, POST, NOT) +# ------------------------------------------- +# Expand to the value of DEF surrounded by PRE and POST if it's %define'ed, +# otherwise NOT. +m4_define([b4_percent_define_get3], + [m4_ifval(m4_quote(b4_percent_define_get([$1])), + [$2[]b4_percent_define_get([$1])[]$3], [$4])]) + + + +# b4_flag_value(BOOLEAN-FLAG) +# --------------------------- +m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])]) + + +# b4_parser_class_declaration +# --------------------------- +# The declaration of the parser class ("class YYParser"), with all its +# qualifiers/annotations. +b4_percent_define_default([[api.parser.abstract]], [[false]]) +b4_percent_define_default([[api.parser.final]], [[false]]) +b4_percent_define_default([[api.parser.public]], [[false]]) +b4_percent_define_default([[api.parser.strictfp]], [[false]]) + +m4_define([b4_parser_class_declaration], +[b4_percent_define_get3([api.parser.annotations], [], [ ])dnl +b4_percent_define_flag_if([api.parser.public], [public ])dnl +b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl +b4_percent_define_flag_if([api.parser.final], [final ])dnl +b4_percent_define_flag_if([api.parser.strictfp], [strictfp ])dnl +[class ]b4_parser_class[]dnl +b4_percent_define_get3([api.parser.extends], [ extends ])dnl +b4_percent_define_get3([api.parser.implements], [ implements ])]) + + +# b4_lexer_if(TRUE, FALSE) +# ------------------------ +m4_define([b4_lexer_if], +[b4_percent_code_ifdef([[lexer]], [$1], [$2])]) + + +# b4_identification +# ----------------- +m4_define([b4_identification], +[ /** Version number for the Bison executable that generated this parser. */ + public static final String bisonVersion = "b4_version"; + + /** Name of the skeleton that generated this parser. */ + public static final String bisonSkeleton = b4_skeleton; +]) + + +## ------------ ## +## Data types. ## +## ------------ ## + +# b4_int_type(MIN, MAX) +# --------------------- +# Return the smallest int type able to handle numbers ranging from +# MIN to MAX (included). +m4_define([b4_int_type], +[m4_if(b4_ints_in($@, [-128], [127]), [1], [byte], + b4_ints_in($@, [-32768], [32767]), [1], [short], + [int])]) + +# b4_int_type_for(NAME) +# --------------------- +# Return the smallest int type able to handle numbers ranging from +# 'NAME_min' to 'NAME_max' (included). +m4_define([b4_int_type_for], +[b4_int_type($1_min, $1_max)]) + +# b4_null +# ------- +m4_define([b4_null], [null]) + + +# b4_typed_parser_table_define(TYPE, NAME, DATA, COMMENT) +# ------------------------------------------------------- +m4_define([b4_typed_parser_table_define], +[m4_ifval([$4], [b4_comment([$4]) + ])dnl +[private static final ]$1[ yy$2_[] = yy$2_init(); + private static final ]$1[[] yy$2_init() + { + return new ]$1[[] + { + ]$3[ + }; + }]]) + + +# b4_integral_parser_table_define(NAME, DATA, COMMENT) +#----------------------------------------------------- +m4_define([b4_integral_parser_table_define], +[b4_typed_parser_table_define([b4_int_type_for([$2])], [$1], [$2], [$3])]) + + +## ------------------------- ## +## Assigning token numbers. ## +## ------------------------- ## + +# b4_token_enum(TOKEN-NUM) +# ------------------------ +# Output the definition of this token as an enum. +m4_define([b4_token_enum], +[b4_token_format([ /** Token number, to be returned by the scanner. */ + static final int %s = %s; +], [$1])]) + +# b4_token_enums +# -------------- +# Output the definition of the tokens (if there are) as enums. +m4_define([b4_token_enums], +[b4_any_token_visible_if([/* Tokens. */ +b4_symbol_foreach([b4_token_enum])])]) + +# b4-case(ID, CODE) +# ----------------- +# We need to fool Java's stupid unreachable code detection. +m4_define([b4_case], [ case $1: + if (yyn == $1) + $2; + break; + ]) + +# b4_predicate_case(LABEL, CONDITIONS) +# ------------------------------------ +m4_define([b4_predicate_case], [ case $1: + if (! ($2)) YYERROR; + break; + ]) + + +## -------- ## +## Checks. ## +## -------- ## + +b4_percent_define_check_kind([[api.value.type]], [code], [deprecated]) + +b4_percent_define_check_kind([[annotations]], [code], [deprecated]) +b4_percent_define_check_kind([[extends]], [code], [deprecated]) +b4_percent_define_check_kind([[implements]], [code], [deprecated]) +b4_percent_define_check_kind([[init_throws]], [code], [deprecated]) +b4_percent_define_check_kind([[lex_throws]], [code], [deprecated]) +b4_percent_define_check_kind([[api.parser.class]], [code], [deprecated]) +b4_percent_define_check_kind([[throws]], [code], [deprecated]) + + + +## ---------------- ## +## Default values. ## +## ---------------- ## + +m4_define([b4_yystype], [b4_percent_define_get([[api.value.type]])]) +b4_percent_define_default([[api.value.type]], [[Object]]) + +# %name-prefix +m4_define_default([b4_prefix], [[YY]]) + +b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser]) +m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])]) + +b4_percent_define_default([[lex_throws]], [[java.io.IOException]]) +m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])]) + +b4_percent_define_default([[throws]], []) +m4_define([b4_throws], [b4_percent_define_get([[throws]])]) + +b4_percent_define_default([[init_throws]], []) +m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])]) + +b4_percent_define_default([[api.location.type]], [Location]) +m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])]) + +b4_percent_define_default([[api.position.type]], [Position]) +m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])]) + + +## ----------------- ## +## Semantic Values. ## +## ----------------- ## + + +# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG]) +# ---------------------------------------------- +# See README. +m4_define([b4_symbol_value], +[m4_ifval([$3], + [(($3)($1))], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [((b4_symbol([$2], [type]))($1))], + [$1])], + [$1])])]) + + +# b4_lhs_value([SYMBOL-NUM], [TYPE]) +# ---------------------------------- +# See README. +m4_define([b4_lhs_value], [yyval]) + + +# b4_rhs_data(RULE-LENGTH, POS) +# ----------------------------- +# See README. +m4_define([b4_rhs_data], +[yystack.valueAt (b4_subtract($@))]) + +# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE]) +# -------------------------------------------------- +# See README. +# +# In this simple implementation, %token and %type have class names +# between the angle brackets. +m4_define([b4_rhs_value], +[b4_symbol_value([b4_rhs_data([$1], [$2])], [$3], [$4])]) + + +# b4_lhs_location() +# ----------------- +# Expansion of @$. +m4_define([b4_lhs_location], +[(yyloc)]) + + +# b4_rhs_location(RULE-LENGTH, POS) +# --------------------------------- +# Expansion of @POS, where the current rule has RULE-LENGTH symbols +# on RHS. +m4_define([b4_rhs_location], +[yystack.locationAt (b4_subtract($@))]) + + +# b4_lex_param +# b4_parse_param +# -------------- +# If defined, b4_lex_param arrives double quoted, but below we prefer +# it to be single quoted. Same for b4_parse_param. + +# TODO: should be in bison.m4 +m4_define_default([b4_lex_param], [[]]) +m4_define([b4_lex_param], b4_lex_param) +m4_define([b4_parse_param], b4_parse_param) + +# b4_lex_param_decl +# ----------------- +# Extra formal arguments of the constructor. +m4_define([b4_lex_param_decl], +[m4_ifset([b4_lex_param], + [b4_remove_comma([$1], + b4_param_decls(b4_lex_param))], + [$1])]) + +m4_define([b4_param_decls], + [m4_map([b4_param_decl], [$@])]) +m4_define([b4_param_decl], [, $1]) + +m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)]) + + + +# b4_parse_param_decl +# ------------------- +# Extra formal arguments of the constructor. +m4_define([b4_parse_param_decl], +[m4_ifset([b4_parse_param], + [b4_remove_comma([$1], + b4_param_decls(b4_parse_param))], + [$1])]) + + + +# b4_lex_param_call +# ----------------- +# Delegating the lexer parameters to the lexer constructor. +m4_define([b4_lex_param_call], + [m4_ifset([b4_lex_param], + [b4_remove_comma([$1], + b4_param_calls(b4_lex_param))], + [$1])]) +m4_define([b4_param_calls], + [m4_map([b4_param_call], [$@])]) +m4_define([b4_param_call], [, $2]) + + + +# b4_parse_param_cons +# ------------------- +# Extra initialisations of the constructor. +m4_define([b4_parse_param_cons], + [m4_ifset([b4_parse_param], + [b4_constructor_calls(b4_parse_param)])]) + +m4_define([b4_constructor_calls], + [m4_map([b4_constructor_call], [$@])]) +m4_define([b4_constructor_call], + [this.$2 = $2; + ]) + + + +# b4_parse_param_vars +# ------------------- +# Extra instance variables. +m4_define([b4_parse_param_vars], + [m4_ifset([b4_parse_param], + [ + /* User arguments. */ +b4_var_decls(b4_parse_param)])]) + +m4_define([b4_var_decls], + [m4_map_sep([b4_var_decl], [ +], [$@])]) +m4_define([b4_var_decl], + [ protected final $1;]) + + + +# b4_maybe_throws(THROWS) +# ----------------------- +# Expand to either an empty string or "throws THROWS". +m4_define([b4_maybe_throws], + [m4_ifval($1, [throws $1])]) diff --git a/msys2/usr/share/bison/skeletons/lalr1.cc b/msys2/usr/share/bison/skeletons/lalr1.cc new file mode 100644 index 0000000..09f4259 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/lalr1.cc @@ -0,0 +1,1247 @@ +# C++ skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_include(b4_skeletonsdir/[c++.m4]) + +# api.value.type=variant is valid. +m4_define([b4_value_type_setup_variant]) + + +# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT) +# -------------------------------------------------------------- +# Declare "parser::yy_" whose contents is CONTENT. +m4_define([b4_integral_parser_table_declare], +[m4_ifval([$3], [b4_comment([$3], [ ]) +])dnl + static const b4_int_type_for([$2]) yy$1_[[]];dnl +]) + +# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT) +# ------------------------------------------------------------- +# Define "parser::yy_" whose contents is CONTENT. +m4_define([b4_integral_parser_table_define], +[ const b4_int_type_for([$2]) + b4_parser_class::yy$1_[[]] = + { + $2 + };dnl +]) + +# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE]) +# ------------------------------------------------- +# Same as b4_symbol_value, but used in a template method. It makes +# a difference when using variants. Note that b4_value_type_setup_union +# overrides b4_symbol_value, so we must override it again. +m4_copy([b4_symbol_value], [b4_symbol_value_template]) +m4_append([b4_value_type_setup_union], +[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])]) + +# b4_lhs_value(SYMBOL-NUM, [TYPE]) +# -------------------------------- +# See README. +m4_define([b4_lhs_value], +[b4_symbol_value([yylhs.value], [$1], [$2])]) + + +# b4_lhs_location() +# ----------------- +# Expansion of @$. +m4_define([b4_lhs_location], +[yylhs.location]) + + +# b4_rhs_data(RULE-LENGTH, POS) +# ----------------------------- +# See README. +m4_define([b4_rhs_data], +[yystack_@{b4_subtract($@)@}]) + + +# b4_rhs_state(RULE-LENGTH, POS) +# ------------------------------ +# The state corresponding to the symbol #POS, where the current +# rule has RULE-LENGTH symbols on RHS. +m4_define([b4_rhs_state], +[b4_rhs_data([$1], [$2]).state]) + + +# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE]) +# -------------------------------------------------- +# See README. +m4_define([_b4_rhs_value], +[b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3], [$4])]) + +m4_define([b4_rhs_value], +[b4_percent_define_ifdef([api.value.automove], + [YY_MOVE (_b4_rhs_value($@))], + [_b4_rhs_value($@)])]) + + +# b4_rhs_location(RULE-LENGTH, POS) +# --------------------------------- +# Expansion of @POS, where the current rule has RULE-LENGTH symbols +# on RHS. +m4_define([b4_rhs_location], +[b4_rhs_data([$1], [$2]).location]) + + +# b4_symbol_action(SYMBOL-NUM, KIND) +# ---------------------------------- +# Run the action KIND (destructor or printer) for SYMBOL-NUM. +# Same as in C, but using references instead of pointers. +m4_define([b4_symbol_action], +[b4_symbol_if([$1], [has_$2], +[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl +b4_dollar_pushdef([yysym.value], + [$1], + [], + [yysym.location])dnl + _b4_symbol_case([$1])[]dnl +b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])]) + b4_symbol([$1], [$2]) +b4_syncline([@oline@], [@ofile@]) + break; + +m4_popdef([b4_symbol_value])[]dnl +b4_dollar_popdef[]dnl +])]) + + +# b4_lex +# ------ +# Call yylex. +m4_define([b4_lex], +[b4_token_ctor_if( +[b4_function_call([yylex], + [symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))], +[b4_function_call([yylex], [int], + [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl +b4_locations_if([, [[location*], [&yyla.location]]])dnl +m4_ifdef([b4_lex_param], [, ]b4_lex_param))])]) + + +m4_pushdef([b4_copyright_years], + [2002-2015, 2018-2019]) + +m4_define([b4_parser_class], + [b4_percent_define_get([[api.parser.class]])]) + +b4_bison_locations_if([# Backward compatibility. + m4_define([b4_location_constructors]) + m4_include(b4_skeletonsdir/[location.cc])]) +m4_include(b4_skeletonsdir/[stack.hh]) +b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])]) + + +# b4_shared_declarations(hh|cc) +# ----------------------------- +# Declaration that might either go into the header (if --defines, $1 = hh) +# or in the implementation file. +m4_define([b4_shared_declarations], +[b4_percent_code_get([[requires]])[ +]b4_parse_assert_if([# include ])[ +# include // std::abort +# include +# include +# include +# include + +]b4_cxx_portability[ +]m4_ifdef([b4_location_include], + [[# include ]b4_location_include])[ +]b4_variant_if([b4_variant_includes])[ + +]b4_attribute_define[ +]b4_null_define[ + +]b4_YYDEBUG_define[ + +]b4_namespace_open[ + +]b4_bison_locations_if([m4_ifndef([b4_location_file], + [b4_location_define])])[ + + /// A Bison parser. + class ]b4_parser_class[ + { + public: +]b4_public_types_declare[ +]b4_symbol_type_define[ + /// Build a parser object. + ]b4_parser_class[ (]b4_parse_param_decl[); + virtual ~]b4_parser_class[ (); + + /// Parse. An alias for parse (). + /// \returns 0 iff parsing succeeded. + int operator() (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + +#if ]b4_api_PREFIX[DEBUG + /// The current debugging stream. + std::ostream& debug_stream () const YY_ATTRIBUTE_PURE; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const YY_ATTRIBUTE_PURE; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); +#endif + + /// Report a syntax error.]b4_locations_if([[ + /// \param loc where the syntax error is found.]])[ + /// \param msg a description of the syntax error. + virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg); + + /// Report a syntax error. + void error (const syntax_error& err); + +]b4_token_constructor_define[ + + private: + /// This class is not copyable. + ]b4_parser_class[ (const ]b4_parser_class[&); + ]b4_parser_class[& operator= (const ]b4_parser_class[&); + + /// State numbers. + typedef int state_type; + + /// Generate an error message. + /// \param yystate the state where the error occurred. + /// \param yyla the lookahead token. + virtual std::string yysyntax_error_ (state_type yystate, + const symbol_type& yyla) const; + + /// Compute post-reduction state. + /// \param yystate the current state + /// \param yysym the nonterminal to push on the stack + state_type yy_lr_goto_state_ (state_type yystate, int yysym); + + /// Whether the given \c yypact_ value indicates a defaulted state. + /// \param yyvalue the value to check + static bool yy_pact_value_is_default_ (int yyvalue); + + /// Whether the given \c yytable_ value indicates a syntax error. + /// \param yyvalue the value to check + static bool yy_table_value_is_error_ (int yyvalue); + + static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_; + static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_; + + /// Convert a scanner token number \a t to a symbol number. + static token_number_type yytranslate_ (]b4_token_ctor_if([token_type], [int])[ t); + + // Tables. +]b4_parser_tables_declare[]b4_error_verbose_if([ + + /// Convert the symbol name \a n to a form suitable for a diagnostic. + static std::string yytnamerr_ (const char *n);])[ + +]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[ + /// For a symbol, its name in clear. + static const char* const yytname_[]; +]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[ +]b4_integral_parser_table_declare([rline], [b4_rline], + [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ + /// Report on the debug stream that the rule \a r is going to be reduced. + virtual void yy_reduce_print_ (int r); + /// Print the state stack on the debug stream. + virtual void yystack_print_ (); + + /// Debugging level. + int yydebug_; + /// Debug stream. + std::ostream* yycdebug_; + + /// \brief Display a symbol type, value and location. + /// \param yyo The output stream. + /// \param yysym The symbol. + template + void yy_print_ (std::ostream& yyo, const basic_symbol& yysym) const; +#endif + + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// If null, print nothing. + /// \param yysym The symbol. + template + void yy_destroy_ (const char* yymsg, basic_symbol& yysym) const; + + private: + /// Type access provider for state based symbols. + struct by_state + { + /// Default constructor. + by_state () YY_NOEXCEPT; + + /// The symbol type as needed by the constructor. + typedef state_type kind_type; + + /// Constructor. + by_state (kind_type s) YY_NOEXCEPT; + + /// Copy constructor. + by_state (const by_state& that) YY_NOEXCEPT; + + /// Record that this symbol is empty. + void clear () YY_NOEXCEPT; + + /// Steal the symbol type from \a that. + void move (by_state& that); + + /// The (internal) type number (corresponding to \a state). + /// \a empty_symbol when empty. + symbol_number_type type_get () const YY_NOEXCEPT; + + /// The state number used to denote an empty symbol. + enum { empty_state = -1 }; + + /// The state. + /// \a empty when empty. + state_type state; + }; + + /// "Internal" symbol: element of the stack. + struct stack_symbol_type : basic_symbol + { + /// Superclass. + typedef basic_symbol super_type; + /// Construct an empty symbol. + stack_symbol_type (); + /// Move or copy construction. + stack_symbol_type (YY_RVREF (stack_symbol_type) that); + /// Steal the contents from \a sym to build this. + stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) sym); +#if YY_CPLUSPLUS < 201103L + /// Assignment, needed by push_back by some old implementations. + /// Moves the contents of that. + stack_symbol_type& operator= (stack_symbol_type& that); +#endif + }; + +]b4_stack_define[ + + /// Stack type. + typedef stack stack_type; + + /// The stack. + stack_type yystack_; + + /// Push a new state on the stack. + /// \param m a debug message to display + /// if null, no trace is output. + /// \param sym the symbol + /// \warning the contents of \a s.value is stolen. + void yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym); + + /// Push a new look ahead token on the state on the stack. + /// \param m a debug message to display + /// if null, no trace is output. + /// \param s the state + /// \param sym the symbol (for its value and location). + /// \warning the contents of \a sym.value is stolen. + void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym); + + /// Pop \a n symbols from the stack. + void yypop_ (int n = 1); + + /// Constants. + enum + { + yyeof_ = 0, + yylast_ = ]b4_last[, ///< Last index in yytable_. + yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols. + yyfinal_ = ]b4_final_state_number[, ///< Termination state number. + yyterror_ = 1, + yyerrcode_ = 256, + yyntokens_ = ]b4_tokens_number[ ///< Number of tokens. + }; + +]b4_parse_param_vars[ + }; + +]b4_token_ctor_if([b4_yytranslate_define([$1])[ +]b4_public_types_define([$1])])[ +]b4_namespace_close[ + +]b4_percent_define_flag_if([[global_tokens_and_yystype]], +[b4_token_defines + +#ifndef ]b4_api_PREFIX[STYPE + // Redirection for backward compatibility. +# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type +#endif +])[ +]b4_percent_code_get([[provides]])[ +]]) + +## -------------- ## +## Output files. ## +## -------------- ## + +b4_defines_if( +[b4_output_begin([b4_spec_defines_file]) +b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++]) +[ +/** + ** \file ]b4_spec_defines_file[ + ** Define the ]b4_namespace_ref[::parser class. + */ + +// C++ LALR(1) parser skeleton written by Akim Demaille. + +]b4_disclaimer[ +]b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_shared_declarations(hh)[ +]b4_cpp_guard_close([b4_spec_defines_file]) +b4_output_end +]) + + +b4_output_begin([b4_parser_file_name])[ +]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])[ +]b4_disclaimer[ +]b4_percent_code_get([[top]])[]dnl +m4_if(b4_prefix, [yy], [], +[ +// Take the name prefix into account. +[#]define yylex b4_prefix[]lex])[ + +]b4_user_pre_prologue[ + +]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]], + [b4_shared_declarations([cc])])[ + +]b4_user_post_prologue[ +]b4_percent_code_get[ + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include // FIXME: INFRINGES ON USER NAME SPACE. +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +// Whether we are compiled with exception support. +#ifndef YY_EXCEPTIONS +# if defined __GNUC__ && !defined __EXCEPTIONS +# define YY_EXCEPTIONS 0 +# else +# define YY_EXCEPTIONS 1 +# endif +#endif + +]b4_locations_if([dnl +[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location) +]b4_yylloc_default_define])[ + +// Suppress unused-variable warnings by "using" E. +#define YYUSE(E) ((void) (E)) + +// Enable debugging if requested. +#if ]b4_api_PREFIX[DEBUG + +// A pseudo ostream that takes yydebug_ into account. +# define YYCDEBUG if (yydebug_) (*yycdebug_) + +# define YY_SYMBOL_PRINT(Title, Symbol) \ + do { \ + if (yydebug_) \ + { \ + *yycdebug_ << Title << ' '; \ + yy_print_ (*yycdebug_, Symbol); \ + *yycdebug_ << '\n'; \ + } \ + } while (false) + +# define YY_REDUCE_PRINT(Rule) \ + do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ + } while (false) + +# define YY_STACK_PRINT() \ + do { \ + if (yydebug_) \ + yystack_print_ (); \ + } while (false) + +#else // !]b4_api_PREFIX[DEBUG + +# define YYCDEBUG if (false) std::cerr +# define YY_SYMBOL_PRINT(Title, Symbol) YYUSE (Symbol) +# define YY_REDUCE_PRINT(Rule) static_cast (0) +# define YY_STACK_PRINT() static_cast (0) + +#endif // !]b4_api_PREFIX[DEBUG + +#define yyerrok (yyerrstatus_ = 0) +#define yyclearin (yyla.clear ()) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYRECOVERING() (!!yyerrstatus_) + +]b4_namespace_open[]b4_error_verbose_if([[ + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + ]b4_parser_class[::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + + return yystr; + } +]])[ + + /// Build a parser object. + ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ + :])[ +#if ]b4_api_PREFIX[DEBUG + ]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false), + yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[ +#endif]b4_parse_param_cons[ + {} + + ]b4_parser_class::~b4_parser_class[ () + {} + + ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW + {} + + /*---------------. + | Symbol types. | + `---------------*/ + +]b4_token_ctor_if([], [b4_public_types_define([cc])])[ + + // by_state. + ]b4_parser_class[::by_state::by_state () YY_NOEXCEPT + : state (empty_state) + {} + + ]b4_parser_class[::by_state::by_state (const by_state& that) YY_NOEXCEPT + : state (that.state) + {} + + void + ]b4_parser_class[::by_state::clear () YY_NOEXCEPT + { + state = empty_state; + } + + void + ]b4_parser_class[::by_state::move (by_state& that) + { + state = that.state; + that.clear (); + } + + ]b4_parser_class[::by_state::by_state (state_type s) YY_NOEXCEPT + : state (s) + {} + + ]b4_parser_class[::symbol_number_type + ]b4_parser_class[::by_state::type_get () const YY_NOEXCEPT + { + if (state == empty_state) + return empty_symbol; + else + return yystos_[state]; + } + + ]b4_parser_class[::stack_symbol_type::stack_symbol_type () + {} + + ]b4_parser_class[::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that) + : super_type (YY_MOVE (that.state)]b4_variant_if([], [, YY_MOVE (that.value)])b4_locations_if([, YY_MOVE (that.location)])[) + {]b4_variant_if([ + b4_symbol_variant([that.type_get ()], + [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[ +#if 201103L <= YY_CPLUSPLUS + // that is emptied. + that.state = empty_state; +#endif + } + + ]b4_parser_class[::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that) + : super_type (s]b4_variant_if([], [, YY_MOVE (that.value)])[]b4_locations_if([, YY_MOVE (that.location)])[) + {]b4_variant_if([ + b4_symbol_variant([that.type_get ()], + [value], [move], [YY_MOVE (that.value)])])[ + // that is emptied. + that.type = empty_symbol; + } + +#if YY_CPLUSPLUS < 201103L + ]b4_parser_class[::stack_symbol_type& + ]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that) + { + state = that.state; + ]b4_variant_if([b4_symbol_variant([that.type_get ()], + [value], [move], [that.value])], + [[value = that.value;]])[]b4_locations_if([ + location = that.location;])[ + // that is emptied. + that.state = empty_state; + return *this; + } +#endif + + template + void + ]b4_parser_class[::yy_destroy_ (const char* yymsg, basic_symbol& yysym) const + { + if (yymsg) + YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [ + + // User destructor. + b4_symbol_actions([destructor], [yysym.type_get ()])])[ + } + +#if ]b4_api_PREFIX[DEBUG + template + void + ]b4_parser_class[::yy_print_ (std::ostream& yyo, + const basic_symbol& yysym) const + { + std::ostream& yyoutput = yyo; + YYUSE (yyoutput); + symbol_number_type yytype = yysym.type_get (); +#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408 + // Avoid a (spurious) G++ 4.8 warning about "array subscript is + // below array bounds". + if (yysym.empty ()) + std::abort (); +#endif + yyo << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " ("]b4_locations_if([ + << yysym.location << ": "])[; + ]b4_symbol_actions([printer])[ + yyo << ')'; + } +#endif + + void + ]b4_parser_class[::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym) + { + if (m) + YY_SYMBOL_PRINT (m, sym); + yystack_.push (YY_MOVE (sym)); + } + + void + ]b4_parser_class[::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym) + { +#if 201103L <= YY_CPLUSPLUS + yypush_ (m, stack_symbol_type (s, std::move (sym))); +#else + stack_symbol_type ss (s, sym); + yypush_ (m, ss); +#endif + } + + void + ]b4_parser_class[::yypop_ (int n) + { + yystack_.pop (n); + } + +#if ]b4_api_PREFIX[DEBUG + std::ostream& + ]b4_parser_class[::debug_stream () const + { + return *yycdebug_; + } + + void + ]b4_parser_class[::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + ]b4_parser_class[::debug_level_type + ]b4_parser_class[::debug_level () const + { + return yydebug_; + } + + void + ]b4_parser_class[::set_debug_level (debug_level_type l) + { + yydebug_ = l; + } +#endif // ]b4_api_PREFIX[DEBUG + + ]b4_parser_class[::state_type + ]b4_parser_class[::yy_lr_goto_state_ (state_type yystate, int yysym) + { + int yyr = yypgoto_[yysym - yyntokens_] + yystate; + if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate) + return yytable_[yyr]; + else + return yydefgoto_[yysym - yyntokens_]; + } + + bool + ]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue) + { + return yyvalue == yypact_ninf_; + } + + bool + ]b4_parser_class[::yy_table_value_is_error_ (int yyvalue) + { + return yyvalue == yytable_ninf_; + } + + int + ]b4_parser_class[::operator() () + { + return parse (); + } + + int + ]b4_parser_class[::parse () + { + // State. + int yyn; + /// Length of the RHS of the rule being reduced. + int yylen = 0; + + // Error handling. + int yynerrs_ = 0; + int yyerrstatus_ = 0; + + /// The lookahead symbol. + symbol_type yyla;]b4_locations_if([[ + + /// The locations where the error started and ended. + stack_symbol_type yyerror_range[3];]])[ + + /// The return value of parse (). + int yyresult; + +#if YY_EXCEPTIONS + try +#endif // YY_EXCEPTIONS + { + YYCDEBUG << "Starting parse\n"; + +]m4_ifdef([b4_initial_action], [ +b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl + b4_user_initial_action +b4_dollar_popdef])[]dnl + + [ /* Initialize the stack. The initial state will be set in + yynewstate, since the latter expects the semantical and the + location values to have been already stored, initialize these + stacks with a primary value. */ + yystack_.clear (); + yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla)); + + /*-----------------------------------------------. + | yynewstate -- push a new symbol on the stack. | + `-----------------------------------------------*/ + yynewstate: + YYCDEBUG << "Entering state " << yystack_[0].state << '\n'; + + // Accept? + if (yystack_[0].state == yyfinal_) + YYACCEPT; + + goto yybackup; + + + /*-----------. + | yybackup. | + `-----------*/ + yybackup: + // Try to take a decision without lookahead. + yyn = yypact_[yystack_[0].state]; + if (yy_pact_value_is_default_ (yyn)) + goto yydefault; + + // Read a lookahead token. + if (yyla.empty ()) + { + YYCDEBUG << "Reading a token: "; +#if YY_EXCEPTIONS + try +#endif // YY_EXCEPTIONS + {]b4_token_ctor_if([[ + symbol_type yylookahead (]b4_lex[); + yyla.move (yylookahead);]], [[ + yyla.type = yytranslate_ (]b4_lex[);]])[ + } +#if YY_EXCEPTIONS + catch (const syntax_error& yyexc) + { + YYCDEBUG << "Caught exception: " << yyexc.what() << '\n'; + error (yyexc); + goto yyerrlab1; + } +#endif // YY_EXCEPTIONS + } + YY_SYMBOL_PRINT ("Next token is", yyla); + + /* If the proper action on seeing token YYLA.TYPE is to reduce or + to detect an error, take that action. */ + yyn += yyla.type_get (); + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ()) + goto yydefault; + + // Reduce or error. + yyn = yytable_[yyn]; + if (yyn <= 0) + { + if (yy_table_value_is_error_ (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + // Count tokens shifted since error; after three, turn off error status. + if (yyerrstatus_) + --yyerrstatus_; + + // Shift the lookahead token. + yypush_ ("Shifting", yyn, YY_MOVE (yyla)); + goto yynewstate; + + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + yydefault: + yyn = yydefact_[yystack_[0].state]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + + /*-----------------------------. + | yyreduce -- do a reduction. | + `-----------------------------*/ + yyreduce: + yylen = yyr2_[yyn]; + { + stack_symbol_type yylhs; + yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([ + /* Variants are always initialized to an empty instance of the + correct type. The default '$$ = $1' action is NOT applied + when using variants. */ + b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [ + /* If YYLEN is nonzero, implement the default value of the + action: '$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYLHS.VALUE to garbage. + This behavior is undocumented and Bison users should not rely + upon it. */ + if (yylen) + yylhs.value = yystack_@{yylen - 1@}.value; + else + yylhs.value = yystack_@{0@}.value;])[ +]b4_locations_if([dnl +[ + // Default location. + { + stack_type::slice range (yystack_, yylen); + YYLLOC_DEFAULT (yylhs.location, range, yylen); + yyerror_range[1].location = yylhs.location; + }]])[ + + // Perform the reduction. + YY_REDUCE_PRINT (yyn); +#if YY_EXCEPTIONS + try +#endif // YY_EXCEPTIONS + { + switch (yyn) + { +]b4_user_actions[ + default: + break; + } + } +#if YY_EXCEPTIONS + catch (const syntax_error& yyexc) + { + YYCDEBUG << "Caught exception: " << yyexc.what() << '\n'; + error (yyexc); + YYERROR; + } +#endif // YY_EXCEPTIONS + YY_SYMBOL_PRINT ("-> $$ =", yylhs); + yypop_ (yylen); + yylen = 0; + YY_STACK_PRINT (); + + // Shift the result of the reduction. + yypush_ (YY_NULLPTR, YY_MOVE (yylhs)); + } + goto yynewstate; + + + /*--------------------------------------. + | yyerrlab -- here on detecting error. | + `--------------------------------------*/ + yyerrlab: + // If not already recovering from an error, report this error. + if (!yyerrstatus_) + { + ++yynerrs_; + error (]b4_join(b4_locations_if([yyla.location]), + [[yysyntax_error_ (yystack_[0].state, yyla)]])[); + } + +]b4_locations_if([[ + yyerror_range[1].location = yyla.location;]])[ + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + // Return failure if at end of input. + if (yyla.type_get () == yyeof_) + YYABORT; + else if (!yyla.empty ()) + { + yy_destroy_ ("Error: discarding", yyla); + yyla.clear (); + } + } + + // Else will try to reuse lookahead token after shifting the error token. + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ + yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and + the label yyerrorlab therefore never appears in user code. */ + if (false) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + yypop_ (yylen); + yylen = 0; + goto yyerrlab1; + + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: + yyerrstatus_ = 3; // Each real token shifted decrements this. + { + stack_symbol_type error_token; + for (;;) + { + yyn = yypact_[yystack_[0].state]; + if (!yy_pact_value_is_default_ (yyn)) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + // Pop the current state because it cannot handle the error token. + if (yystack_.size () == 1) + YYABORT; +]b4_locations_if([[ + yyerror_range[1].location = yystack_[0].location;]])[ + yy_destroy_ ("Error: popping", yystack_[0]); + yypop_ (); + YY_STACK_PRINT (); + } +]b4_locations_if([[ + yyerror_range[2].location = yyla.location; + YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[ + + // Shift the error token. + error_token.state = yyn; + yypush_ ("Shifting", YY_MOVE (error_token)); + } + goto yynewstate; + + + /*-------------------------------------. + | yyacceptlab -- YYACCEPT comes here. | + `-------------------------------------*/ + yyacceptlab: + yyresult = 0; + goto yyreturn; + + + /*-----------------------------------. + | yyabortlab -- YYABORT comes here. | + `-----------------------------------*/ + yyabortlab: + yyresult = 1; + goto yyreturn; + + + /*-----------------------------------------------------. + | yyreturn -- parsing is finished, return the result. | + `-----------------------------------------------------*/ + yyreturn: + if (!yyla.empty ()) + yy_destroy_ ("Cleanup: discarding lookahead", yyla); + + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + yypop_ (yylen); + while (1 < yystack_.size ()) + { + yy_destroy_ ("Cleanup: popping", yystack_[0]); + yypop_ (); + } + + return yyresult; + } +#if YY_EXCEPTIONS + catch (...) + { + YYCDEBUG << "Exception caught: cleaning lookahead and stack\n"; + // Do not try to display the values of the reclaimed symbols, + // as their printers might throw an exception. + if (!yyla.empty ()) + yy_destroy_ (YY_NULLPTR, yyla); + + while (1 < yystack_.size ()) + { + yy_destroy_ (YY_NULLPTR, yystack_[0]); + yypop_ (); + } + throw; + } +#endif // YY_EXCEPTIONS + } + + void + ]b4_parser_class[::error (const syntax_error& yyexc) + { + error (]b4_join(b4_locations_if([yyexc.location]), + [[yyexc.what ()]])[); + } + + // Generate an error message. + std::string + ]b4_parser_class[::yysyntax_error_ (]dnl +b4_error_verbose_if([state_type yystate, const symbol_type& yyla], + [state_type, const symbol_type&])[) const + {]b4_error_verbose_if([[ + // Number of reported tokens (one for the "unexpected", one per + // "expected"). + size_t yycount = 0; + // Its maximum. + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + // Arguments of yyformat. + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yyla) is + if this state is a consistent state with a default action. + Thus, detecting the absence of a lookahead is sufficient to + determine that there is no unexpected or expected token to + report. In that case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is + a consistent state with a default action. There might have + been a previous inconsistent state, consistent state with a + non-default action, or user semantic action that manipulated + yyla. (However, yyla is currently not documented for users.) + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state + merging (from LALR or IELR) and default reductions corrupt the + expected token list. However, the list is correct for + canonical LR with one exception: it will still contain any + token that will not be accepted due to an error action in a + later state. + */ + if (!yyla.empty ()) + { + int yytoken = yyla.type_get (); + yyarg[yycount++] = yytname_[yytoken]; + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + // Stay within bounds of both yycheck and yytname. + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + for (int yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_ + && !yy_table_value_is_error_ (yytable_[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + break; + } + else + yyarg[yycount++] = yytname_[yyx]; + } + } + } + + char const* yyformat = YY_NULLPTR; + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: // Avoid compiler warnings. + YYCASE_ (0, YY_("syntax error")); + YYCASE_ (1, YY_("syntax error, unexpected %s")); + YYCASE_ (2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_ (3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_ (4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_ (5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + std::string yyres; + // Argument number. + size_t yyi = 0; + for (char const* yyp = yyformat; *yyp; ++yyp) + if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) + { + yyres += yytnamerr_ (yyarg[yyi++]); + ++yyp; + } + else + yyres += *yyp; + return yyres;]], [[ + return YY_("syntax error");]])[ + } + + + const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class::yypact_ninf_ = b4_pact_ninf[; + + const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class::yytable_ninf_ = b4_table_ninf[; + +]b4_parser_tables_define[ + +]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[ + // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + // First, the terminals, then, starting at \a yyntokens_, nonterminals. + const char* + const ]b4_parser_class[::yytname_[] = + { + ]b4_tname[ + }; + +]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[ +]b4_integral_parser_table_define([rline], [b4_rline])[ + + // Print the state stack on the debug stream. + void + ]b4_parser_class[::yystack_print_ () + { + *yycdebug_ << "Stack now"; + for (stack_type::const_iterator + i = yystack_.begin (), + i_end = yystack_.end (); + i != i_end; ++i) + *yycdebug_ << ' ' << i->state; + *yycdebug_ << '\n'; + } + + // Report on the debug stream that the rule \a yyrule is going to be reduced. + void + ]b4_parser_class[::yy_reduce_print_ (int yyrule) + { + unsigned yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + // Print the symbols being reduced, and their result. + *yycdebug_ << "Reducing stack by rule " << yyrule - 1 + << " (line " << yylno << "):\n"; + // The symbols being reduced. + for (int yyi = 0; yyi < yynrhs; yyi++) + YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", + ]b4_rhs_data(yynrhs, yyi + 1)[); + } +#endif // ]b4_api_PREFIX[DEBUG + +]b4_token_ctor_if([], [b4_yytranslate_define([cc])])[ +]b4_namespace_close[ +]b4_epilogue[]dnl +b4_output_end + + +m4_popdef([b4_copyright_years])dnl diff --git a/msys2/usr/share/bison/skeletons/lalr1.d b/msys2/usr/share/bison/skeletons/lalr1.d new file mode 100644 index 0000000..770e537 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/lalr1.d @@ -0,0 +1,897 @@ +# Java skeleton for Bison -*- autoconf -*- + +# Copyright (C) 2007-2011, 2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_include(b4_skeletonsdir/[d.m4]) + + +m4_divert_push(0)dnl +@output(b4_parser_file_name@)@ +b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D], + [2007-2012, 2019]) + +b4_percent_define_ifdef([package], [module b4_percent_define_get([package]); +])[ +version(D_Version2) { +} else { + static assert(false, "need compiler for D Version 2"); +} + +]b4_user_pre_prologue[ +]b4_user_post_prologue[ +]b4_percent_code_get([[imports]])[ +import std.format; + +/** + * A Bison parser, automatically generated from ]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[. + * + * @@author LALR (1) parser skeleton written by Paolo Bonzini. + * Port to D language was done by Oliver Mangold. + */ + +/** + * Communication interface between the scanner and the Bison-generated + * parser ]b4_parser_class[. + */ +public interface Lexer +{ + ]b4_locations_if([[/** + * Method to retrieve the beginning position of the last scanned token. + * @@return the position at which the last scanned token starts. */ + @@property ]b4_position_type[ startPos (); + + /** + * Method to retrieve the ending position of the last scanned token. + * @@return the first position beyond the last scanned token. */ + @@property ]b4_position_type[ endPos ();]])[ + + /** + * Method to retrieve the semantic value of the last scanned token. + * @@return the semantic value of the last scanned token. */ + @@property ]b4_yystype[ semanticVal (); + + /** + * Entry point for the scanner. Returns the token identifier corresponding + * to the next token and prepares to return the semantic value + * ]b4_locations_if([and beginning/ending positions ])[of the token. + * @@return the token identifier corresponding to the next token. */ + YYTokenType yylex (); + + /** + * Entry point for error reporting. Emits an error + * ]b4_locations_if([referring to the given location ])[in a user-defined way. + * + * ]b4_locations_if([[@@param loc The location of the element to which the + * error message is related]])[ + * @@param s The string for the error message. */ + void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[string s); +} + +private final struct YYStackElement{ + int state; + ]b4_yystype[ value; + ]b4_locations_if(b4_location_type[[] location;])[ +} + +private final struct YYStack { + private YYStackElement[] stack = []; + + public final @@property ulong height() + { + return stack.length; + } + + public final void push (int state, ]b4_yystype[ value]dnl +b4_locations_if([, ref ]b4_location_type[ loc])[) + { + stack ~= YYStackElement(state, value]b4_locations_if([, loc])[); + } + + public final void pop () + { + pop (1); + } + + public final void pop (int num) + { + stack.length -= num; + } + + public final int stateAt (int i) + { + return stack[$-i-1].state; + } + + ]b4_locations_if([[public final ref ]b4_location_type[ locationAt (int i) + { + return stack[$-i-1].location; + } + + ]])[public final ref ]b4_yystype[ valueAt (int i) + { + return stack[$-i-1].value; + } + + // Print the state stack on the debug stream. + public final void print (File stream) + { + stream.write ("Stack now"); + for (int i = 0; i < stack.length; i++) + stream.write (" %d", stack[i].state); + stream.writeln (); + } +} +]b4_locations_if(b4_position_type_if([[[ +static assert(__traits(compiles, + (new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]), + "struct/class ]b4_position_type[ must be default-constructible " + "and assignable"); +static assert(__traits(compiles, (new string[1])[0]=(new ]b4_position_type[).toString()), + "error: struct/class ]b4_position_type[ must have toString method"); +]]], [[ + /** + * A struct denoting a point in the input.*/ +public struct ]b4_position_type[ { + + /** The column index within the line of input. */ + public int column = 1; + /** The line number within an input file. */ + public int line = 1; + /** The name of the input file. */ + public string filename = "(unspecified file)"; + + /** + * Return a string representation of the position. */ + public string toString() const { + return format("%s:%d.%d", filename, line, column); + } +} +]])b4_location_type_if([[[ +static assert(__traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0]))) && + __traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0], (new ]b4_position_type[[1])[0]))), + "error: struct/class ]b4_location_type[ must have " + "default constructor and constructors this(]b4_position_type[) and this(]b4_position_type[, ]b4_position_type[)."); +static assert(__traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].begin) && + __traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].end) && + __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].begin) && + __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].end), + "error: struct/class ]b4_location_type[ must have assignment-compatible " + "members/properties 'begin' and 'end'."); +static assert(__traits(compiles, (new string[1])[0]=(new ]b4_location_type[[1])[0].toString()), + "error: struct/class ]b4_location_type[ must have toString method."); + +private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]]], [[ +/** + * A class defining a pair of positions. Positions, defined by the + * ]b4_position_type[ class, denote a point in the input. + * Locations represent a part of the input through the beginning + * and ending positions. */ +public class ]b4_location_type[ +{ + /** The first, inclusive, position in the range. */ + public ]b4_position_type[ begin; + + /** The first position beyond the range. */ + public ]b4_position_type[ end; + + /** + * Create a ]b4_location_type[ denoting an empty range located at + * a given point. + * @@param loc The position at which the range is anchored. */ + public this (]b4_position_type[ loc) { + this.begin = this.end = loc; + } + + /** + * Create a ]b4_location_type[ from the endpoints of the range. + * @@param begin The first position included in the range. + * @@param end The first position beyond the range. */ + public this (]b4_position_type[ begin, ]b4_position_type[ end) + { + this.begin = begin; + this.end = end; + } + + /** + * Return a representation of the location. For this to be correct, + * ]b4_position_type[ should override the toString + * method. */ + public const string toString () const { + if (begin==end) + return begin.toString (); + else + return begin.toString () ~ "-" ~ end.toString (); + } +} + +private immutable bool yy_location_is_class = true; + +]]))m4_ifdef([b4_user_union_members], [private union YYSemanticType +{ +b4_user_union_members +};], +[m4_if(b4_tag_seen_flag, 0, +[[private alias int YYSemanticType;]])])[ +]b4_token_enums(b4_tokens)[ +]b4_parser_class_declaration[ +{ + ]b4_identification[ + + /** True if verbose error messages are enabled. */ + public bool errorVerbose = ]b4_flag_value([error_verbose]); + + b4_locations_if([[ + private final ]b4_location_type[ yylloc_from_stack (ref YYStack rhs, int n) + { + static if (yy_location_is_class) { + if (n > 0) + return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end); + else + return new ]b4_location_type[ (rhs.locationAt (0).end); + } else { + if (n > 0) + return ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end); + else + return ]b4_location_type[ (rhs.locationAt (0).end); + } + }]])[ + + ]b4_lexer_if([[private class YYLexer implements Lexer { +]b4_percent_code_get([[lexer]])[ + } + + ]])[/** The object doing lexical analysis for us. */ + private Lexer yylexer; + ] + b4_parse_param_vars + +b4_lexer_if([[ + /** + * Instantiates the Bison-generated parser. + */ + public this] (b4_parse_param_decl([b4_lex_param_decl])[) { + this.yylexer = new YYLexer(]b4_lex_param_call[); + this.yyDebugStream = stderr; + ]b4_parse_param_cons[ + } +]]) + + /** + * Instantiates the Bison-generated parser. + * @@param yylexer The scanner that will supply tokens to the parser. + */ + b4_lexer_if([[protected]], [[public]]) [this (]b4_parse_param_decl([[Lexer yylexer]])[) { + this.yylexer = yylexer; + this.yyDebugStream = stderr; + ]b4_parse_param_cons[ + } + + private File yyDebugStream; + + /** + * Return the File on which the debugging output is + * printed. + */ + public File getDebugStream () { return yyDebugStream; } + + /** + * Set the std.File on which the debug output is printed. + * @@param s The stream that is used for debugging output. + */ + public final void setDebugStream(File s) { yyDebugStream = s; } + + private int yydebug = 0; + + /** + * Answer the verbosity of the debugging output; 0 means that all kinds of + * output from the parser are suppressed. + */ + public final int getDebugLevel() { return yydebug; } + + /** + * Set the verbosity of the debugging output; 0 means that all kinds of + * output from the parser are suppressed. + * @@param level The verbosity level for debugging output. + */ + public final void setDebugLevel(int level) { yydebug = level; } + + private final int yylex () { + return yylexer.yylex (); + } + protected final void yyerror (]b4_locations_if(ref [b4_location_type[ loc, ]])[string s) { + yylexer.yyerror (]b4_locations_if([loc, ])[s); + }] + + [protected final void yycdebug (string s) { + if (yydebug > 0) + yyDebugStream.writeln (s); + } + + /** + * Returned by a Bison action in order to stop the parsing process and + * return success (true). */ + public static immutable int YYACCEPT = 0; + + /** + * Returned by a Bison action in order to stop the parsing process and + * return failure (false). */ + public static immutable int YYABORT = 1; + + /** + * Returned by a Bison action in order to start error recovery without + * printing an error message. */ + public static immutable int YYERROR = 2; + + // Internal return codes that are not supported for user semantic + // actions. + private static immutable int YYERRLAB = 3; + private static immutable int YYNEWSTATE = 4; + private static immutable int YYDEFAULT = 5; + private static immutable int YYREDUCE = 6; + private static immutable int YYERRLAB1 = 7; + private static immutable int YYRETURN = 8; +]b4_locations_if([ + private static immutable YYSemanticType yy_semantic_null = cast(YYSemanticType)null;])[ + private int yyerrstatus_ = 0; + + /** + * Return whether error recovery is being done. In this state, the parser + * reads token until it reaches a known state, and then restarts normal + * operation. */ + public final bool recovering () + { + return yyerrstatus_ == 0; + } + + private int yyaction (int yyn, ref YYStack yystack, int yylen) + { + ]b4_yystype[ yyval; + ]b4_locations_if([b4_location_type[ yyloc = yylloc_from_stack (yystack, yylen);]])[ + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen > 0) + yyval = yystack.valueAt (yylen - 1); + else + yyval = yystack.valueAt (0); + + yy_reduce_print (yyn, yystack); + + switch (yyn) + { +]b4_user_actions[ + default: break; + } + + yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[); + + yystack.pop (yylen); + yylen = 0; + + /* Shift the result of the reduction. */ + yyn = yyr1_[yyn]; + int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0); + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystack.stateAt (0)) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyn - yyntokens_]; + + yystack.push (yystate, yyval]b4_locations_if([, yyloc])[); + return YYNEWSTATE; + } + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + private final string yytnamerr_ (string yystr) + { + if (yystr[0] == '"') + { + string yyr; + strip_quotes: for (int i = 1; i < yystr.length; i++) + switch (yystr[i]) + { + case '\'': + case ',': + break strip_quotes; + + case '\\': + if (yystr[++i] != '\\') + break strip_quotes; + goto default; + default: + yyr ~= yystr[i]; + break; + + case '"': + return yyr; + } + } + else if (yystr=="$end") + return "end of input"; + + return yystr; + } + + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + private final void yy_symbol_print (string s, int yytype, + ref ]b4_yystype[ yyvaluep]dnl +b4_locations_if([, ref ]b4_location_type[ yylocationp])[) + { + if (yydebug > 0) { + string message = s ~ (yytype < yyntokens_ ? " token " : " nterm ") + ~ yytname_[yytype] ~ " ("]b4_locations_if([ + ~ yylocationp.toString() ~ ": "])[; + static if (__traits(compiles, message~=yyvaluep.toString ())) + message ~= yyvaluep.toString (); + else + message ~= format ("%s", &yyvaluep); + message ~= ")"; + yycdebug (message); + } + } + + /** + * Parse input from the scanner that was specified at object construction + * time. Return whether the end of the input was reached successfully. + * + * @@return true if the parsing succeeds. Note that this does not + * imply that there were no syntax errors. + */ + public bool parse () + { + /// Lookahead and lookahead in internal form. + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn = 0; + int yylen = 0; + int yystate = 0; + + YYStack yystack; + + /* Error handling. */ + int yynerrs_ = 0; + ]b4_locations_if([/// The location where the error started. + ]b4_location_type[ yyerrloc = null; + + /// ]b4_location_type[ of the lookahead. + ]b4_location_type[ yylloc; + + /// @@$. + ]b4_location_type[ yyloc;])[ + + /// Semantic value of the lookahead. + ]b4_yystype[ yylval; + + int yyresult; + + yycdebug ("Starting parse\n"); + yyerrstatus_ = 0; + +]m4_ifdef([b4_initial_action], [ +m4_pushdef([b4_at_dollar], [yylloc])dnl +m4_pushdef([b4_dollar_dollar], [yylval])dnl + /* User initialization code. */ + b4_user_initial_action +m4_popdef([b4_dollar_dollar])dnl +m4_popdef([b4_at_dollar])])dnl + + [ /* Initialize the stack. */ + yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); + + int label = YYNEWSTATE; + for (;;) + final switch (label) + { + /* New state. Unlike in the C/C++ skeletons, the state is already + pushed when we come here. */ + case YYNEWSTATE: + yycdebug (format("Entering state %d\n", yystate)); + if (yydebug > 0) + yystack.print (yyDebugStream); + + /* Accept? */ + if (yystate == yyfinal_) + return true; + + /* Take a decision. First try without lookahead. */ + yyn = yypact_[yystate]; + if (yy_pact_value_is_default_ (yyn)) + { + label = YYDEFAULT; + break; + } + + /* Read a lookahead token. */ + if (yychar == yyempty_) + { + yycdebug ("Reading a token: "); + yychar = yylex ();] + b4_locations_if([[ + static if (yy_location_is_class) { + yylloc = new ]b4_location_type[(yylexer.startPos, yylexer.endPos); + } else { + yylloc = ]b4_location_type[(yylexer.startPos, yylexer.endPos); + }]]) + yylval = yylexer.semanticVal;[ + } + + /* Convert token to internal form. */ + if (yychar <= YYTokenType.EOF) + { + yychar = yytoken = YYTokenType.EOF; + yycdebug ("Now at end of input.\n"); + } + else + { + yytoken = yytranslate_ (yychar); + yy_symbol_print ("Next token is", + yytoken, yylval]b4_locations_if([, yylloc])[); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + label = YYDEFAULT; + + /* <= 0 means reduce or error. */ + else if ((yyn = yytable_[yyn]) <= 0) + { + if (yy_table_value_is_error_ (yyn)) + label = YYERRLAB; + else + { + yyn = -yyn; + label = YYREDUCE; + } + } + else + { + /* Shift the lookahead token. */ + yy_symbol_print ("Shifting", yytoken, + yylval]b4_locations_if([, yylloc])[); + + /* Discard the token being shifted. */ + yychar = yyempty_; + + /* Count tokens shifted since error; after three, turn off error + * status. */ + if (yyerrstatus_ > 0) + --yyerrstatus_; + + yystate = yyn; + yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); + label = YYNEWSTATE; + } + break; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + case YYDEFAULT: + yyn = yydefact_[yystate]; + if (yyn == 0) + label = YYERRLAB; + else + label = YYREDUCE; + break; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + case YYREDUCE: + yylen = yyr2_[yyn]; + label = yyaction (yyn, yystack, yylen); + yystate = yystack.stateAt (0); + break; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + case YYERRLAB: + /* If not already recovering from an error, report this error. */ + if (yyerrstatus_ == 0) + { + ++yynerrs_; + if (yychar == yyempty_) + yytoken = yyempty_; + yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken)); + } + + ]b4_locations_if([yyerrloc = yylloc;])[ + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse lookahead token after an + * error, discard it. */ + + if (yychar <= YYTokenType.EOF) + { + /* Return failure if at end of input. */ + if (yychar == YYTokenType.EOF) + return false; + } + else + yychar = yyempty_; + } + + /* Else will try to reuse lookahead token after shifting the error + * token. */ + label = YYERRLAB1; + break; + + /*-------------------------------------------------. + | errorlab -- error raised explicitly by YYERROR. | + `-------------------------------------------------*/ + case YYERROR: + + ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[ + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yystack.pop (yylen); + yylen = 0; + yystate = yystack.stateAt (0); + label = YYERRLAB1; + break; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + case YYERRLAB1: + yyerrstatus_ = 3; /* Each real token shifted decrements this.xb */ + + for (;;) + { + yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yystack.height == 1) + return false; + + ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[ + yystack.pop (); + yystate = yystack.stateAt (0); + if (yydebug > 0) + yystack.print (yyDebugStream); + } + + ]b4_locations_if([ + /* Muck with the stack to setup for yylloc. */ + yystack.push (0, yy_semantic_null, yylloc); + yystack.push (0, yy_semantic_null, yyerrloc); + yyloc = yylloc_from_stack (yystack, 2); + yystack.pop (2);])[ + + /* Shift the error token. */ + yy_symbol_print ("Shifting", yystos_[yyn], + yylval]b4_locations_if([, yyloc])[); + + yystate = yyn; + yystack.push (yyn, yylval]b4_locations_if([, yyloc])[); + label = YYNEWSTATE; + break; + + /* Accept. */ + case YYACCEPT: + return true; + + /* Abort. */ + case YYABORT: + return false; + } + } + + // Generate an error message. + private final string yysyntax_error (int yystate, int tok) + { + if (errorVerbose) + { + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. + See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, + then the only way this function was invoked is if the + default action is an error action. In that case, don't + check for expected tokens because there are none. + - The only way there can be no lookahead present (in tok) is + if this state is a consistent state with a default action. + Thus, detecting the absence of a lookahead is sufficient to + determine that there is no unexpected or expected token to + report. In that case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this + state is a consistent state with a default action. There + might have been a previous inconsistent state, consistent + state with a non-default action, or user semantic action + that manipulated yychar. (However, yychar is currently out + of scope during semantic actions.) + - Of course, the expected token list depends on states to + have correct lookahead information, and it depends on the + parser not to perform extra reductions after fetching a + lookahead from the scanner and before detecting a syntax + error. Thus, state merging (from LALR or IELR) and default + reductions corrupt the expected token list. However, the + list is correct for canonical LR with one exception: it + will still contain any token that will not be accepted due + to an error action in a later state. + */ + if (tok != yyempty_) + { + // FIXME: This method of building the message is not compatible + // with internationalization. + string res = "syntax error, unexpected "; + res ~= yytnamerr_ (yytname_[tok]); + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative + indexes in YYCHECK. In other words, skip the first + -YYN actions for this state because they are default + actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_ + && !yy_table_value_is_error_ (yytable_[x + yyn])) + ++count; + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_ + && !yy_table_value_is_error_ (yytable_[x + yyn])) + { + res ~= count++ == 0 ? ", expecting " : " or "; + res ~= yytnamerr_ (yytname_[x]); + } + } + } + return res; + } + } + + return "syntax error"; + } + + /** + * Whether the given yypact_ value indicates a defaulted state. + * @@param yyvalue the value to check + */ + private static bool yy_pact_value_is_default_ (int yyvalue) + { + return yyvalue == yypact_ninf_; + } + + /** + * Whether the given yytable_ value indicates a syntax error. + * @@param yyvalue the value to check + */ + private static bool yy_table_value_is_error_ (int yyvalue) + { + return yyvalue == yytable_ninf_; + } + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + private static immutable ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[; + + /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF_, syntax error. */ + private static immutable ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[; + + ]b4_parser_tables_define[ + + /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM. */ + private static immutable ]b4_int_type_for([b4_toknum])[[] + yytoken_number_ = + @{ + ]b4_toknum[ + @}; + + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + private static immutable string[] yytname_ = + @{ + ]b4_tname[ + @}; + + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ = + @{ + ]b4_rline[ + @}; + + // Report on the debug stream that the rule yyrule is going to be reduced. + private final void yy_reduce_print (int yyrule, ref YYStack yystack) + { + if (yydebug == 0) + return; + + int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + yycdebug (format("Reducing stack by rule %d (line %d), ", + yyrule - 1, yylno)); + + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + yy_symbol_print (format(" $%d =", yyi + 1), + yystos_[yystack.stateAt(yynrhs - (yyi + 1))], + ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, + b4_rhs_location(yynrhs, yyi + 1)])[); + } + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + private static immutable ]b4_int_type_for([b4_translate])[[] yytranslate_table_ = + @{ + ]b4_translate[ + @}; + + private static ]b4_int_type_for([b4_translate])[ yytranslate_ (int t) + { + if (t >= 0 && t <= yyuser_token_number_max_) + return yytranslate_table_[t]; + else + return yyundef_token_; + } + + private static immutable int yylast_ = ]b4_last[; + private static immutable int yynnts_ = ]b4_nterms_number[; + private static immutable int yyempty_ = -2; + private static immutable int yyfinal_ = ]b4_final_state_number[; + private static immutable int yyterror_ = 1; + private static immutable int yyerrcode_ = 256; + private static immutable int yyntokens_ = ]b4_tokens_number[; + + private static immutable int yyuser_token_number_max_ = ]b4_user_token_number_max[; + private static immutable int yyundef_token_ = ]b4_undef_token_number[; + +]/* User implementation code. */ +b4_percent_code_get[]dnl + +} + +b4_epilogue +m4_divert_pop(0)dnl diff --git a/msys2/usr/share/bison/skeletons/lalr1.java b/msys2/usr/share/bison/skeletons/lalr1.java new file mode 100644 index 0000000..1b9e11d --- /dev/null +++ b/msys2/usr/share/bison/skeletons/lalr1.java @@ -0,0 +1,1061 @@ +# Java skeleton for Bison -*- autoconf -*- + +# Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_include(b4_skeletonsdir/[java.m4]) + +b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java], + [b4_skeleton])]) + +# We do not depend on %debug in Java, but pacify warnings about +# non-used flags. +b4_parse_trace_if([0], [0]) + +m4_define([b4_symbol_no_destructor_assert], +[b4_symbol_if([$1], [has_destructor], + [b4_fatal([%s: %s: %%destructor does not make sense in Java], + [b4_skeleton], + [b4_symbol_action_location([$1], [destructor])])])]) +b4_symbol_foreach([b4_symbol_no_destructor_assert]) + +# Setup some macros for api.push-pull. +b4_percent_define_default([[api.push-pull]], [[pull]]) +b4_percent_define_check_values([[[[api.push-pull]], + [[pull]], [[push]], [[both]]]]) + +# Define m4 conditional macros that encode the value +# of the api.push-pull flag. +b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]]) +b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]]) +m4_case(b4_percent_define_get([[api.push-pull]]), + [pull], [m4_define([b4_push_flag], [[0]])], + [push], [m4_define([b4_pull_flag], [[0]])]) + +# Define a macro to be true when api.push-pull has the value "both". +m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])]) + +# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing +# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the +# behavior of Bison at all when push parsing is already requested. +b4_define_flag_if([use_push_for_pull]) +b4_use_push_for_pull_if([ + b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])], + [m4_define([b4_push_flag], [[1]])])]) + +# Define a macro to encapsulate the parse state variables. +# This allows them to be defined either in parse() when doing +# pull parsing, or as class instance variable when doing push parsing. +m4_define([b4_define_state],[[ + /* Lookahead and lookahead in internal form. */ + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn = 0; + int yylen = 0; + int yystate = 0; + YYStack yystack = new YYStack (); + int label = YYNEWSTATE; + + /* Error handling. */ + int yynerrs_ = 0; + ]b4_locations_if([/* The location where the error started. */ + b4_location_type yyerrloc = null; + + /* Location. */ + b4_location_type yylloc = new b4_location_type (null, null);])[ + + /* Semantic value of the lookahead. */ + ]b4_yystype[ yylval = null; +]]) + +b4_output_begin([b4_parser_file_name])[ +]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java], + [2007-2015, 2018])[ +]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[ +]])[ +]b4_user_pre_prologue[ +]b4_user_post_prologue[ +]b4_percent_code_get([[imports]]) +[/** + * A Bison parser, automatically generated from ]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[. + * + * @@author LALR (1) parser skeleton written by Paolo Bonzini. + */ +]b4_parser_class_declaration[ +{ + ]b4_identification[ +]b4_error_verbose_if([[ + /** + * True if verbose error messages are enabled. + */ + private boolean yyErrorVerbose = true; + + /** + * Return whether verbose error messages are enabled. + */ + public final boolean getErrorVerbose() { return yyErrorVerbose; } + + /** + * Set the verbosity of error messages. + * @@param verbose True to request verbose error messages. + */ + public final void setErrorVerbose(boolean verbose) + { yyErrorVerbose = verbose; } +]]) + +b4_locations_if([[ + /** + * A class defining a pair of positions. Positions, defined by the + * ]b4_position_type[ class, denote a point in the input. + * Locations represent a part of the input through the beginning + * and ending positions. + */ + public class ]b4_location_type[ { + /** + * The first, inclusive, position in the range. + */ + public ]b4_position_type[ begin; + + /** + * The first position beyond the range. + */ + public ]b4_position_type[ end; + + /** + * Create a ]b4_location_type[ denoting an empty range located at + * a given point. + * @@param loc The position at which the range is anchored. + */ + public ]b4_location_type[ (]b4_position_type[ loc) { + this.begin = this.end = loc; + } + + /** + * Create a ]b4_location_type[ from the endpoints of the range. + * @@param begin The first position included in the range. + * @@param end The first position beyond the range. + */ + public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) { + this.begin = begin; + this.end = end; + } + + /** + * Print a representation of the location. For this to be correct, + * ]b4_position_type[ should override the equals + * method. + */ + public String toString () { + if (begin.equals (end)) + return begin.toString (); + else + return begin.toString () + "-" + end.toString (); + } + } + +]]) + + b4_locations_if([[ + private ]b4_location_type[ yylloc (YYStack rhs, int n) + { + if (n > 0) + return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end); + else + return new ]b4_location_type[ (rhs.locationAt (0).end); + }]])[ + + /** + * Communication interface between the scanner and the Bison-generated + * parser ]b4_parser_class[. + */ + public interface Lexer { + /** Token returned by the scanner to signal the end of its input. */ + public static final int EOF = 0; + +]b4_token_enums[ + + ]b4_locations_if([[/** + * Method to retrieve the beginning position of the last scanned token. + * @@return the position at which the last scanned token starts. + */ + ]b4_position_type[ getStartPos (); + + /** + * Method to retrieve the ending position of the last scanned token. + * @@return the first position beyond the last scanned token. + */ + ]b4_position_type[ getEndPos ();]])[ + + /** + * Method to retrieve the semantic value of the last scanned token. + * @@return the semantic value of the last scanned token. + */ + ]b4_yystype[ getLVal (); + + /** + * Entry point for the scanner. Returns the token identifier corresponding + * to the next token and prepares to return the semantic value + * ]b4_locations_if([and beginning/ending positions ])[of the token. + * @@return the token identifier corresponding to the next token. + */ + int yylex () ]b4_maybe_throws([b4_lex_throws])[; + + /** + * Entry point for error reporting. Emits an error + * ]b4_locations_if([referring to the given location ])[in a user-defined way. + * + * ]b4_locations_if([[@@param loc The location of the element to which the + * error message is related]])[ + * @@param msg The string for the error message. + */ + void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);] + } + + b4_lexer_if([[private class YYLexer implements Lexer { +]b4_percent_code_get([[lexer]])[ + } + + ]])[/** + * The object doing lexical analysis for us. + */ + private Lexer yylexer; + ] + b4_parse_param_vars + +b4_lexer_if([[ + /** + * Instantiates the Bison-generated parser. + */ + public ]b4_parser_class (b4_parse_param_decl([b4_lex_param_decl])[) ]b4_maybe_throws([b4_init_throws])[ + { + ]b4_percent_code_get([[init]])[ + this.yylexer = new YYLexer(]b4_lex_param_call[); + ]b4_parse_param_cons[ + } +]]) + + /** + * Instantiates the Bison-generated parser. + * @@param yylexer The scanner that will supply tokens to the parser. + */ + b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[) ]b4_maybe_throws([b4_init_throws])[ + { + ]b4_percent_code_get([[init]])[ + this.yylexer = yylexer; + ]b4_parse_param_cons[ + } + + private java.io.PrintStream yyDebugStream = System.err; + + /** + * Return the PrintStream on which the debugging output is + * printed. + */ + public final java.io.PrintStream getDebugStream () { return yyDebugStream; } + + /** + * Set the PrintStream on which the debug output is printed. + * @@param s The stream that is used for debugging output. + */ + public final void setDebugStream(java.io.PrintStream s) { yyDebugStream = s; } + + private int yydebug = 0; + + /** + * Answer the verbosity of the debugging output; 0 means that all kinds of + * output from the parser are suppressed. + */ + public final int getDebugLevel() { return yydebug; } + + /** + * Set the verbosity of the debugging output; 0 means that all kinds of + * output from the parser are suppressed. + * @@param level The verbosity level for debugging output. + */ + public final void setDebugLevel(int level) { yydebug = level; } + + /** + * Print an error message via the lexer. + *]b4_locations_if([[ Use a null location.]])[ + * @@param msg The error message. + */ + public final void yyerror (String msg) + { + yylexer.yyerror (]b4_locations_if([[(]b4_location_type[)null, ]])[msg); + } +]b4_locations_if([[ + /** + * Print an error message via the lexer. + * @@param loc The location associated with the message. + * @@param msg The error message. + */ + public final void yyerror (]b4_location_type[ loc, String msg) + { + yylexer.yyerror (loc, msg); + } + + /** + * Print an error message via the lexer. + * @@param pos The position associated with the message. + * @@param msg The error message. + */ + public final void yyerror (]b4_position_type[ pos, String msg) + { + yylexer.yyerror (new ]b4_location_type[ (pos), msg); + }]]) + + [protected final void yycdebug (String s) { + if (yydebug > 0) + yyDebugStream.println (s); + } + + private final class YYStack { + private int[] stateStack = new int[16]; + ]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[ + private ]b4_yystype[[] valueStack = new ]b4_yystype[[16]; + + public int size = 16; + public int height = -1; + + public final void push (int state, ]b4_yystype[ value]dnl + b4_locations_if([, ]b4_location_type[ loc])[) { + height++; + if (size == height) + { + int[] newStateStack = new int[size * 2]; + System.arraycopy (stateStack, 0, newStateStack, 0, height); + stateStack = newStateStack; + ]b4_locations_if([[ + ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2]; + System.arraycopy (locStack, 0, newLocStack, 0, height); + locStack = newLocStack;]]) + + b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2]; + System.arraycopy (valueStack, 0, newValueStack, 0, height); + valueStack = newValueStack; + + size *= 2; + } + + stateStack[height] = state; + ]b4_locations_if([[locStack[height] = loc;]])[ + valueStack[height] = value; + } + + public final void pop () { + pop (1); + } + + public final void pop (int num) { + // Avoid memory leaks... garbage collection is a white lie! + if (num > 0) { + java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null); + ]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[ + } + height -= num; + } + + public final int stateAt (int i) { + return stateStack[height - i]; + } + + ]b4_locations_if([[public final ]b4_location_type[ locationAt (int i) { + return locStack[height - i]; + } + + ]])[public final ]b4_yystype[ valueAt (int i) { + return valueStack[height - i]; + } + + // Print the state stack on the debug stream. + public void print (java.io.PrintStream out) { + out.print ("Stack now"); + + for (int i = 0; i <= height; i++) + { + out.print (' '); + out.print (stateStack[i]); + } + out.println (); + } + } + + /** + * Returned by a Bison action in order to stop the parsing process and + * return success (true). + */ + public static final int YYACCEPT = 0; + + /** + * Returned by a Bison action in order to stop the parsing process and + * return failure (false). + */ + public static final int YYABORT = 1; + +]b4_push_if([ + /** + * Returned by a Bison action in order to request a new token. + */ + public static final int YYPUSH_MORE = 4;])[ + + /** + * Returned by a Bison action in order to start error recovery without + * printing an error message. + */ + public static final int YYERROR = 2; + + /** + * Internal return codes that are not supported for user semantic + * actions. + */ + private static final int YYERRLAB = 3; + private static final int YYNEWSTATE = 4; + private static final int YYDEFAULT = 5; + private static final int YYREDUCE = 6; + private static final int YYERRLAB1 = 7; + private static final int YYRETURN = 8; +]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[ + + private int yyerrstatus_ = 0; + +]b4_push_if([dnl +b4_define_state])[ + /** + * Return whether error recovery is being done. In this state, the parser + * reads token until it reaches a known state, and then restarts normal + * operation. + */ + public final boolean recovering () + { + return yyerrstatus_ == 0; + } + + /** Compute post-reduction state. + * @@param yystate the current state + * @@param yysym the nonterminal to push on the stack + */ + private int yy_lr_goto_state_ (int yystate, int yysym) + { + int yyr = yypgoto_[yysym - yyntokens_] + yystate; + if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate) + return yytable_[yyr]; + else + return yydefgoto_[yysym - yyntokens_]; + } + + private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[ + { + ]b4_yystype[ yyval; + ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[ + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen > 0) + yyval = yystack.valueAt (yylen - 1); + else + yyval = yystack.valueAt (0); + + yy_reduce_print (yyn, yystack); + + switch (yyn) + { + ]b4_user_actions[ + default: break; + } + + yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[); + + yystack.pop (yylen); + yylen = 0; + + /* Shift the result of the reduction. */ + int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]); + yystack.push (yystate, yyval]b4_locations_if([, yyloc])[); + return YYNEWSTATE; + } + +]b4_error_verbose_if([[ + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + private final String yytnamerr_ (String yystr) + { + if (yystr.charAt (0) == '"') + { + StringBuffer yyr = new StringBuffer (); + strip_quotes: for (int i = 1; i < yystr.length (); i++) + switch (yystr.charAt (i)) + { + case '\'': + case ',': + break strip_quotes; + + case '\\': + if (yystr.charAt(++i) != '\\') + break strip_quotes; + /* Fall through. */ + default: + yyr.append (yystr.charAt (i)); + break; + + case '"': + return yyr.toString (); + } + } + else if (yystr.equals ("$end")) + return "end of input"; + + return yystr; + } +]])[ + + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + private void yy_symbol_print (String s, int yytype, + ]b4_yystype[ yyvaluep]dnl + b4_locations_if([, Object yylocationp])[) + { + if (yydebug > 0) + yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ") + + yytname_[yytype] + " ("]b4_locations_if([ + + yylocationp + ": "])[ + + (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")"); + } + +]b4_push_if([],[[ + /** + * Parse input from the scanner that was specified at object construction + * time. Return whether the end of the input was reached successfully. + * + * @@return true if the parsing succeeds. Note that this does not + * imply that there were no syntax errors. + */ + public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[ +]b4_push_if([ + /** + * Push Parse input from external lexer + * + * @@param yylextoken current token + * @@param yylexval current lval +]b4_locations_if([ * @@param yylexloc current position])[ + * + * @@return YYACCEPT, YYABORT, YYPUSH_MORE + */ + public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc])) + b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[ + { + ]b4_locations_if([/* @@$. */ + b4_location_type yyloc;])[ +]b4_push_if([],[[ +]b4_define_state[ + yycdebug ("Starting parse\n"); + yyerrstatus_ = 0; + + /* Initialize the stack. */ + yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[); +]m4_ifdef([b4_initial_action], [ +b4_dollar_pushdef([yylval], [], [], [yylloc])dnl + b4_user_initial_action +b4_dollar_popdef[]dnl +])[ +]])[ +]b4_push_if([[ + if (!this.push_parse_initialized) + { + push_parse_initialize (); +]m4_ifdef([b4_initial_action], [ +b4_dollar_pushdef([yylval], [], [], [yylloc])dnl + b4_user_initial_action +b4_dollar_popdef[]dnl +])[ + yycdebug ("Starting parse\n"); + yyerrstatus_ = 0; + } else + label = YYGETTOKEN; + + boolean push_token_consumed = true; +]])[ + for (;;) + switch (label) + { + /* New state. Unlike in the C/C++ skeletons, the state is already + pushed when we come here. */ + case YYNEWSTATE: + yycdebug ("Entering state " + yystate + "\n"); + if (yydebug > 0) + yystack.print (yyDebugStream); + + /* Accept? */ + if (yystate == yyfinal_) + ]b4_push_if([{label = YYACCEPT; break;}], + [return true;])[ + + /* Take a decision. First try without lookahead. */ + yyn = yypact_[yystate]; + if (yy_pact_value_is_default_ (yyn)) + { + label = YYDEFAULT; + break; + } +]b4_push_if([ /* Fall Through */ + + case YYGETTOKEN:])[ + /* Read a lookahead token. */ + if (yychar == yyempty_) + { +]b4_push_if([[ + if (!push_token_consumed) + return YYPUSH_MORE; + yycdebug ("Reading a token: "); + yychar = yylextoken; + yylval = yylexval;]b4_locations_if([ + yylloc = yylexloc;])[ + push_token_consumed = false;]])[ +]b4_push_if([],[[ + yycdebug ("Reading a token: "); + yychar = yylexer.yylex (); + yylval = yylexer.getLVal ();]b4_locations_if([ + yylloc = new b4_location_type (yylexer.getStartPos (), + yylexer.getEndPos ());])[ +]])[ + } + + /* Convert token to internal form. */ + if (yychar <= Lexer.EOF) + { + yychar = yytoken = Lexer.EOF; + yycdebug ("Now at end of input.\n"); + } + else + { + yytoken = yytranslate_ (yychar); + yy_symbol_print ("Next token is", yytoken, + yylval]b4_locations_if([, yylloc])[); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + label = YYDEFAULT; + + /* <= 0 means reduce or error. */ + else if ((yyn = yytable_[yyn]) <= 0) + { + if (yy_table_value_is_error_ (yyn)) + label = YYERRLAB; + else + { + yyn = -yyn; + label = YYREDUCE; + } + } + + else + { + /* Shift the lookahead token. */ + yy_symbol_print ("Shifting", yytoken, + yylval]b4_locations_if([, yylloc])[); + + /* Discard the token being shifted. */ + yychar = yyempty_; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_ > 0) + --yyerrstatus_; + + yystate = yyn; + yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); + label = YYNEWSTATE; + } + break; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + case YYDEFAULT: + yyn = yydefact_[yystate]; + if (yyn == 0) + label = YYERRLAB; + else + label = YYREDUCE; + break; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + case YYREDUCE: + yylen = yyr2_[yyn]; + label = yyaction (yyn, yystack, yylen); + yystate = yystack.stateAt (0); + break; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + case YYERRLAB: + /* If not already recovering from an error, report this error. */ + if (yyerrstatus_ == 0) + { + ++yynerrs_; + if (yychar == yyempty_) + yytoken = yyempty_; + yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken)); + } + + ]b4_locations_if([yyerrloc = yylloc;])[ + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= Lexer.EOF) + { + /* Return failure if at end of input. */ + if (yychar == Lexer.EOF) + ]b4_push_if([{label = YYABORT; break;}],[return false;])[ + } + else + yychar = yyempty_; + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + label = YYERRLAB1; + break; + + /*-------------------------------------------------. + | errorlab -- error raised explicitly by YYERROR. | + `-------------------------------------------------*/ + case YYERROR: + + ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[ + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yystack.pop (yylen); + yylen = 0; + yystate = yystack.stateAt (0); + label = YYERRLAB1; + break; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + case YYERRLAB1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the + * error token. */ + if (yystack.height == 0) + ]b4_push_if([{label = YYABORT; break;}],[return false;])[ + + ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[ + yystack.pop (); + yystate = yystack.stateAt (0); + if (yydebug > 0) + yystack.print (yyDebugStream); + } + + if (label == YYABORT) + /* Leave the switch. */ + break; + +]b4_locations_if([ + /* Muck with the stack to setup for yylloc. */ + yystack.push (0, null, yylloc); + yystack.push (0, null, yyerrloc); + yyloc = yylloc (yystack, 2); + yystack.pop (2);])[ + + /* Shift the error token. */ + yy_symbol_print ("Shifting", yystos_[yyn], + yylval]b4_locations_if([, yyloc])[); + + yystate = yyn; + yystack.push (yyn, yylval]b4_locations_if([, yyloc])[); + label = YYNEWSTATE; + break; + + /* Accept. */ + case YYACCEPT: + ]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;], + [return true;])[ + + /* Abort. */ + case YYABORT: + ]b4_push_if([this.push_parse_initialized = false; return YYABORT;], + [return false;])[ + } +} +]b4_push_if([[ + boolean push_parse_initialized = false; + + /** + * (Re-)Initialize the state of the push parser. + */ + public void push_parse_initialize() + { + /* Lookahead and lookahead in internal form. */ + this.yychar = yyempty_; + this.yytoken = 0; + + /* State. */ + this.yyn = 0; + this.yylen = 0; + this.yystate = 0; + this.yystack = new YYStack (); + this.label = YYNEWSTATE; + + /* Error handling. */ + this.yynerrs_ = 0; + ]b4_locations_if([/* The location where the error started. */ + this.yyerrloc = null; + this.yylloc = new b4_location_type (null, null);])[ + + /* Semantic value of the lookahead. */ + this.yylval = null; + + yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[); + + this.push_parse_initialized = true; + + } +]b4_locations_if([ + /** + * Push parse given input from an external lexer. + * + * @@param yylextoken current token + * @@param yylexval current lval + * @@param yyylexpos current position + * + * @@return YYACCEPT, YYABORT, YYPUSH_MORE + */ + public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos) + b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])]) + { + return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos)); + } +])[]]) + +b4_both_if([[ + /** + * Parse input from the scanner that was specified at object construction + * time. Return whether the end of the input was reached successfully. + * This version of parse () is defined only when api.push-push=both. + * + * @@return true if the parsing succeeds. Note that this does not + * imply that there were no syntax errors. + */ + public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ + { + if (yylexer == null) + throw new NullPointerException("Null Lexer"); + int status; + do { + int token = yylexer.yylex(); + ]b4_yystype[ lval = yylexer.getLVal(); +]b4_locations_if([dnl + b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (), + yylexer.getEndPos ());])[ + ]b4_locations_if([status = push_parse(token,lval,yyloc);],[ + status = push_parse(token,lval);])[ + } while (status == YYPUSH_MORE); + return (status == YYACCEPT); + } +]])[ + + // Generate an error message. + private String yysyntax_error (int yystate, int tok) + {]b4_error_verbose_if([[ + if (yyErrorVerbose) + { + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, + then the only way this function was invoked is if the + default action is an error action. In that case, don't + check for expected tokens because there are none. + - The only way there can be no lookahead present (in tok) is + if this state is a consistent state with a default action. + Thus, detecting the absence of a lookahead is sufficient to + determine that there is no unexpected or expected token to + report. In that case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this + state is a consistent state with a default action. There + might have been a previous inconsistent state, consistent + state with a non-default action, or user semantic action + that manipulated yychar. (However, yychar is currently out + of scope during semantic actions.) + - Of course, the expected token list depends on states to + have correct lookahead information, and it depends on the + parser not to perform extra reductions after fetching a + lookahead from the scanner and before detecting a syntax + error. Thus, state merging (from LALR or IELR) and default + reductions corrupt the expected token list. However, the + list is correct for canonical LR with one exception: it + will still contain any token that will not be accepted due + to an error action in a later state. + */ + if (tok != yyempty_) + { + /* FIXME: This method of building the message is not compatible + with internationalization. */ + StringBuffer res = + new StringBuffer ("syntax error, unexpected "); + res.append (yytnamerr_ (yytname_[tok])); + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative + indexes in YYCHECK. In other words, skip the first + -YYN actions for this state because they are default + actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_ + && !yy_table_value_is_error_ (yytable_[x + yyn])) + ++count; + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_ + && !yy_table_value_is_error_ (yytable_[x + yyn])) + { + res.append (count++ == 0 ? ", expecting " : " or "); + res.append (yytnamerr_ (yytname_[x])); + } + } + } + return res.toString (); + } + } +]])[ + return "syntax error"; + } + + /** + * Whether the given yypact_ value indicates a defaulted state. + * @@param yyvalue the value to check + */ + private static boolean yy_pact_value_is_default_ (int yyvalue) + { + return yyvalue == yypact_ninf_; + } + + /** + * Whether the given yytable_ + * value indicates a syntax error. + * @@param yyvalue the value to check + */ + private static boolean yy_table_value_is_error_ (int yyvalue) + { + return yyvalue == yytable_ninf_; + } + + private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[; + private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[; + + ]b4_parser_tables_define[ + ]b4_integral_parser_table_define([token_number], [b4_toknum], + [[YYTOKEN_NUMBER[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM.]])[ + + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + ]b4_typed_parser_table_define([String], [tname], [b4_tname])[ + + ]b4_integral_parser_table_define([rline], [b4_rline], + [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ + + + // Report on the debug stream that the rule yyrule is going to be reduced. + private void yy_reduce_print (int yyrule, YYStack yystack) + { + if (yydebug == 0) + return; + + int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + yycdebug ("Reducing stack by rule " + (yyrule - 1) + + " (line " + yylno + "), "); + + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + yy_symbol_print (" $" + (yyi + 1) + " =", + yystos_[yystack.stateAt(yynrhs - (yyi + 1))], + ]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([, + b4_rhs_location(yynrhs, yyi + 1)])[); + } + + /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ + ]b4_integral_parser_table_define([translate_table], [b4_translate])[ + + private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t) + { + if (t >= 0 && t <= yyuser_token_number_max_) + return yytranslate_table_[t]; + else + return yyundef_token_; + } + + private static final int yylast_ = ]b4_last[; + private static final int yynnts_ = ]b4_nterms_number[; + private static final int yyempty_ = -2; + private static final int yyfinal_ = ]b4_final_state_number[; + private static final int yyterror_ = 1; + private static final int yyerrcode_ = 256; + private static final int yyntokens_ = ]b4_tokens_number[; + + private static final int yyuser_token_number_max_ = ]b4_user_token_number_max[; + private static final int yyundef_token_ = ]b4_undef_token_number[; + +]/* User implementation code. */ +b4_percent_code_get[]dnl + +} + +b4_epilogue[]dnl +b4_output_end diff --git a/msys2/usr/share/bison/skeletons/location.cc b/msys2/usr/share/bison/skeletons/location.cc new file mode 100644 index 0000000..a57c0fb --- /dev/null +++ b/msys2/usr/share/bison/skeletons/location.cc @@ -0,0 +1,363 @@ +# C++ skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +m4_pushdef([b4_copyright_years], + [2002-2015, 2018-2019]) + + +# b4_position_file +# ---------------- +# Name of the file containing the position class, if we want this file. +b4_defines_if([b4_required_version_if([302], [], + [m4_define([b4_position_file], [position.hh])])])]) + + +# b4_location_file +# ---------------- +# Name of the file containing the position/location class, +# if we want this file. +b4_percent_define_check_file([b4_location_file], + [[api.location.file]], + b4_defines_if([[location.hh]])) + +# b4_location_include +# ------------------- +# If location.hh is to be generated, the name under which should it be +# included. +# +# b4_location_path +# ---------------- +# The path to use for the CPP guard. +m4_ifdef([b4_location_file], +[m4_define([b4_location_include], + [b4_percent_define_get([[api.location.include]], + ["b4_location_file"])]) + m4_define([b4_location_path], + b4_percent_define_get([[api.location.include]], + ["b4_dir_prefix[]b4_location_file"])) + m4_define([b4_location_path], + m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2))) + ]) + + + +# b4_location_define +# ------------------ +# Define the position and location classes. +m4_define([b4_location_define], +[[ /// A point in a source file. + class position + { + public:]m4_ifdef([b4_location_constructors], [[ + /// Construct a position. + explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR, + unsigned l = ]b4_location_initial_line[u, + unsigned c = ]b4_location_initial_column[u) + : filename (f) + , line (l) + , column (c) + {} + +]])[ + /// Initialization. + void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR, + unsigned l = ]b4_location_initial_line[u, + unsigned c = ]b4_location_initial_column[u) + { + filename = fn; + line = l; + column = c; + } + + /** \name Line and Column related manipulators + ** \{ */ + /// (line related) Advance to the COUNT next lines. + void lines (int count = 1) + { + if (count) + { + column = ]b4_location_initial_column[u; + line = add_ (line, count, ]b4_location_initial_line[); + } + } + + /// (column related) Advance to the COUNT next columns. + void columns (int count = 1) + { + column = add_ (column, count, ]b4_location_initial_column[); + } + /** \} */ + + /// File name to which this position refers. + ]b4_percent_define_get([[filename_type]])[* filename; + /// Current line number. + unsigned line; + /// Current column number. + unsigned column; + + private: + /// Compute max (min, lhs+rhs). + static unsigned add_ (unsigned lhs, int rhs, int min) + { + return static_cast (std::max (min, + static_cast (lhs) + rhs)); + } + }; + + /// Add \a width columns, in place. + inline position& + operator+= (position& res, int width) + { + res.columns (width); + return res; + } + + /// Add \a width columns. + inline position + operator+ (position res, int width) + { + return res += width; + } + + /// Subtract \a width columns, in place. + inline position& + operator-= (position& res, int width) + { + return res += -width; + } + + /// Subtract \a width columns. + inline position + operator- (position res, int width) + { + return res -= width; + } +]b4_percent_define_flag_if([[define_location_comparison]], [[ + /// Compare two position objects. + inline bool + operator== (const position& pos1, const position& pos2) + { + return (pos1.line == pos2.line + && pos1.column == pos2.column + && (pos1.filename == pos2.filename + || (pos1.filename && pos2.filename + && *pos1.filename == *pos2.filename))); + } + + /// Compare two position objects. + inline bool + operator!= (const position& pos1, const position& pos2) + { + return !(pos1 == pos2); + } +]])[ + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + template + std::basic_ostream& + operator<< (std::basic_ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + + /// Two points in a source file. + class location + { + public: +]m4_ifdef([b4_location_constructors], [ + /// Construct a location from \a b to \a e. + location (const position& b, const position& e) + : begin (b) + , end (e) + {} + + /// Construct a 0-width location in \a p. + explicit location (const position& p = position ()) + : begin (p) + , end (p) + {} + + /// Construct a 0-width location in \a f, \a l, \a c. + explicit location (]b4_percent_define_get([[filename_type]])[* f, + unsigned l = ]b4_location_initial_line[u, + unsigned c = ]b4_location_initial_column[u) + : begin (f, l, c) + , end (f, l, c) + {} + +])[ + /// Initialization. + void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR, + unsigned l = ]b4_location_initial_line[u, + unsigned c = ]b4_location_initial_column[u) + { + begin.initialize (f, l, c); + end = begin; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// Reset initial location to final location. + void step () + { + begin = end; + } + + /// Extend the current location to the COUNT next columns. + void columns (int count = 1) + { + end += count; + } + + /// Extend the current location to the COUNT next lines. + void lines (int count = 1) + { + end.lines (count); + } + /** \} */ + + + public: + /// Beginning of the located region. + position begin; + /// End of the located region. + position end; + }; + + /// Join two locations, in place. + inline location& operator+= (location& res, const location& end) + { + res.end = end.end; + return res; + } + + /// Join two locations. + inline location operator+ (location res, const location& end) + { + return res += end; + } + + /// Add \a width columns to the end position, in place. + inline location& operator+= (location& res, int width) + { + res.columns (width); + return res; + } + + /// Add \a width columns to the end position. + inline location operator+ (location res, int width) + { + return res += width; + } + + /// Subtract \a width columns to the end position, in place. + inline location& operator-= (location& res, int width) + { + return res += -width; + } + + /// Subtract \a width columns to the end position. + inline location operator- (location res, int width) + { + return res -= width; + } +]b4_percent_define_flag_if([[define_location_comparison]], [[ + /// Compare two location objects. + inline bool + operator== (const location& loc1, const location& loc2) + { + return loc1.begin == loc2.begin && loc1.end == loc2.end; + } + + /// Compare two location objects. + inline bool + operator!= (const location& loc1, const location& loc2) + { + return !(loc1 == loc2); + } +]])[ + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param loc a reference to the location to redirect + ** + ** Avoid duplicate information. + */ + template + std::basic_ostream& + operator<< (std::basic_ostream& ostr, const location& loc) + { + unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; + ostr << loc.begin; + if (loc.end.filename + && (!loc.begin.filename + || *loc.begin.filename != *loc.end.filename)) + ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col; + else if (loc.begin.line < loc.end.line) + ostr << '-' << loc.end.line << '.' << end_col; + else if (loc.begin.column < end_col) + ostr << '-' << end_col; + return ostr; + } +]]) + + +m4_ifdef([b4_position_file], [[ +]b4_output_begin([b4_dir_prefix], [b4_position_file])[ +]b4_generated_by[ +// Starting with Bison 3.2, this file is useless: the structure it +// used to define is now defined in "]b4_location_file[". +// +// To get rid of this file: +// 1. add 'require "3.2"' (or newer) to your grammar file +// 2. remove references to this file from your build system +// 3. if you used to include it, include "]b4_location_file[" instead. + +#include ]b4_location_include[ +]b4_output_end[ +]]) + + +m4_ifdef([b4_location_file], [[ +]b4_output_begin([b4_dir_prefix], [b4_location_file])[ +]b4_copyright([Locations for Bison parsers in C++])[ +/** + ** \file ]b4_location_path[ + ** Define the ]b4_namespace_ref[::location class. + */ + +]b4_cpp_guard_open([b4_location_path])[ + +# include // std::max +# include +# include + +]b4_null_define[ + +]b4_namespace_open[ +]b4_location_define[ +]b4_namespace_close[ +]b4_cpp_guard_close([b4_location_path])[ +]b4_output_end[ +]]) + + +m4_popdef([b4_copyright_years]) diff --git a/msys2/usr/share/bison/skeletons/stack.hh b/msys2/usr/share/bison/skeletons/stack.hh new file mode 100644 index 0000000..926a6f8 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/stack.hh @@ -0,0 +1,163 @@ +# C++ skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# b4_stack_file +# ------------- +# Name of the file containing the stack class, if we want this file. +b4_defines_if([b4_required_version_if([302], [], + [m4_define([b4_stack_file], [stack.hh])])]) + + +# b4_stack_define +# --------------- +m4_define([b4_stack_define], +[[ /// A stack with random access from its top. + template > + class stack + { + public: + // Hide our reversed order. + typedef typename S::reverse_iterator iterator; + typedef typename S::const_reverse_iterator const_iterator; + typedef typename S::size_type size_type; + + stack (size_type n = 200) + : seq_ (n) + {} + + /// Random access. + /// + /// Index 0 returns the topmost element. + T& + operator[] (size_type i) + { + return seq_[size () - 1 - i]; + } + + /// Random access. + /// + /// Index 0 returns the topmost element. + T& + operator[] (int i) + { + return operator[] (size_type (i)); + } + + /// Random access. + /// + /// Index 0 returns the topmost element. + const T& + operator[] (size_type i) const + { + return seq_[size () - 1 - i]; + } + + /// Random access. + /// + /// Index 0 returns the topmost element. + const T& + operator[] (int i) const + { + return operator[] (size_type (i)); + } + + /// Steal the contents of \a t. + /// + /// Close to move-semantics. + void + push (YY_MOVE_REF (T) t) + { + seq_.push_back (T ()); + operator[] (0).move (t); + } + + /// Pop elements from the stack. + void + pop (int n = 1) YY_NOEXCEPT + { + for (; 0 < n; --n) + seq_.pop_back (); + } + + /// Pop all elements from the stack. + void + clear () YY_NOEXCEPT + { + seq_.clear (); + } + + /// Number of elements on the stack. + size_type + size () const YY_NOEXCEPT + { + return seq_.size (); + } + + /// Iterator on top of the stack (going downwards). + const_iterator + begin () const YY_NOEXCEPT + { + return seq_.rbegin (); + } + + /// Bottom of the stack. + const_iterator + end () const YY_NOEXCEPT + { + return seq_.rend (); + } + + /// Present a slice of the top of a stack. + class slice + { + public: + slice (const stack& stack, int range) + : stack_ (stack) + , range_ (range) + {} + + const T& + operator[] (int i) const + { + return stack_[range_ - i]; + } + + private: + const stack& stack_; + int range_; + }; + + private: + stack (const stack&); + stack& operator= (const stack&); + /// The wrapped container. + S seq_; + }; +]]) + +m4_ifdef([b4_stack_file], +[b4_output_begin([b4_dir_prefix], [b4_stack_file])[ +]b4_generated_by[ +// Starting with Bison 3.2, this file is useless: the structure it +// used to define is now defined with the parser itself. +// +// To get rid of this file: +// 1. add 'require "3.2"' (or newer) to your grammar file +// 2. remove references to this file from your build system. +]b4_output_end[ +]]) diff --git a/msys2/usr/share/bison/skeletons/variant.hh b/msys2/usr/share/bison/skeletons/variant.hh new file mode 100644 index 0000000..8b9d480 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/variant.hh @@ -0,0 +1,453 @@ +# C++ skeleton for Bison + +# Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +## --------- ## +## variant. ## +## --------- ## + +# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS]) +# ------------------------------------------------ +# Run some ACTION ("build", or "destroy") on YYVAL of symbol type +# YYTYPE. +m4_define([b4_symbol_variant], +[m4_pushdef([b4_dollar_dollar], + [$2.$3< $][3 > (m4_shift3($@))])dnl +switch ($1) + { +b4_type_foreach([_b4_type_action])[]dnl + default: + break; + } +m4_popdef([b4_dollar_dollar])dnl +]) + + +# _b4_char_sizeof_counter +# ----------------------- +# A counter used by _b4_char_sizeof_dummy to create fresh symbols. +m4_define([_b4_char_sizeof_counter], +[0]) + +# _b4_char_sizeof_dummy +# --------------------- +# At each call return a new C++ identifier. +m4_define([_b4_char_sizeof_dummy], +[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl +dummy[]_b4_char_sizeof_counter]) + + +# b4_char_sizeof(SYMBOL-NUMS) +# --------------------------- +# To be mapped on the list of type names to produce: +# +# char dummy1[sizeof (type_name_1)]; +# char dummy2[sizeof (type_name_2)]; +# +# for defined type names. +m4_define([b4_char_sizeof], +[b4_symbol_if([$1], [has_type], +[ +m4_map([ b4_symbol_tag_comment], [$@])dnl + char _b4_char_sizeof_dummy@{sizeof (b4_symbol([$1], [type]))@}; +])]) + + +# b4_variant_includes +# ------------------- +# The needed includes for variants support. +m4_define([b4_variant_includes], +[b4_parse_assert_if([[#include ]])[ +#ifndef YYASSERT +# include +# define YYASSERT assert +#endif +]]) + + + +## -------------------------- ## +## Adjustments for variants. ## +## -------------------------- ## + + +# b4_value_type_declare +# --------------------- +# Define semantic_type. +m4_define([b4_value_type_declare], +[[ /// A buffer to store and retrieve objects. + /// + /// Sort of a variant, but does not keep track of the nature + /// of the stored data, since that knowledge is available + /// via the current parser state. + class semantic_type + { + public: + /// Type of *this. + typedef semantic_type self_type; + + /// Empty construction. + semantic_type () YY_NOEXCEPT + : yybuffer_ ()]b4_parse_assert_if([ + , yytypeid_ (YY_NULLPTR)])[ + {} + + /// Construct and fill. + template + semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([ + : yytypeid_ (&typeid (T))])[ + { + YYASSERT (sizeof (T) <= size); + new (yyas_ ()) T (YY_MOVE (t)); + } + + /// Destruction, allowed only if empty. + ~semantic_type () YY_NOEXCEPT + {]b4_parse_assert_if([ + YYASSERT (!yytypeid_); + ])[} + +# if 201103L <= YY_CPLUSPLUS + /// Instantiate a \a T in here from \a t. + template + T& + emplace (U&&... u) + {]b4_parse_assert_if([ + YYASSERT (!yytypeid_); + YYASSERT (sizeof (T) <= size); + yytypeid_ = & typeid (T);])[ + return *new (yyas_ ()) T (std::forward (u)...); + } +# else + /// Instantiate an empty \a T in here. + template + T& + emplace () + {]b4_parse_assert_if([ + YYASSERT (!yytypeid_); + YYASSERT (sizeof (T) <= size); + yytypeid_ = & typeid (T);])[ + return *new (yyas_ ()) T (); + } + + /// Instantiate a \a T in here from \a t. + template + T& + emplace (const T& t) + {]b4_parse_assert_if([ + YYASSERT (!yytypeid_); + YYASSERT (sizeof (T) <= size); + yytypeid_ = & typeid (T);])[ + return *new (yyas_ ()) T (t); + } +# endif + + /// Instantiate an empty \a T in here. + /// Obsolete, use emplace. + template + T& + build () + { + return emplace (); + } + + /// Instantiate a \a T in here from \a t. + /// Obsolete, use emplace. + template + T& + build (const T& t) + { + return emplace (t); + } + + /// Accessor to a built \a T. + template + T& + as () YY_NOEXCEPT + {]b4_parse_assert_if([ + YYASSERT (yytypeid_); + YYASSERT (*yytypeid_ == typeid (T)); + YYASSERT (sizeof (T) <= size);])[ + return *yyas_ (); + } + + /// Const accessor to a built \a T (for %printer). + template + const T& + as () const YY_NOEXCEPT + {]b4_parse_assert_if([ + YYASSERT (yytypeid_); + YYASSERT (*yytypeid_ == typeid (T)); + YYASSERT (sizeof (T) <= size);])[ + return *yyas_ (); + } + + /// Swap the content with \a that, of same type. + /// + /// Both variants must be built beforehand, because swapping the actual + /// data requires reading it (with as()), and this is not possible on + /// unconstructed variants: it would require some dynamic testing, which + /// should not be the variant's responsibility. + /// Swapping between built and (possibly) non-built is done with + /// self_type::move (). + template + void + swap (self_type& that) YY_NOEXCEPT + {]b4_parse_assert_if([ + YYASSERT (yytypeid_); + YYASSERT (*yytypeid_ == *that.yytypeid_);])[ + std::swap (as (), that.as ()); + } + + /// Move the content of \a that to this. + /// + /// Destroys \a that. + template + void + move (self_type& that) + { +# if 201103L <= YY_CPLUSPLUS + emplace (std::move (that.as ())); +# else + emplace (); + swap (that); +# endif + that.destroy (); + } + +# if 201103L <= YY_CPLUSPLUS + /// Move the content of \a that to this. + template + void + move (self_type&& that) + { + emplace (std::move (that.as ())); + that.destroy (); + } +#endif + + /// Copy the content of \a that to this. + template + void + copy (const self_type& that) + { + emplace (that.as ()); + } + + /// Destroy the stored \a T. + template + void + destroy () + { + as ().~T ();]b4_parse_assert_if([ + yytypeid_ = YY_NULLPTR;])[ + } + + private: + /// Prohibit blind copies. + self_type& operator= (const self_type&); + semantic_type (const self_type&); + + /// Accessor to raw memory as \a T. + template + T* + yyas_ () YY_NOEXCEPT + { + void *yyp = yybuffer_.yyraw; + return static_cast (yyp); + } + + /// Const accessor to raw memory as \a T. + template + const T* + yyas_ () const YY_NOEXCEPT + { + const void *yyp = yybuffer_.yyraw; + return static_cast (yyp); + } + + /// An auxiliary type to compute the largest semantic type. + union union_type + {]b4_type_foreach([b4_char_sizeof])[ }; + + /// The size of the largest semantic type. + enum { size = sizeof (union_type) }; + + /// A buffer to store semantic values. + union + { + /// Strongest alignment constraints. + long double yyalign_me; + /// A buffer large enough to store any of the semantic values. + char yyraw[size]; + } yybuffer_;]b4_parse_assert_if([ + + /// Whether the content is built: if defined, the name of the stored type. + const std::type_info *yytypeid_;])[ + }; +]]) + + +# How the semantic value is extracted when using variants. + +# b4_symbol_value(VAL, SYMBOL-NUM, [TYPE]) +# ---------------------------------------- +# See README. +m4_define([b4_symbol_value], +[m4_ifval([$3], + [$1.as< $3 > ()], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [$1.as < b4_symbol([$2], [type]) > ()], + [$1])], + [$1])])]) + +# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE]) +# ------------------------------------------------- +# Same as b4_symbol_value, but used in a template method. +m4_define([b4_symbol_value_template], +[m4_ifval([$3], + [$1.template as< $3 > ()], + [m4_ifval([$2], + [b4_symbol_if([$2], [has_type], + [$1.template as < b4_symbol([$2], [type]) > ()], + [$1])], + [$1])])]) + + + +## ------------- ## +## make_SYMBOL. ## +## ------------- ## + + +# _b4_includes_tokens(SYMBOL-NUM...) +# ---------------------------------- +# Expands to non-empty iff one of the SYMBOL-NUM denotes +# a token. +m4_define([_b4_is_token], + [b4_symbol_if([$1], [is_token], [1])]) +m4_define([_b4_includes_tokens], + [m4_map([_b4_is_token], [$@])]) + + +# _b4_token_maker_define(SYMBOL-NUM) +# ---------------------------------- +# Declare make_SYMBOL for SYMBOL-NUM. Use at class-level. +m4_define([_b4_token_maker_define], +[b4_token_visible_if([$1], +[#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_[]_b4_symbol([$1], [id]) (b4_join( + b4_symbol_if([$1], [has_type], + [b4_symbol([$1], [type]) v]), + b4_locations_if([location_type l]))) + { + return symbol_type (b4_join([token::b4_symbol([$1], [id])], + b4_symbol_if([$1], [has_type], [std::move (v)]), + b4_locations_if([std::move (l)]))); + } +#else + static + symbol_type + make_[]_b4_symbol([$1], [id]) (b4_join( + b4_symbol_if([$1], [has_type], + [const b4_symbol([$1], [type])& v]), + b4_locations_if([const location_type& l]))) + { + return symbol_type (b4_join([token::b4_symbol([$1], [id])], + b4_symbol_if([$1], [has_type], [v]), + b4_locations_if([l]))); + } +#endif +])]) + + +m4_define([_b4_type_clause], +[b4_symbol_if([$1], [is_token], + [b4_symbol_if([$1], [has_id], + [tok == token::b4_symbol([$1], [id])], + [tok == b4_symbol([$1], [user_number])])])]) + + +# _b4_token_constructor_define(SYMBOL-NUM...) +# ------------------------------------------- +# Define a unique make_symbol for all the SYMBOL-NUM (they +# have the same type). Use at class-level. +m4_define([_b4_token_constructor_define], +[m4_ifval(_b4_includes_tokens($@), +[[#if 201103L <= YY_CPLUSPLUS + symbol_type (]b4_join( + [int tok], + b4_symbol_if([$1], [has_type], + [b4_symbol([$1], [type]) v]), + b4_locations_if([location_type l]))[) + : super_type(]b4_join([token_type (tok)], + b4_symbol_if([$1], [has_type], [std::move (v)]), + b4_locations_if([std::move (l)]))[) + { + YYASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[); + } +#else + symbol_type (]b4_join( + [int tok], + b4_symbol_if([$1], [has_type], + [const b4_symbol([$1], [type])& v]), + b4_locations_if([const location_type& l]))[) + : super_type(]b4_join([token_type (tok)], + b4_symbol_if([$1], [has_type], [v]), + b4_locations_if([l]))[) + { + YYASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[); + } +#endif +]])]) + + +# b4_basic_symbol_constructor_define(SYMBOL-NUM) +# ---------------------------------------------- +# Generate a constructor for basic_symbol from given type. +m4_define([b4_basic_symbol_constructor_define], +[[#if 201103L <= YY_CPLUSPLUS + basic_symbol (]b4_join( + [typename Base::kind_type t], + b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]), + b4_locations_if([location_type&& l]))[) + : Base (t)]b4_symbol_if([$1], [has_type], [ + , value (std::move (v))])[]b4_locations_if([ + , location (std::move (l))])[ + {} +#else + basic_symbol (]b4_join( + [typename Base::kind_type t], + b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]), + b4_locations_if([const location_type& l]))[) + : Base (t)]b4_symbol_if([$1], [has_type], [ + , value (v)])[]b4_locations_if([ + , location (l)])[ + {} +#endif +]]) + + +# b4_token_constructor_define +# --------------------------- +# Define the overloaded versions of make_symbol for all the value types. +m4_define([b4_token_constructor_define], +[ // Implementation of make_symbol for each symbol type. +b4_symbol_foreach([_b4_token_maker_define])]) diff --git a/msys2/usr/share/bison/skeletons/yacc.c b/msys2/usr/share/bison/skeletons/yacc.c new file mode 100644 index 0000000..54e40e6 --- /dev/null +++ b/msys2/usr/share/bison/skeletons/yacc.c @@ -0,0 +1,1927 @@ + -*- C -*- +# Yacc compatible skeleton for Bison + +# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software +# Foundation, Inc. + +m4_pushdef([b4_copyright_years], + [1984, 1989-1990, 2000-2015, 2018-2019]) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check the value of %define api.push-pull. +b4_percent_define_default([[api.push-pull]], [[pull]]) +b4_percent_define_check_values([[[[api.push-pull]], + [[pull]], [[push]], [[both]]]]) +b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]]) +b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]]) +m4_case(b4_percent_define_get([[api.push-pull]]), + [pull], [m4_define([b4_push_flag], [[0]])], + [push], [m4_define([b4_pull_flag], [[0]])]) + +# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing +# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the +# behavior of Bison at all when push parsing is already requested. +b4_define_flag_if([use_push_for_pull]) +b4_use_push_for_pull_if([ + b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])], + [m4_define([b4_push_flag], [[1]])])]) + +# Check the value of %define parse.lac and friends, where LAC stands for +# lookahead correction. +b4_percent_define_default([[parse.lac]], [[none]]) +b4_percent_define_default([[parse.lac.es-capacity-initial]], [[20]]) +b4_percent_define_default([[parse.lac.memory-trace]], [[failures]]) +b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]], + [[[[parse.lac.memory-trace]], + [[failures]], [[full]]]]) +b4_define_flag_if([lac]) +m4_define([b4_lac_flag], + [m4_if(b4_percent_define_get([[parse.lac]]), + [none], [[0]], [[1]])]) + +m4_include(b4_skeletonsdir/[c.m4]) + +## ---------------- ## +## Default values. ## +## ---------------- ## + +# Stack parameters. +m4_define_default([b4_stack_depth_max], [10000]) +m4_define_default([b4_stack_depth_init], [200]) + + +## ------------------------ ## +## Pure/impure interfaces. ## +## ------------------------ ## + +b4_percent_define_default([[api.pure]], [[false]]) +b4_percent_define_check_values([[[[api.pure]], + [[false]], [[true]], [[]], [[full]]]]) + +m4_define([b4_pure_flag], [[0]]) +m4_case(b4_percent_define_get([[api.pure]]), + [false], [m4_define([b4_pure_flag], [[0]])], + [true], [m4_define([b4_pure_flag], [[1]])], + [], [m4_define([b4_pure_flag], [[1]])], + [full], [m4_define([b4_pure_flag], [[2]])]) + +m4_define([b4_pure_if], +[m4_case(b4_pure_flag, + [0], [$2], + [1], [$1], + [2], [$1])]) + [m4_fatal([invalid api.pure value: ]$1)])]) + +# b4_yyerror_arg_loc_if(ARG) +# -------------------------- +# Expand ARG iff yyerror is to be given a location as argument. +m4_define([b4_yyerror_arg_loc_if], +[b4_locations_if([m4_case(b4_pure_flag, + [1], [m4_ifset([b4_parse_param], [$1])], + [2], [$1])])]) + +# b4_yyerror_args +# --------------- +# Arguments passed to yyerror: user args plus yylloc. +m4_define([b4_yyerror_args], +[b4_yyerror_arg_loc_if([&yylloc, ])dnl +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])]) + + + +## ------------ ## +## Data Types. ## +## ------------ ## + +# b4_int_type(MIN, MAX) +# --------------------- +# Return the smallest int type able to handle numbers ranging from +# MIN to MAX (included). Overwrite the version from c.m4, which +# uses only C89 types, so that the user can override the shorter +# types, and so that pre-C89 compilers are handled correctly. +m4_define([b4_int_type], +[m4_if(b4_ints_in($@, [0], [255]), [1], [yytype_uint8], + b4_ints_in($@, [-128], [127]), [1], [yytype_int8], + + b4_ints_in($@, [0], [65535]), [1], [yytype_uint16], + b4_ints_in($@, [-32768], [32767]), [1], [yytype_int16], + + m4_eval([0 <= $1]), [1], [unsigned], + + [int])]) + + +## ----------------- ## +## Semantic Values. ## +## ----------------- ## + + +# b4_lhs_value(SYMBOL-NUM, [TYPE]) +# -------------------------------- +# See README. +m4_define([b4_lhs_value], +[b4_symbol_value(yyval, [$1], [$2])]) + + +# b4_rhs_value(RULE-LENGTH, POS, [SYMBOL-NUM], [TYPE]) +# ---------------------------------------------------- +# See README. +m4_define([b4_rhs_value], +[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3], [$4])]) + + +## ----------- ## +## Locations. ## +## ----------- ## + +# b4_lhs_location() +# ----------------- +# Expansion of @$. +m4_define([b4_lhs_location], +[(yyloc)]) + + +# b4_rhs_location(RULE-LENGTH, POS) +# --------------------------------- +# Expansion of @POS, where the current rule has RULE-LENGTH symbols +# on RHS. +m4_define([b4_rhs_location], +[(yylsp@{b4_subtract([$2], [$1])@})]) + + +## -------------- ## +## Declarations. ## +## -------------- ## + +# b4_declare_scanner_communication_variables +# ------------------------------------------ +# Declare the variables that are global, or local to YYPARSE if +# pure-parser. +m4_define([b4_declare_scanner_communication_variables], [[ +/* The lookahead symbol. */ +int yychar; + +]b4_pure_if([[ +/* The semantic value of the lookahead symbol. */ +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +YY_INITIAL_VALUE (static YYSTYPE yyval_default;) +YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[ + +/* Location data for the lookahead symbol. */ +static YYLTYPE yyloc_default]b4_yyloc_default[; +YYLTYPE yylloc = yyloc_default;]])], +[[/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval;]b4_locations_if([[ +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc]b4_yyloc_default[;]])[ +/* Number of syntax errors so far. */ +int yynerrs;]])]) + + +# b4_declare_parser_state_variables +# --------------------------------- +# Declare all the variables that are needed to maintain the parser state +# between calls to yypush_parse. +m4_define([b4_declare_parser_state_variables], [b4_pure_if([[ + /* Number of syntax errors so far. */ + int yynerrs; +]])[ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values.]b4_locations_if([[ + 'yyls': related to locations.]])[ + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp;]b4_locations_if([[ + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3];]])[ + + YYSIZE_T yystacksize;]b4_lac_if([[ + + yytype_int16 yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@}; + yytype_int16 *yyes; + YYSIZE_T yyes_capacity;]])]) + + +# _b4_declare_yyparse_push +# ------------------------ +# Declaration of yyparse (and dependencies) when using the push parser +# (including in pull mode). +m4_define([_b4_declare_yyparse_push], +[[#ifndef YYPUSH_MORE_DEFINED +# define YYPUSH_MORE_DEFINED +enum { YYPUSH_MORE = 4 }; +#endif + +typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; + +]b4_pull_if([b4_function_declare([b4_prefix[parse]], [[int]], b4_parse_param) +])b4_function_declare([b4_prefix[push_parse]], [[int]], + [[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([, + [[[int pushed_char]], [[pushed_char]]], + [[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([, + [[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [, + b4_parse_param])) +b4_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]], + [[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [, + b4_parse_param]))]) +b4_function_declare([b4_prefix[pstate_new]], [b4_prefix[pstate *]], + [[[void]], []]) +b4_function_declare([b4_prefix[pstate_delete]], [[void]], + [[b4_prefix[pstate *ps]], [[ps]]])dnl +]) + +# _b4_declare_yyparse +# ------------------- +# When not the push parser. +m4_define([_b4_declare_yyparse], +[b4_function_declare(b4_prefix[parse], [int], b4_parse_param)]) + + +# b4_declare_yyparse +# ------------------ +m4_define([b4_declare_yyparse], +[b4_push_if([_b4_declare_yyparse_push], + [_b4_declare_yyparse])[]dnl +]) + + +# b4_shared_declarations +# ---------------------- +# Declaration that might either go into the header (if --defines) +# or open coded in the parser body. +m4_define([b4_shared_declarations], +[b4_cpp_guard_open([b4_spec_defines_file])[ +]b4_declare_yydebug[ +]b4_percent_code_get([[requires]])[ +]b4_token_enums_defines[ +]b4_declare_yylstype[ +]b4_declare_yyparse[ +]b4_percent_code_get([[provides]])[ +]b4_cpp_guard_close([b4_spec_defines_file])[]dnl +]) + +## -------------- ## +## Output files. ## +## -------------- ## + +b4_output_begin([b4_parser_file_name])[ +]b4_copyright([Bison implementation for Yacc-like parsers in C])[ +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +]b4_disclaimer[ +]b4_identification[ +]b4_percent_code_get([[top]])[]dnl +m4_if(b4_api_prefix, [yy], [], +[[/* Substitute the type names. */ +#define YYSTYPE ]b4_api_PREFIX[STYPE]b4_locations_if([[ +#define YYLTYPE ]b4_api_PREFIX[LTYPE]])])[ +]m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */]b4_pull_if([[ +#define yyparse ]b4_prefix[parse]])b4_push_if([[ +#define yypush_parse ]b4_prefix[push_parse]b4_pull_if([[ +#define yypull_parse ]b4_prefix[pull_parse]])[ +#define yypstate_new ]b4_prefix[pstate_new +#define yypstate_delete ]b4_prefix[pstate_delete +#define yypstate ]b4_prefix[pstate]])[ +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yydebug ]b4_prefix[debug +#define yynerrs ]b4_prefix[nerrs +]]b4_pure_if([], [[ +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])]))[ + +]b4_user_pre_prologue[ +]b4_null_define[ + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[ +#endif + +]m4_ifval(m4_quote(b4_spec_defines_file), +[[/* In a future release of Bison, this section will be replaced + by #include "@basename(]b4_spec_defines_file[@)". */ +]])dnl +b4_shared_declarations[ + +]b4_user_post_prologue[ +]b4_percent_code_get[]dnl + +[#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +]b4_attribute_define[ + +#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[ + +/* The parser invokes alloca or malloc; define the necessary symbols. */]dnl +b4_push_if([], [b4_lac_if([], [[ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif]])])[ + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif]b4_lac_if([[ +# define YYCOPY_NEEDED 1]])[ +#endif]b4_lac_if([], [[ /* ! defined yyoverflow || YYERROR_VERBOSE */]])[ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \ + && ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc;]b4_locations_if([ + YYLTYPE yyls_alloc;])[ +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +]b4_locations_if( +[# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM)], +[# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM)])[ + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL ]b4_final_state_number[ +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST ]b4_last[ + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS ]b4_tokens_number[ +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS ]b4_nterms_number[ +/* YYNRULES -- Number of rules. */ +#define YYNRULES ]b4_rules_number[ +/* YYNSTATES -- Number of states. */ +#define YYNSTATES ]b4_states_number[ + +#define YYUNDEFTOK ]b4_undef_token_number[ +#define YYMAXUTOK ]b4_user_token_number_max[ + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const ]b4_int_type_for([b4_translate])[ yytranslate[] = +{ + ]b4_translate[ +}; + +#if ]b4_api_PREFIX[DEBUG +]b4_integral_parser_table_define([rline], [b4_rline], + [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ +#endif + +#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[ +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + ]b4_tname[ +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const ]b4_int_type_for([b4_toknum])[ yytoknum[] = +{ + ]b4_toknum[ +}; +# endif + +#define YYPACT_NINF ]b4_pact_ninf[ + +#define yypact_value_is_default(Yystate) \ + ]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[ + +#define YYTABLE_NINF ]b4_table_ninf[ + +#define yytable_value_is_error(Yytable_value) \ + ]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[ + +]b4_parser_tables_define[ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \]b4_lac_if([[ + YY_LAC_DISCARD ("YYBACKUP"); \]])[ + goto yybackup; \ + } \ + else \ + { \ + yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + +]b4_locations_if([[ +]b4_yylloc_default_define[ +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +]])[ + +/* Enable debugging if requested. */ +#if ]b4_api_PREFIX[DEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +]b4_yy_location_print_define[ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value]b4_locations_if([, Location])[]b4_user_args[); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +]b4_yy_symbol_print_define[ + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +]b4_function_define([yy_stack_print], [static void], + [[yytype_int16 *yybottom], [yybottom]], + [[yytype_int16 *yytop], [yytop]])[ +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +]b4_function_define([yy_reduce_print], [static void], + [[yytype_int16 *yyssp], [yyssp]], + [[YYSTYPE *yyvsp], [yyvsp]], + b4_locations_if([[[YYLTYPE *yylsp], [yylsp]], + ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [, + b4_parse_param]))[ +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &]b4_rhs_value(yynrhs, yyi + 1)[ + ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl + b4_user_args[); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !]b4_api_PREFIX[DEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !]b4_api_PREFIX[DEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH ]b4_stack_depth_init[ +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH ]b4_stack_depth_max[ +#endif]b4_lac_if([[ + +/* Given a state stack such that *YYBOTTOM is its bottom, such that + *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty + stack, and such that *YYCAPACITY is the maximum number of elements it + can hold without a reallocation, make sure there is enough room to + store YYADD more elements. If not, allocate a new stack using + YYSTACK_ALLOC, copy the existing elements, and adjust *YYBOTTOM, + *YYTOP, and *YYCAPACITY to reflect the new capacity and memory + location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack + using YYSTACK_FREE. Return 0 if successful or if no reallocation is + required. Return 1 if memory is exhausted. */ +static int +yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd, +#if ]b4_api_PREFIX[DEBUG + char const *yydebug_prefix, + char const *yydebug_suffix, +#endif + yytype_int16 **yybottom, + yytype_int16 *yybottom_no_free, + yytype_int16 **yytop, yytype_int16 *yytop_empty) +{ + YYSIZE_T yysize_old = + (YYSIZE_T) (*yytop == yytop_empty ? 0 : *yytop - *yybottom + 1); + YYSIZE_T yysize_new = yysize_old + yyadd; + if (*yycapacity < yysize_new) + { + YYSIZE_T yyalloc = 2 * yysize_new; + yytype_int16 *yybottom_new; + /* Use YYMAXDEPTH for maximum stack size given that the stack + should never need to grow larger than the main state stack + needs to grow without LAC. */ + if (YYMAXDEPTH < yysize_new) + { + YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix, + yydebug_suffix)); + return 1; + } + if (YYMAXDEPTH < yyalloc) + yyalloc = YYMAXDEPTH; + yybottom_new = + (yytype_int16*) YYSTACK_ALLOC (yyalloc * sizeof *yybottom_new); + if (!yybottom_new) + { + YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix, + yydebug_suffix)); + return 1; + } + if (*yytop != yytop_empty) + { + YYCOPY (yybottom_new, *yybottom, yysize_old); + *yytop = yybottom_new + (yysize_old - 1); + } + if (*yybottom != yybottom_no_free) + YYSTACK_FREE (*yybottom); + *yybottom = yybottom_new; + *yycapacity = yyalloc;]m4_if(b4_percent_define_get([[parse.lac.memory-trace]]), + [full], [[ + YYDPRINTF ((stderr, "%srealloc to %lu%s", yydebug_prefix, + (unsigned long) yyalloc, yydebug_suffix));]])[ + } + return 0; +} + +/* Establish the initial context for the current lookahead if no initial + context is currently established. + + We define a context as a snapshot of the parser stacks. We define + the initial context for a lookahead as the context in which the + parser initially examines that lookahead in order to select a + syntactic action. Thus, if the lookahead eventually proves + syntactically unacceptable (possibly in a later context reached via a + series of reductions), the initial context can be used to determine + the exact set of tokens that would be syntactically acceptable in the + lookahead's place. Moreover, it is the context after which any + further semantic actions would be erroneous because they would be + determined by a syntactically unacceptable token. + + YY_LAC_ESTABLISH should be invoked when a reduction is about to be + performed in an inconsistent state (which, for the purposes of LAC, + includes consistent states that don't know they're consistent because + their default reductions have been disabled). Iff there is a + lookahead token, it should also be invoked before reporting a syntax + error. This latter case is for the sake of the debugging output. + + For parse.lac=full, the implementation of YY_LAC_ESTABLISH is as + follows. If no initial context is currently established for the + current lookahead, then check if that lookahead can eventually be + shifted if syntactic actions continue from the current context. + Report a syntax error if it cannot. */ +#define YY_LAC_ESTABLISH \ +do { \ + if (!yy_lac_established) \ + { \ + YYDPRINTF ((stderr, \ + "LAC: initial context established for %s\n", \ + yytname[yytoken])); \ + yy_lac_established = 1; \ + { \ + int yy_lac_status = \ + yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken); \ + if (yy_lac_status == 2) \ + goto yyexhaustedlab; \ + if (yy_lac_status == 1) \ + goto yyerrlab; \ + } \ + } \ +} while (0) + +/* Discard any previous initial lookahead context because of Event, + which may be a lookahead change or an invalidation of the currently + established initial context for the current lookahead. + + The most common example of a lookahead change is a shift. An example + of both cases is syntax error recovery. That is, a syntax error + occurs when the lookahead is syntactically erroneous for the + currently established initial context, so error recovery manipulates + the parser stacks to try to find a new initial context in which the + current lookahead is syntactically acceptable. If it fails to find + such a context, it discards the lookahead. */ +#if ]b4_api_PREFIX[DEBUG +# define YY_LAC_DISCARD(Event) \ +do { \ + if (yy_lac_established) \ + { \ + if (yydebug) \ + YYFPRINTF (stderr, "LAC: initial context discarded due to " \ + Event "\n"); \ + yy_lac_established = 0; \ + } \ +} while (0) +#else +# define YY_LAC_DISCARD(Event) yy_lac_established = 0 +#endif + +/* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can + eventually (after perhaps some reductions) be shifted, return 1 if + not, or return 2 if memory is exhausted. As preconditions and + postconditions: *YYES_CAPACITY is the allocated size of the array to + which *YYES points, and either *YYES = YYESA or *YYES points to an + array allocated with YYSTACK_ALLOC. yy_lac may overwrite the + contents of either array, alter *YYES and *YYES_CAPACITY, and free + any old *YYES other than YYESA. */ +static int +yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes, + YYSIZE_T *yyes_capacity, yytype_int16 *yyssp, int yytoken) +{ + yytype_int16 *yyes_prev = yyssp; + yytype_int16 *yyesp = yyes_prev; + YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yytname[yytoken])); + if (yytoken == YYUNDEFTOK) + { + YYDPRINTF ((stderr, " Always Err\n")); + return 1; + } + while (1) + { + int yyrule = yypact[*yyesp]; + if (yypact_value_is_default (yyrule) + || (yyrule += yytoken) < 0 || YYLAST < yyrule + || yycheck[yyrule] != yytoken) + { + yyrule = yydefact[*yyesp]; + if (yyrule == 0) + { + YYDPRINTF ((stderr, " Err\n")); + return 1; + } + } + else + { + yyrule = yytable[yyrule]; + if (yytable_value_is_error (yyrule)) + { + YYDPRINTF ((stderr, " Err\n")); + return 1; + } + if (0 < yyrule) + { + YYDPRINTF ((stderr, " S%d\n", yyrule)); + return 0; + } + yyrule = -yyrule; + } + { + YYSIZE_T yylen = yyr2[yyrule]; + YYDPRINTF ((stderr, " R%d", yyrule - 1)); + if (yyesp != yyes_prev) + { + YYSIZE_T yysize = (YYSIZE_T) (yyesp - *yyes + 1); + if (yylen < yysize) + { + yyesp -= yylen; + yylen = 0; + } + else + { + yylen -= yysize; + yyesp = yyes_prev; + } + } + if (yylen) + yyesp = yyes_prev -= yylen; + } + { + yytype_int16 yystate; + { + const int yylhs = yyr1[yyrule] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyesp; + yystate = ((yytype_int16) + (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp + ? yytable[yyi] + : yydefgoto[yylhs])); + } + if (yyesp == yyes_prev) + { + yyesp = *yyes; + *yyesp = yystate; + } + else + { + if (yy_lac_stack_realloc (yyes_capacity, 1, +#if ]b4_api_PREFIX[DEBUG + " (", ")", +#endif + yyes, yyesa, &yyesp, yyes_prev)) + { + YYDPRINTF ((stderr, "\n")); + return 2; + } + *++yyesp = yystate; + } + YYDPRINTF ((stderr, " G%d", (int) yystate)); + } + } +}]])[ + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +]b4_function_define([yystrlen], [static YYSIZE_T], + [[const char *yystr], [yystr]])[ +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +]b4_function_define([yystpcpy], [static char *], + [[char *yydest], [yydest]], [[const char *yysrc], [yysrc]])[ +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP.]b4_lac_if([[ In order to see if a particular token T is a + valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[ + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store]b4_lac_if([[ or if + yy_lac returned 2]])[. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + ]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes, + YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar.]b4_lac_if([[ + In the first two cases, it might appear that the current syntax + error should have been detected in the previous state when yy_lac + was invoked. However, at that time, there might have been a + different syntax error that discarded a different initial context + during error recovery, leaving behind the current lookahead.]], [[ + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state.]])[ + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp];]b4_lac_if([[ + YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[ + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + {]b4_lac_if([], [[ + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;]])[ + int yyx;]b4_lac_if([[ + + for (yyx = 0; yyx < YYNTOKENS; ++yyx) + if (yyx != YYTERROR && yyx != YYUNDEFTOK) + { + { + int yy_lac_status = yy_lac (yyesa, yyes, yyes_capacity, + yyssp, yyx); + if (yy_lac_status == 2) + return 2; + if (yy_lac_status == 1) + continue; + }]], [[ + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + {]])[ + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + }]b4_lac_if([[ +# if ]b4_api_PREFIX[DEBUG + else if (yydebug) + YYFPRINTF (stderr, "No expected tokens.\n"); +# endif]])[ + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +]b4_yydestruct_define[ + +]b4_pure_if([], [ + +b4_declare_scanner_communication_variables])[]b4_push_if([[ + +struct yypstate + {]b4_declare_parser_state_variables[ + /* Used to determine if this is the first time this instance has + been used. */ + int yynew; + };]b4_pure_if([], [[ + +static char yypstate_allocated = 0;]])b4_pull_if([ + +b4_function_define([[yyparse]], [[int]], b4_parse_param)[ +{ + return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param], + [[, ]b4_args(b4_parse_param)])[); +} + +]b4_function_define([[yypull_parse]], [[int]], + [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [, + b4_parse_param]))[ +{]b4_pure_if([b4_locations_if([[ + static YYLTYPE yyloc_default][]b4_yyloc_default[; + YYLTYPE yylloc = yyloc_default;]])])[ + yypstate *yyps_local; + if (yyps) + yyps_local = yyps; + else + { + yyps_local = yypstate_new (); + if (!yyps_local) + {]b4_pure_if([[ + yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[ + if (!yypstate_allocated) + yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[ + return 2; + } + } + int yystatus; + do {]b4_pure_if([[ + YYSTYPE yylval; + int ]])[yychar = ]b4_lex[; + yystatus = + yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[); + } while (yystatus == YYPUSH_MORE); + if (!yyps) + yypstate_delete (yyps_local); + return yystatus; +}]])[ + +/* Initialize the parser data structure. */ +]b4_function_define([[yypstate_new]], [[yypstate *]])[ +{ + yypstate *yyps;]b4_pure_if([], [[ + if (yypstate_allocated) + return YY_NULLPTR;]])[ + yyps = (yypstate *) malloc (sizeof *yyps); + if (!yyps) + return YY_NULLPTR; + yyps->yynew = 1;]b4_pure_if([], [[ + yypstate_allocated = 1;]])[ + return yyps; +} + +]b4_function_define([[yypstate_delete]], [[void]], + [[[yypstate *yyps]], [[yyps]]])[ +{ + if (yyps) + { +#ifndef yyoverflow + /* If the stack was reallocated but the parse did not complete, then the + stack still needs to be freed. */ + if (!yyps->yynew && yyps->yyss != yyps->yyssa) + YYSTACK_FREE (yyps->yyss); +#endif]b4_lac_if([[ + if (!yyps->yynew && yyps->yyes != yyps->yyesa) + YYSTACK_FREE (yyps->yyes);]])[ + free (yyps);]b4_pure_if([], [[ + yypstate_allocated = 0;]])[ + } +} +]b4_pure_if([[ +#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[ +#define yystate yyps->yystate +#define yyerrstatus yyps->yyerrstatus +#define yyssa yyps->yyssa +#define yyss yyps->yyss +#define yyssp yyps->yyssp +#define yyvsa yyps->yyvsa +#define yyvs yyps->yyvs +#define yyvsp yyps->yyvsp]b4_locations_if([[ +#define yylsa yyps->yylsa +#define yyls yyps->yyls +#define yylsp yyps->yylsp +#define yyerror_range yyps->yyerror_range]])[ +#define yystacksize yyps->yystacksize]b4_lac_if([[ +#define yyesa yyps->yyesa +#define yyes yyps->yyes +#define yyes_capacity yyps->yyes_capacity]])[ + + +/*---------------. +| yypush_parse. | +`---------------*/ + +]b4_function_define([[yypush_parse]], [[int]], + [[[yypstate *yyps]], [[yyps]]]b4_pure_if([, + [[[int yypushed_char]], [[yypushed_char]]], + [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, + [[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, + b4_parse_param]))], [[ + + +/*----------. +| yyparse. | +`----------*/ + +]b4_function_define([yyparse], [int], b4_parse_param)])[ +{]b4_pure_if([b4_declare_scanner_communication_variables +])b4_push_if([b4_pure_if([], [[ + int yypushed_char = yychar; + YYSTYPE yypushed_val = yylval;]b4_locations_if([[ + YYLTYPE yypushed_loc = yylloc;]]) +])], + [b4_declare_parser_state_variables +])b4_lac_if([[ + int yy_lac_established = 0;]])[ + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval;]b4_locations_if([[ + YYLTYPE yyloc;]])[ + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0;]b4_push_if([[ + + if (!yyps->yynew) + { + yyn = yypact[yystate]; + goto yyread_pushed_token; + }]])[ + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa;]b4_locations_if([[ + yylsp = yyls = yylsa;]])[ + yystacksize = YYINITDEPTH;]b4_lac_if([[ + + yyes = yyesa; + yyes_capacity = sizeof yyesa / sizeof *yyes; + if (YYMAXDEPTH < yyes_capacity) + yyes_capacity = YYMAXDEPTH;]])[ + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ +]m4_ifdef([b4_initial_action], [ +b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [], + [b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl +b4_user_initial_action +b4_dollar_popdef[]dnl +m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval; +]])])dnl +b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])[; +]])dnl +[ goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss;]b4_locations_if([ + YYLTYPE *yyls1 = yyls;])[ + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([ + &yyls1, yysize * sizeof (*yylsp),])[ + &yystacksize); + yyss = yyss1; + yyvs = yyvs1;]b4_locations_if([ + yyls = yyls1;])[ + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([ + YYSTACK_RELOCATE (yyls_alloc, yyls);])[ +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1;]b4_locations_if([ + yylsp = yyls + yysize - 1;])[ + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + {]b4_push_if([[ + if (!yyps->yynew) + {]b4_use_push_for_pull_if([], [[ + YYDPRINTF ((stderr, "Return for a new token:\n"));]])[ + yyresult = YYPUSH_MORE; + goto yypushreturn; + } + yyps->yynew = 0;]b4_pure_if([], [[ + /* Restoring the pushed token is only necessary for the first + yypush_parse invocation since subsequent invocations don't overwrite + it before jumping to yyread_pushed_token. */ + yychar = yypushed_char; + yylval = yypushed_val;]b4_locations_if([[ + yylloc = yypushed_loc;]])])[ +yyread_pushed_token:]])[ + YYDPRINTF ((stderr, "Reading a token: "));]b4_push_if([b4_pure_if([[ + yychar = yypushed_char; + if (yypushed_val) + yylval = *yypushed_val;]b4_locations_if([[ + if (yypushed_loc) + yylloc = *yypushed_loc;]])])], [[ + yychar = ]b4_lex[;]])[ + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)]b4_lac_if([[ + { + YY_LAC_ESTABLISH; + goto yydefault; + }]], [[ + goto yydefault;]])[ + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab;]b4_lac_if([[ + YY_LAC_ESTABLISH;]])[ + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY;]b4_lac_if([[ + YY_LAC_DISCARD ("shift");]])[ + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END +]b4_locations_if([ *++yylsp = yylloc;])[ + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + +]b4_locations_if( +[[ /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + yyerror_range[1] = yyloc;]])[ + YY_REDUCE_PRINT (yyn);]b4_lac_if([[ + { + int yychar_backup = yychar; + switch (yyn) + { +]b4_user_actions[ + default: break; + } + if (yychar_backup != yychar) + YY_LAC_DISCARD ("yychar change"); + }]], [[ + switch (yyn) + { + ]b4_user_actions[ + default: break; + }]])[ + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval;]b4_locations_if([ + *++yylsp = yyloc;])[ + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (]b4_yyerror_args[YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \]b4_lac_if([[ + yyesa, &yyes, &yyes_capacity, \]])[ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status;]b4_lac_if([[ + if (yychar != YYEMPTY) + YY_LAC_ESTABLISH;]])[ + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (]b4_yyerror_args[yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + +]b4_locations_if([[ yyerror_range[1] = yylloc;]])[ + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + +]b4_locations_if([[ yyerror_range[1] = *yylsp;]])[ + yydestruct ("Error: popping", + yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + }]b4_lac_if([[ + + /* If the stack popping above didn't lose the initial context for the + current lookahead token, the shift below will for sure. */ + YY_LAC_DISCARD ("error recovery");]])[ + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END +]b4_locations_if([[ + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); + *++yylsp = yyloc;]])[ + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if ]b4_lac_if([[1]], [[!defined yyoverflow || YYERROR_VERBOSE]])[ +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (]b4_yyerror_args[YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif]b4_lac_if([[ + if (yyes != yyesa) + YYSTACK_FREE (yyes);]])b4_push_if([[ + yyps->yynew = 1; + + +/*-----------------------------------------. +| yypushreturn -- ask for the next token. | +`-----------------------------------------*/ +yypushreturn:]])[ +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +]b4_epilogue[]dnl +b4_output_end + +b4_defines_if([[ +]b4_output_begin([b4_spec_defines_file])[ +]b4_copyright([Bison interface for Yacc-like parsers in C])[ +]b4_disclaimer[ +]b4_shared_declarations[ +]b4_output_end[ +]])# b4_defines_if diff --git a/share/bison/xslt/bison.xsl b/msys2/usr/share/bison/xslt/bison.xsl similarity index 86% rename from share/bison/xslt/bison.xsl rename to msys2/usr/share/bison/xslt/bison.xsl index 9a6ce8a..5c1a358 100644 --- a/share/bison/xslt/bison.xsl +++ b/msys2/usr/share/bison/xslt/bison.xsl @@ -3,7 +3,7 @@ + + + + + + + + + + + + // Generated by GNU Bison + + . + // Report bugs to < + + >. + // Home page: < + + >. + + + + + + + + digraph " + + + + " { + node [fontname = courier, shape = box, colorscheme = paired6] + edge [fontname = courier] + + + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + label="[ + + + + + + , + + + ]", + + + + style=solid] + + + + + + + + + 3 + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + . + + + + + + + . + + + + + + + + + + + %empty + + + + [ + + ] + + + + + + , + + + + + + + + + + + -> " + + R + + + d + + " [ + + + + + + + + " + + R + + + d + + " [label=" + + + Acc", fillcolor=1 + + + R + + ", fillcolor= + + + + , shape=diamond, style=filled] + + + + + + + + + + dotted + + + solid + + + dashed + + + + + + + + + + + + + + + + + [label=" + State + + \n + + + + \l"] + + + + + + + + + + -> + + [style= + + + label=" + + + + " + + ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/bison/xslt/xml2text.xsl b/msys2/usr/share/bison/xslt/xml2text.xsl similarity index 91% rename from share/bison/xslt/xml2text.xsl rename to msys2/usr/share/bison/xslt/xml2text.xsl index a783512..72b56e7 100644 --- a/share/bison/xslt/xml2text.xsl +++ b/msys2/usr/share/bison/xslt/xml2text.xsl @@ -3,7 +3,7 @@ diff --git a/share/bison/xslt/xml2xhtml.xsl b/msys2/usr/share/bison/xslt/xml2xhtml.xsl similarity index 83% rename from share/bison/xslt/xml2xhtml.xsl rename to msys2/usr/share/bison/xslt/xml2xhtml.xsl index 91dc630..087b035 100644 --- a/share/bison/xslt/xml2xhtml.xsl +++ b/msys2/usr/share/bison/xslt/xml2xhtml.xsl @@ -3,7 +3,7 @@ - - - - - - - - - - - - - - - - digraph Automaton { - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -> - - . - - - - - . - - - - - - - - - - - - - [ - - ] - - - - - - , - - - - - - - - - - - dotted - - - solid - - - dashed - - - - - - - - - - - - - - - - - [label=" - - - - "] - - - - - - - - - - -> - - [style= - - - label=" - - - - " - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/share/bison/yacc.c b/share/bison/yacc.c deleted file mode 100644 index 19f77a5..0000000 --- a/share/bison/yacc.c +++ /dev/null @@ -1,1741 +0,0 @@ - -*- C -*- - -# Yacc compatible skeleton for Bison - -# Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -# 2007, 2008 Free Software Foundation, Inc. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Check the value of %define api.push_pull. -b4_percent_define_default([[api.push_pull]], [[pull]]) -b4_percent_define_check_values([[[[api.push_pull]], - [[pull]], [[push]], [[both]]]]) -b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]]) -b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]]) -m4_case(b4_percent_define_get([[api.push_pull]]), - [pull], [m4_define([b4_push_flag], [[0]])], - [push], [m4_define([b4_pull_flag], [[0]])]) - -# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing -# tests function as written, don't let BISON_USE_PUSH_FOR_PULL modify Bison's -# behavior at all when push parsing is already requested. -b4_define_flag_if([use_push_for_pull]) -b4_use_push_for_pull_if([ - b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])], - [m4_define([b4_push_flag], [[1]])])]) - -m4_include(b4_pkgdatadir/[c.m4]) - -## ---------------- ## -## Default values. ## -## ---------------- ## - -# Stack parameters. -m4_define_default([b4_stack_depth_max], [10000]) -m4_define_default([b4_stack_depth_init], [200]) - - -## ------------------------ ## -## Pure/impure interfaces. ## -## ------------------------ ## - -b4_percent_define_default([[api.pure]], [[false]]) -b4_define_flag_if([pure]) -m4_define([b4_pure_flag], - [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])]) - -# b4_yacc_pure_if(IF-TRUE, IF-FALSE) -# ---------------------------------- -# Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise. -m4_define([b4_yacc_pure_if], -[b4_pure_if([m4_ifset([b4_parse_param], - [$1], [$2])], - [$2])]) - - -# b4_yyerror_args -# --------------- -# Arguments passed to yyerror: user args plus yylloc. -m4_define([b4_yyerror_args], -[b4_yacc_pure_if([b4_locations_if([&yylloc, ])])dnl -m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])]) - - -# b4_lex_param -# ------------ -# Accumulate in b4_lex_param all the yylex arguments. -# b4_lex_param arrives quoted twice, but we want to keep only one level. -m4_define([b4_lex_param], -m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl -b4_locations_if([, [[YYLTYPE *], [&yylloc]]])m4_ifdef([b4_lex_param], [, ])])dnl -m4_ifdef([b4_lex_param], b4_lex_param))) - - -## ------------ ## -## Data Types. ## -## ------------ ## - -# b4_int_type(MIN, MAX) -# --------------------- -# Return the smallest int type able to handle numbers ranging from -# MIN to MAX (included). Overwrite the version from c.m4, which -# uses only C89 types, so that the user can override the shorter -# types, and so that pre-C89 compilers are handled correctly. -m4_define([b4_int_type], -[m4_if(b4_ints_in($@, [0], [255]), [1], [yytype_uint8], - b4_ints_in($@, [-128], [127]), [1], [yytype_int8], - - b4_ints_in($@, [0], [65535]), [1], [yytype_uint16], - b4_ints_in($@, [-32768], [32767]), [1], [yytype_int16], - - m4_eval([0 <= $1]), [1], [unsigned int], - - [int])]) - - -## ----------------- ## -## Semantic Values. ## -## ----------------- ## - - -# b4_lhs_value([TYPE]) -# -------------------- -# Expansion of $$. -m4_define([b4_lhs_value], -[(yyval[]m4_ifval([$1], [.$1]))]) - - -# b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) -# -------------------------------------- -# Expansion of $NUM, where the current rule has RULE-LENGTH -# symbols on RHS. -m4_define([b4_rhs_value], -[(yyvsp@{($2) - ($1)@}m4_ifval([$3], [.$3]))]) - - - -## ----------- ## -## Locations. ## -## ----------- ## - -# b4_lhs_location() -# ----------------- -# Expansion of @$. -m4_define([b4_lhs_location], -[(yyloc)]) - - -# b4_rhs_location(RULE-LENGTH, NUM) -# --------------------------------- -# Expansion of @NUM, where the current rule has RULE-LENGTH symbols -# on RHS. -m4_define([b4_rhs_location], -[(yylsp@{($2) - ($1)@})]) - - - -## --------------------------------------------------------- ## -## Defining symbol actions, e.g., printers and destructors. ## -## --------------------------------------------------------- ## - -# We do want M4 expansion after # for CPP macros. -m4_changecom() -m4_divert_push(0)dnl -@output(b4_parser_file_name@) -b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl ' - [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])[ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -]b4_identification -b4_percent_code_get([[top]])[]dnl -m4_if(b4_prefix, [yy], [], -[[/* Substitute the variable and function names. */ -]b4_pull_if([[#define yyparse ]b4_prefix[parse -]])b4_push_if([[#define yypush_parse ]b4_prefix[push_parse -]b4_pull_if([[#define yypull_parse ]b4_prefix[pull_parse -]])[#define yypstate_new ]b4_prefix[pstate_new -#define yypstate_delete ]b4_prefix[pstate_delete -#define yypstate ]b4_prefix[pstate -]])[#define yylex ]b4_prefix[lex -#define yyerror ]b4_prefix[error -#define yylval ]b4_prefix[lval -#define yychar ]b4_prefix[char -#define yydebug ]b4_prefix[debug -#define yynerrs ]b4_prefix[nerrs -]b4_locations_if([[#define yylloc ]b4_prefix[lloc]])])[ - -/* Copy the first part of user declarations. */ -]b4_user_pre_prologue[ - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG ]b4_debug_flag[ -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE ]b4_error_verbose_flag[ -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE ]b4_token_table[ -#endif - -]b4_percent_code_get([[requires]])[]dnl - -b4_token_enums_defines(b4_tokens)[ - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -]m4_ifdef([b4_stype], -[[typedef union ]b4_union_name[ -{ -]b4_user_stype[ -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1]], -[m4_if(b4_tag_seen_flag, 0, -[[typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1]])])[ -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif]b4_locations_if([[ - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif]])b4_push_if([[ - -#ifndef YYPUSH_DECLS -# define YYPUSH_DECLS -struct yypstate; -typedef struct yypstate yypstate; -enum { YYPUSH_MORE = 4 }; - -]b4_pull_if([b4_c_function_decl([[yyparse]], [[int]], b4_parse_param) -])b4_c_function_decl([[yypush_parse]], [[int]], - [[[yypstate *yyps]], [[yyps]]]b4_pure_if([, - [[[int yypushed_char]], [[yypushed_char]]], - [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, - [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, - b4_parse_param])) -b4_pull_if([b4_c_function_decl([[yypull_parse]], [[int]], - [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [, - b4_parse_param]))]) -b4_c_function_decl([[yypstate_new]], [[yypstate *]], [[[void]], []]) -b4_c_function_decl([[yypstate_delete]], [[void]], - [[[yypstate *yyps]], [[yyps]]])[ -#endif]]) - -b4_percent_code_get([[provides]])[]dnl - -[/* Copy the second part of user declarations. */ -]b4_user_post_prologue -b4_percent_code_get[]dnl - -[#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif ]b4_c_modern[ -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && ]b4_c_modern[ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -]b4_c_function_def([YYID], [static int], [[int yyi], [yyi]])[ -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -]b4_push_if([], -[[/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && ]b4_c_modern[ -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -]])dnl -[# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && ]b4_c_modern[ -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && ]b4_c_modern[ -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc;]b4_locations_if([ - YYLTYPE yyls_alloc;])[ -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -]b4_locations_if( -[# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM)], -[# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM)])[ - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL ]b4_final_state_number[ -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST ]b4_last[ - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS ]b4_tokens_number[ -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS ]b4_nterms_number[ -/* YYNRULES -- Number of rules. */ -#define YYNRULES ]b4_rules_number[ -/* YYNRULES -- Number of states. */ -#define YYNSTATES ]b4_states_number[ - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK ]b4_undef_token_number[ -#define YYMAXUTOK ]b4_user_token_number_max[ - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const ]b4_int_type_for([b4_translate])[ yytranslate[] = -{ - ]b4_translate[ -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const ]b4_int_type_for([b4_prhs])[ yyprhs[] = -{ - ]b4_prhs[ -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const ]b4_int_type_for([b4_rhs])[ yyrhs[] = -{ - ]b4_rhs[ -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const ]b4_int_type_for([b4_rline])[ yyrline[] = -{ - ]b4_rline[ -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - ]b4_tname[ -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const ]b4_int_type_for([b4_toknum])[ yytoknum[] = -{ - ]b4_toknum[ -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const ]b4_int_type_for([b4_r1])[ yyr1[] = -{ - ]b4_r1[ -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const ]b4_int_type_for([b4_r2])[ yyr2[] = -{ - ]b4_r2[ -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const ]b4_int_type_for([b4_defact])[ yydefact[] = -{ - ]b4_defact[ -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const ]b4_int_type_for([b4_defgoto])[ yydefgoto[] = -{ - ]b4_defgoto[ -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF ]b4_pact_ninf[ -static const ]b4_int_type_for([b4_pact])[ yypact[] = -{ - ]b4_pact[ -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] = -{ - ]b4_pgoto[ -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF ]b4_table_ninf[ -static const ]b4_int_type_for([b4_table])[ yytable[] = -{ - ]b4_table[ -}; - -static const ]b4_int_type_for([b4_check])[ yycheck[] = -{ - ]b4_check[ -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const ]b4_int_type_for([b4_stos])[ yystos[] = -{ - ]b4_stos[ -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM) -#else -# define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[ -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value]b4_locations_if([, Location])[]b4_user_args[); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - -]b4_yy_symbol_print_generate([b4_c_function_def])[ - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -]b4_c_function_def([yy_stack_print], [static void], - [[yytype_int16 *yybottom], [yybottom]], - [[yytype_int16 *yytop], [yytop]])[ -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -]b4_c_function_def([yy_reduce_print], [static void], - [[YYSTYPE *yyvsp], [yyvsp]], - b4_locations_if([[[YYLTYPE *yylsp], [yylsp]], - ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [, - b4_parse_param]))[ -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &]b4_rhs_value(yynrhs, yyi + 1)[ - ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl - b4_user_args[); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH ]b4_stack_depth_init[ -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH ]b4_stack_depth_max[ -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -]b4_c_function_def([yystrlen], [static YYSIZE_T], - [[const char *yystr], [yystr]])[ -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -]b4_c_function_def([yystpcpy], [static char *], - [[char *yydest], [yydest]], [[const char *yysrc], [yysrc]])[ -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -]b4_yydestruct_generate([b4_c_function_def])[ - -]b4_push_if([], -[[/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -]b4_c_function_decl([yyparse], [int], - [[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[ -#else /* ! YYPARSE_PARAM */ -]b4_c_function_decl([yyparse], [int], b4_parse_param)[ -#endif /* ! YYPARSE_PARAM */]]) - -m4_divert_push([KILL])# ======================== M4 code. -# b4_declare_scanner_communication_variables -# ------------------------------------------ -# Declare the variables that are global, or local to YYPARSE if -# pure-parser. -m4_define([b4_declare_scanner_communication_variables], -[[/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -]b4_locations_if([[ -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; -]])b4_pure_if([], [[ -/* Number of syntax errors so far. */ -int yynerrs; -]])]) - -# b4_declare_parser_state_variables -# --------------------------------- -# Declare all the variables that are needed to maintain the parser state -# between calls to yypush_parse. -m4_define([b4_declare_parser_state_variables], -[b4_pure_if([[ /* Number of syntax errors so far. */ - int yynerrs; -]])[ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values.]b4_locations_if([[ - `yyls': related to locations.]])[ - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; -]b4_locations_if([[ - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; -]])[ - YYSIZE_T yystacksize; -]]) - -m4_divert_pop([KILL])dnl# ====================== End of M4 code. - -b4_pure_if([], [b4_declare_scanner_communication_variables]) - -b4_push_if( -[[struct yypstate - { - ]b4_declare_parser_state_variables[ - /* Used to determine if this is the first time this instance has - been used. */ - int yynew; - };]b4_pure_if([], [[ - -static char yypstate_allocated = 0;]])b4_pull_if([ - -b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[ -{ - return yypull_parse (0]m4_ifset([b4_parse_param], - [[, ]b4_c_args(b4_parse_param)])[); -} - -]b4_c_function_def([[yypull_parse]], [[int]], - [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [, - b4_parse_param]))[ -{ - int yystatus; - yypstate *yyps_local;]b4_pure_if([[ - int yychar; - YYSTYPE yylval;]b4_locations_if([[ - YYLTYPE yylloc;]])])[ - if (yyps == 0) - { - yyps_local = yypstate_new (); - if (!yyps_local) - {]b4_pure_if([[ - yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[ - if (!yypstate_allocated) - yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[ - return 2; - } - } - else - yyps_local = yyps; - do { - yychar = YYLEX; - yystatus = - yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[); - } while (yystatus == YYPUSH_MORE); - if (yyps == 0) - yypstate_delete (yyps_local); - return yystatus; -}]])[ - -/* Initialize the parser data structure. */ -]b4_c_function_def([[yypstate_new]], [[yypstate *]])[ -{ - yypstate *yyps;]b4_pure_if([], [[ - if (yypstate_allocated) - return 0;]])[ - yyps = (yypstate *) malloc (sizeof *yyps); - if (!yyps) - return 0; - yyps->yynew = 1;]b4_pure_if([], [[ - yypstate_allocated = 1;]])[ - return yyps; -} - -]b4_c_function_def([[yypstate_delete]], [[void]], - [[[yypstate *yyps]], [[yyps]]])[ -{ -#ifndef yyoverflow - /* If the stack was reallocated but the parse did not complete, then the - stack still needs to be freed. */ - if (!yyps->yynew && yyps->yyss != yyps->yyssa) - YYSTACK_FREE (yyps->yyss); -#endif - free (yyps);]b4_pure_if([], [[ - yypstate_allocated = 0;]])[ -} - -]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs -]])[#define yystate yyps->yystate -#define yyerrstatus yyps->yyerrstatus -#define yyssa yyps->yyssa -#define yyss yyps->yyss -#define yyssp yyps->yyssp -#define yyvsa yyps->yyvsa -#define yyvs yyps->yyvs -#define yyvsp yyps->yyvsp -]b4_locations_if([[#define yylsa yyps->yylsa -#define yyls yyps->yyls -#define yylsp yyps->yylsp -#define yyerror_range yyps->yyerror_range -]])[#define yystacksize yyps->yystacksize -]])[ -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ -]b4_push_if([ -b4_c_function_def([[yypush_parse]], [[int]], - [[[yypstate *yyps]], [[yyps]]]b4_pure_if([, - [[[int yypushed_char]], [[yypushed_char]]], - [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, - [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, - b4_parse_param]))], [ -#ifdef YYPARSE_PARAM -b4_c_function_def([yyparse], [int], [[void *YYPARSE_PARAM], [YYPARSE_PARAM]]) -#else /* ! YYPARSE_PARAM */ -b4_c_function_def([yyparse], [int], b4_parse_param) -#endif])[ -{ -]b4_pure_if([b4_declare_scanner_communication_variables]) -b4_push_if([b4_pure_if([], [[ int yypushed_char = yychar; - YYSTYPE yypushed_val = yylval; - ]b4_locations_if([[YYLTYPE yypushed_loc = yylloc; -]])])], - [b4_declare_parser_state_variables])[ - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval;]b4_locations_if([[ - YYLTYPE yyloc;]])[ - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0;]b4_push_if([[ - - if (!yyps->yynew) - { - yyn = yypact[yystate]; - goto yyread_pushed_token; - }]])[ - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa;]b4_locations_if([[ - yyls = yylsa;]])[ - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs;]b4_locations_if([[ - yylsp = yyls; - -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = ]b4_location_initial_line[; - yylloc.first_column = yylloc.last_column = ]b4_location_initial_column[; -#endif]]) -m4_ifdef([b4_initial_action],[ -m4_pushdef([b4_at_dollar], [m4_define([b4_at_dollar_used])yylloc])dnl -m4_pushdef([b4_dollar_dollar], [m4_define([b4_dollar_dollar_used])yylval])dnl -/* User initialization code. */ -b4_user_initial_action -m4_popdef([b4_dollar_dollar])dnl -m4_popdef([b4_at_dollar])])dnl -m4_ifdef([b4_dollar_dollar_used],[[ yyvsp[0] = yylval; -]])dnl -m4_ifdef([b4_at_dollar_used], [[ yylsp[0] = yylloc; -]])[ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss;]b4_locations_if([ - YYLTYPE *yyls1 = yyls;])[ - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([ - &yyls1, yysize * sizeof (*yylsp),])[ - &yystacksize); -]b4_locations_if([ - yyls = yyls1;])[ - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([ - YYSTACK_RELOCATE (yyls_alloc, yyls);])[ -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1;]b4_locations_if([ - yylsp = yyls + yysize - 1;])[ - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - {]b4_push_if([[ - if (!yyps->yynew) - {]b4_use_push_for_pull_if([], [[ - YYDPRINTF ((stderr, "Return for a new token:\n"));]])[ - yyresult = YYPUSH_MORE; - goto yypushreturn; - } - yyps->yynew = 0;]b4_pure_if([], [[ - /* Restoring the pushed token is only necessary for the first - yypush_parse invocation since subsequent invocations don't overwrite - it before jumping to yyread_pushed_token. */ - yychar = yypushed_char; - yylval = yypushed_val;]b4_locations_if([[ - yylloc = yypushed_loc;]])])[ -yyread_pushed_token:]])[ - YYDPRINTF ((stderr, "Reading a token: "));]b4_push_if([b4_pure_if([[ - yychar = yypushed_char; - if (yypushed_val) - yylval = *yypushed_val;]b4_locations_if([[ - if (yypushed_loc) - yylloc = *yypushed_loc;]])])], [[ - yychar = YYLEX;]])[ - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; -]b4_locations_if([ *++yylsp = yylloc;])[ - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -]b4_locations_if( -[[ /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);]])[ - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - ]b4_user_actions[ - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval;]b4_locations_if([ - *++yylsp = yyloc;])[ - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (]b4_yyerror_args[YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (]b4_yyerror_args[yymsg); - } - else - { - yyerror (]b4_yyerror_args[YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - -]b4_locations_if([[ yyerror_range[0] = yylloc;]])[ - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - -]b4_locations_if([[ yyerror_range[0] = yylsp[1-yylen]; -]])[ /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - -]b4_locations_if([[ yyerror_range[0] = *yylsp;]])[ - yydestruct ("Error: popping", - yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; -]b4_locations_if([[ - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc;]])[ - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (]b4_yyerror_args[YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -]b4_push_if([[ yyps->yynew = 1; - -yypushreturn: -]])[#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -]b4_epilogue -b4_defines_if( -[@output(b4_spec_defines_file@) -b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl ' - [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006]) - -b4_percent_code_get([[requires]])[]dnl - -b4_token_enums_defines(b4_tokens) - -[#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -]m4_ifdef([b4_stype], -[[typedef union ]b4_union_name[ -{ -]b4_user_stype[ -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1]], -[m4_if(b4_tag_seen_flag, 0, -[[typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1]])])[ -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval;]]) - -b4_locations_if( -[#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - -]b4_pure_if([], [[extern YYLTYPE ]b4_prefix[lloc;]]) -)dnl b4_locations_if -b4_push_if([[ -#ifndef YYPUSH_DECLS -# define YYPUSH_DECLS -struct ]b4_prefix[pstate; -typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; -enum { YYPUSH_MORE = 4 }; -]b4_pull_if([b4_c_function_decl([b4_prefix[parse]], [[int]], b4_parse_param) -])b4_c_function_decl([b4_prefix[push_parse]], [[int]], - [[b4_prefix[pstate *yyps]], [[yyps]]]b4_pure_if([, - [[[int yypushed_char]], [[yypushed_char]]], - [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([, - [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [, - b4_parse_param])) -b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]], - [[b4_prefix[pstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [, - b4_parse_param]))]) -b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]], - [[[void]], []]) -b4_c_function_decl([b4_prefix[pstate_delete]], [[void]], - [[b4_prefix[pstate *yyps]], [[yyps]]])[ -#endif -]]) -b4_percent_code_get([[provides]])[]dnl -])dnl b4_defines_if -m4_divert_pop(0) diff --git a/share/locale/da/LC_MESSAGES/bison-runtime.mo b/share/locale/da/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 03bb961..0000000 Binary files a/share/locale/da/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/da/LC_MESSAGES/bison.mo b/share/locale/da/LC_MESSAGES/bison.mo deleted file mode 100644 index e62a784..0000000 Binary files a/share/locale/da/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/de/LC_MESSAGES/bison-runtime.mo b/share/locale/de/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 178fc68..0000000 Binary files a/share/locale/de/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/de/LC_MESSAGES/bison.mo b/share/locale/de/LC_MESSAGES/bison.mo deleted file mode 100644 index c1783d0..0000000 Binary files a/share/locale/de/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/el/LC_MESSAGES/bison-runtime.mo b/share/locale/el/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 912b59b..0000000 Binary files a/share/locale/el/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/el/LC_MESSAGES/bison.mo b/share/locale/el/LC_MESSAGES/bison.mo deleted file mode 100644 index 0ba96cc..0000000 Binary files a/share/locale/el/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/es/LC_MESSAGES/bison-runtime.mo b/share/locale/es/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 5723878..0000000 Binary files a/share/locale/es/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/es/LC_MESSAGES/bison.mo b/share/locale/es/LC_MESSAGES/bison.mo deleted file mode 100644 index f85ef2c..0000000 Binary files a/share/locale/es/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/et/LC_MESSAGES/bison-runtime.mo b/share/locale/et/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index cb35876..0000000 Binary files a/share/locale/et/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/et/LC_MESSAGES/bison.mo b/share/locale/et/LC_MESSAGES/bison.mo deleted file mode 100644 index a3c20ba..0000000 Binary files a/share/locale/et/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/fi/LC_MESSAGES/bison-runtime.mo b/share/locale/fi/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index c5ea804..0000000 Binary files a/share/locale/fi/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/fr/LC_MESSAGES/bison-runtime.mo b/share/locale/fr/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 11c009e..0000000 Binary files a/share/locale/fr/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/fr/LC_MESSAGES/bison.mo b/share/locale/fr/LC_MESSAGES/bison.mo deleted file mode 100644 index 9101933..0000000 Binary files a/share/locale/fr/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/ga/LC_MESSAGES/bison-runtime.mo b/share/locale/ga/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 6b4fec2..0000000 Binary files a/share/locale/ga/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ga/LC_MESSAGES/bison.mo b/share/locale/ga/LC_MESSAGES/bison.mo deleted file mode 100644 index 6d8783c..0000000 Binary files a/share/locale/ga/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/hr/LC_MESSAGES/bison-runtime.mo b/share/locale/hr/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index bf3cf01..0000000 Binary files a/share/locale/hr/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/hr/LC_MESSAGES/bison.mo b/share/locale/hr/LC_MESSAGES/bison.mo deleted file mode 100644 index f01f2d7..0000000 Binary files a/share/locale/hr/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/id/LC_MESSAGES/bison-runtime.mo b/share/locale/id/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 649f2d9..0000000 Binary files a/share/locale/id/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/id/LC_MESSAGES/bison.mo b/share/locale/id/LC_MESSAGES/bison.mo deleted file mode 100644 index 54f1438..0000000 Binary files a/share/locale/id/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/it/LC_MESSAGES/bison-runtime.mo b/share/locale/it/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 463e291..0000000 Binary files a/share/locale/it/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/it/LC_MESSAGES/bison.mo b/share/locale/it/LC_MESSAGES/bison.mo deleted file mode 100644 index 09771eb..0000000 Binary files a/share/locale/it/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/ja/LC_MESSAGES/bison-runtime.mo b/share/locale/ja/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index d11de40..0000000 Binary files a/share/locale/ja/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ja/LC_MESSAGES/bison.mo b/share/locale/ja/LC_MESSAGES/bison.mo deleted file mode 100644 index c28966a..0000000 Binary files a/share/locale/ja/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/ky/LC_MESSAGES/bison-runtime.mo b/share/locale/ky/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 4185d05..0000000 Binary files a/share/locale/ky/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/lt/LC_MESSAGES/bison-runtime.mo b/share/locale/lt/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 16ac4d1..0000000 Binary files a/share/locale/lt/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ms/LC_MESSAGES/bison-runtime.mo b/share/locale/ms/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 87905ba..0000000 Binary files a/share/locale/ms/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ms/LC_MESSAGES/bison.mo b/share/locale/ms/LC_MESSAGES/bison.mo deleted file mode 100644 index ed59d88..0000000 Binary files a/share/locale/ms/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/nb/LC_MESSAGES/bison-runtime.mo b/share/locale/nb/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index cff7d77..0000000 Binary files a/share/locale/nb/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/nb/LC_MESSAGES/bison.mo b/share/locale/nb/LC_MESSAGES/bison.mo deleted file mode 100644 index 3bcf649..0000000 Binary files a/share/locale/nb/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/nl/LC_MESSAGES/bison-runtime.mo b/share/locale/nl/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 7b2f24c..0000000 Binary files a/share/locale/nl/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/nl/LC_MESSAGES/bison.mo b/share/locale/nl/LC_MESSAGES/bison.mo deleted file mode 100644 index da4de8e..0000000 Binary files a/share/locale/nl/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/pl/LC_MESSAGES/bison-runtime.mo b/share/locale/pl/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 30822a5..0000000 Binary files a/share/locale/pl/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/pl/LC_MESSAGES/bison.mo b/share/locale/pl/LC_MESSAGES/bison.mo deleted file mode 100644 index 7b6fae2..0000000 Binary files a/share/locale/pl/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/pt_BR/LC_MESSAGES/bison-runtime.mo b/share/locale/pt_BR/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 1e72485..0000000 Binary files a/share/locale/pt_BR/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/pt_BR/LC_MESSAGES/bison.mo b/share/locale/pt_BR/LC_MESSAGES/bison.mo deleted file mode 100644 index b579bbb..0000000 Binary files a/share/locale/pt_BR/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/ro/LC_MESSAGES/bison-runtime.mo b/share/locale/ro/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index aaff454..0000000 Binary files a/share/locale/ro/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ro/LC_MESSAGES/bison.mo b/share/locale/ro/LC_MESSAGES/bison.mo deleted file mode 100644 index 76d6c87..0000000 Binary files a/share/locale/ro/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/ru/LC_MESSAGES/bison-runtime.mo b/share/locale/ru/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 189d7dd..0000000 Binary files a/share/locale/ru/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/ru/LC_MESSAGES/bison.mo b/share/locale/ru/LC_MESSAGES/bison.mo deleted file mode 100644 index 7e16fad..0000000 Binary files a/share/locale/ru/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/sl/LC_MESSAGES/bison-runtime.mo b/share/locale/sl/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index fd1b5d2..0000000 Binary files a/share/locale/sl/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/sv/LC_MESSAGES/bison-runtime.mo b/share/locale/sv/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 51d4b15..0000000 Binary files a/share/locale/sv/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/sv/LC_MESSAGES/bison.mo b/share/locale/sv/LC_MESSAGES/bison.mo deleted file mode 100644 index d00a9e2..0000000 Binary files a/share/locale/sv/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/th/LC_MESSAGES/bison-runtime.mo b/share/locale/th/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 537a09b..0000000 Binary files a/share/locale/th/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/tr/LC_MESSAGES/bison-runtime.mo b/share/locale/tr/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index e338912..0000000 Binary files a/share/locale/tr/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/tr/LC_MESSAGES/bison.mo b/share/locale/tr/LC_MESSAGES/bison.mo deleted file mode 100644 index 17e87fe..0000000 Binary files a/share/locale/tr/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/uk/LC_MESSAGES/bison-runtime.mo b/share/locale/uk/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index a0323a5..0000000 Binary files a/share/locale/uk/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/uk/LC_MESSAGES/bison.mo b/share/locale/uk/LC_MESSAGES/bison.mo deleted file mode 100644 index b41d6f3..0000000 Binary files a/share/locale/uk/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/vi/LC_MESSAGES/bison-runtime.mo b/share/locale/vi/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 7e650d7..0000000 Binary files a/share/locale/vi/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/vi/LC_MESSAGES/bison.mo b/share/locale/vi/LC_MESSAGES/bison.mo deleted file mode 100644 index d41ee57..0000000 Binary files a/share/locale/vi/LC_MESSAGES/bison.mo and /dev/null differ diff --git a/share/locale/zh_CN/LC_MESSAGES/bison-runtime.mo b/share/locale/zh_CN/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index b099838..0000000 Binary files a/share/locale/zh_CN/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/zh_TW/LC_MESSAGES/bison-runtime.mo b/share/locale/zh_TW/LC_MESSAGES/bison-runtime.mo deleted file mode 100644 index 243f5aa..0000000 Binary files a/share/locale/zh_TW/LC_MESSAGES/bison-runtime.mo and /dev/null differ diff --git a/share/locale/zh_TW/LC_MESSAGES/bison.mo b/share/locale/zh_TW/LC_MESSAGES/bison.mo deleted file mode 100644 index 9c01484..0000000 Binary files a/share/locale/zh_TW/LC_MESSAGES/bison.mo and /dev/null differ