pax_global_header00006660000000000000000000000064141570007440014514gustar00rootroot0000000000000052 comment=ce3e080c0e82335e8bf6bbb61dbcbd8b52a66623 ksh-1.0.0-beta.2/000077500000000000000000000000001415700074400133505ustar00rootroot00000000000000ksh-1.0.0-beta.2/.github/000077500000000000000000000000001415700074400147105ustar00rootroot00000000000000ksh-1.0.0-beta.2/.github/workflows/000077500000000000000000000000001415700074400167455ustar00rootroot00000000000000ksh-1.0.0-beta.2/.github/workflows/ci.yml000066400000000000000000000020401415700074400200570ustar00rootroot00000000000000name: CI on: [push] jobs: Linux: name: Linux runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v2 - name: Build run: bin/package make - name: Regression tests run: | PS4="$PS4[ci.yml] " set -o xtrace export TZ=UTC ulimit -n 1024 : default regression tests && script -q -e -c "bin/shtests" && : regression tests with OS-provided multibyte locales && LANG=nl_NL.UTF-8 script -q -e -c "bin/shtests --locale --nocompile" && LANG=ja_JP.SJIS script -q -e -c "bin/shtests --locale --nocompile" && : disable most SHOPTs, rebuild ksh && sed --regexp-extended --in-place=.orig \ '/^SHOPT (2DMATCH|AUDIT|BGX|BRACEPAT|DEVFD|DYNAMIC|EDPREDICT|ESH|FIXEDARRAY|HISTEXPAND|MULTIBYTE|NAMESPACE|OPTIMIZE|STATS|SUID_EXEC|VSH)=/ s/=1?/=0/' \ src/cmd/ksh93/SHOPT.sh && bin/package make && : default regression tests with SHOPTs disabled && script -q -e -c "bin/shtests" ksh-1.0.0-beta.2/.gitignore000066400000000000000000000014321415700074400153400ustar00rootroot00000000000000# Project-specific files arch tgz lcl # Flat make libs, binaries, etc /bin/.paths /bin/ar /bin/cc /bin/crossexec /bin/ditto /bin/filter /bin/hurl /bin/iffe /bin/ksh /bin/mamake /bin/mktest /bin/ok/ /bin/proto /bin/pty /bin/ratz /bin/regress /bin/release /bin/rt /bin/shcomp /bin/suid_exec /fun/ /include/ /lib/file/ /lib/lib/ /lib/libast.a /lib/libcmd.a /lib/libdll.a /lib/libshell.a /lib/libsum.a /lib/make/ /lib/package/gen/ /lib/probe/ /man/ # This one keeps changing its license header, causing git to show an # uncommitted file. It's always re-copied anyway, and not for direct # invocation, so exclude. The source file is: src/cmd/INIT/execrate.sh bin/execrate # Miscellaneous artefacts *.bak *.sav *.old *.orig .*.swp *.DS_Store *~ .nfs* *.tmp *.rej *.project *.core core **/#*# tags ksh-1.0.0-beta.2/ANNOUNCE000066400000000000000000000232741415700074400145110ustar00rootroot00000000000000Announcing: KornShell 93u+m 1.0.0-beta.2 https://github.com/ksh93/ksh In May 2020, when every KornShell (ksh93) development project was abandoned, development was rebooted in a new fork based on the last stable AT&T version: ksh 93u+. This new fork is called ksh 93u+m as a permanent nod to its origin. We're restarting it at version 1.0. Seven months after the first beta, the second one is ready. Please test this second beta and report any bugs you find, or help us fix known bugs. We're now the default ksh93 in some OS distributions, at least Debian and Slackware! Even though we don't think it's stable release quality yet, the consensus seems to be that 93u+m is already much better than the last AT&T release. Main developers: Martijn Dekker, Johnothan King, hyenias Contributors: Andy Fiddaman, Anuradha Weeraman, Chase, Gordon Woodhull, Govind Kamat, Harald van Dijk, Lev Kujawski, Marc Wilson, Ryan Schmidt, Sterling Jensen HOW TO GET IT Please download the source code tarball from our GitHub releases page: https://github.com/ksh93/ksh/releases To build, follow the instructions in README.md or src/cmd/ksh93/README. HOW TO GET INVOLVED To report a bug, please open an issue at our GitHub page (see above). Alternatively, email me at martijn@inlv.org with your report. To get involved in development, read the brief policy information in README.md and then jump right in with a pull request or email a patch. See the TODO file in the top-level directory for a to-do list. ### MAIN CHANGES between 1.0.0-beta.1 and 1.0.0-beta.2 ### New features in built-in commands: - 'cd' now supports an -e option that, when combined with -P, verifies that $PWD is correct after changing directories; this helps detect access permission problems. See: https://www.austingroupbugs.net/view.php?id=253 - 'printf' now supports a -v option as in bash. This assigns formatted output directly to variables, which is very fast and will not strip final newline (\n) characters. - The 'return' command, when used to return from a function, can now return any status value in the 32-bit signed integer range, like on zsh. However, due to a traditional Unix kernel limitation, $? is still trimmed to its least significant 8 bits whenever leaving a (sub)shell environment. - 'test'/'[' now supports all the same operators as [[ (including =~, \<, \>) except for the different 'and'/'or' operators. Note that 'test'/'[' remains deprecated due to its unfixable pitfalls; [[ ... ]] is recommended instead. Shell language changes: - Several improvements were made to the --noexec shell code linter. - Arithmetic expressions in native ksh mode no longer interpret a number with a leading zero as octal in any context. Use 8#octalnumber instead (e.g. 8#400 == 256). Arithmetic expressions now also behave identically within and outside ((...)) and $((...)). - POSIX compatibility mode fixes (only applicable with the --posix shell option on): - A leading zero is now consistently recognised as introducing an octal number in all arithmetic contexts. - $((inf)) and $((nan)) are now interpreted as regular variables. - The '.' built-in no longer runs ksh functions and now only runs files. Bugs fixed: - '.' and '..' are now once again completed by tab completion. - If SIGINT is set to ignore, the interactive shell no longer exits on Ctrl+C. - ksh now builds and runs on Apple's new M1 hardware. - The 'return' and 'exit' commands no longer risk triggering actual signals by returning or exiting with a status > 256. - Ksh no longer behaves badly when parsing a type definition command ('typeset -T' or 'enum') without executing it or when executing it in a subshell. Types can now safely be defined in subshells and defined conditionally as in 'if condition; then enum ...; fi'. - Discipline functions, especially those applied to PS2 or .sh.tilde, will no longer crash your shell upon being interrupted or throwing an error. - Fixed a bug that could corrupt output if standard output is closed upon initialising the shell. - Fixed a bug in the [[ ... ]] compound command: the '!' logical negation operator now correctly negates another '!', e.g., [[ ! ! 1 -eq 1 ]] now returns 0/true. Note that this has always been the case for 'test'/'['. - Fixed SHLVL so that replacing ksh by itself (exec ksh) will not increase it. - Arithmetic expressions are no longer allowed to assign out-of-range values to variables of types declared with enum. - The 'time' keyword no longer makes the --errexit shell option ineffective. - Various bugs in libcmd built-in commands (those bound to the /opt/ast/bin path by default) have been fixed. - Various other crashing bugs have been fixed. Fixes for the shcomp byte code compiler: - shcomp is now able to compile scripts that define types using enum. - shcomp now refuses to mess up your terminal by writing bytecode to it. ### MAIN CHANGES between ksh 93u+ 2012-08-01 and 93u+m 1.0.0-beta.1 ### Hundreds of bugs have been fixed, including many serious/critical bugs. This includes upstreamed patches from OpenSUSE, Red Hat, and Solaris, fixes backported from the abandoned 93v- beta and ksh2020 fork, as well as many new fixes from the community. See the NEWS file for more information, and the git commit log for complete documentation of every fix. Incompatible changes have been minimised, but not at the expense of fixing bugs. For a list of potentially incompatible changes, see src/cmd/ksh93/COMPATIBILITY. Though there was a "no new features, bugfixes only" policy, some new features were found necessary, either to fix serious design flaws or to complete functionality that was evidently intended, but not finished. Below is a summary of these new features. New command line editor features: - The forward-delete and End keys are now handled as expected in the emacs and vi built-in line editors. - In the vi and emacs line editors, repeat count parameters can now also be used for the arrow keys and the forward-delete key. E.g., in emacs mode, 7 will now move the cursor seven positions to the left. In vi control mode, this would be entered as: 7 . New shell language features: - The &>file redirection shorthand (for >file 2>&1) is now available for all scripts and interactive sessions and not only for profile/login scripts, bringing ksh 93u+m in line with mksh, bash, and zsh. - File name generation (a.k.a. pathname expansion, a.k.a. globbing) now never matches the special navigational names '.' (current directory) and '..' (parent directory). This change makes a pattern like .* useful; it now matches all hidden files (dotfiles) in the current directory, without the harmful inclusion of '.' and '..'. - Tilde expansion can now be extended or modified by defining a .sh.tilde.get or .sh.tilde.set discipline function. This replaces a 2004 undocumented attempt to add this functionality via a .sh.tilde command, which never worked and crashed the shell. See the manual for details on the new method. New features in built-in commands: - Usage error messages now show the --help/--man self-documentation options. - Path-bound built-ins (such as /opt/ast/bin/cat) can now be executed by invoking the canonical path, so the following will now work as expected: $ /opt/ast/bin/cat --version version cat (AT&T Research) 2012-05-31 - 'command -x' now looks for external commands only, skipping built-ins. In addition, its xargs-like functionality no longer freezes the shell on Linux and macOS, making it effectively a new feature on these systems. - 'redirect' now checks if all arguments are valid redirections before performing them. If an error occurs, it issues an error message instead of terminating the shell. - 'suspend' now refuses to suspend a login shell, as there is probably no parent shell to return to and the login session would freeze. - 'times' now gives high precision output in a POSIX compliant format. - 'typeset' now gives an informative error message if an incompatible combination of options is given. - 'whence -v/-a' now reports the location of autoloadable functions. New features in shell options: - A new --globcasedetect shell option is added on OSs where we can check for a case-insensitive file system (currently Windows/Cygwin, macOS, Linux and QNX 7.0+). When this option is turned on, file name generation (globbing), as well as file name tab completion on interactive shells, automatically become case-insensitive on file systems where the difference between upper and lower case is ignored for file names. This is transparently determined for each directory, so a path pattern that spans multiple file systems can be part case-sensitive and part case-insensitive. - A new --nobackslashctrl shell option disables the special escaping behaviour of the backslash character in the emacs and vi built-in editors. Particularly in the emacs editor, this makes it much easier to go backward, insert a forgotten backslash into a command, and then continue editing without having your next cursor key replace your backslash with garbage. Note that Ctrl+V (or whatever other character was set using 'stty lnext') always escapes all control characters in either editing mode. - A new --posix shell option has been added to ksh 93u+m that makes the ksh language more compatible with other shells by following the POSIX standard more closely. See the manual page for details. It is enabled by default if ksh is invoked as sh, otherwise it is disabled by default. - Enhancement to -G/--globstar: symbolic links to directories are now followed if they match a normal (non-**) glob pattern. For example, if '/lnk' is a symlink to a directory, '/lnk/**' and '/l?k/**' now work as you would expect. ksh-1.0.0-beta.2/COPYRIGHT000066400000000000000000000331771415700074400146560ustar00rootroot00000000000000ksh 93u+m general copyright notice ######################################################################## # # # The KornShell 93u+m distribution # # Copyright (c) 2021 Contributors to ksh 93u+m # # # # Derived from AT&T's ast package (see below) # # Licensed under the Eclipse Public License, Version 1.0 # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # CONTRIBUTORS # # # # Martijn Dekker # # Johnothan King # # hyenias <58673227+hyenias@users.noreply.github.com> # # Anuradha Weeraman # # Chase # # Govind Kamat # # Harald van Dijk # # Lev Kujawski # # Marc Wilson # # # ######################################################################## ast package general copyright notice ######################################################################## # # # This software is part of the ast package # # Copyright (c) 1986-2014 AT&T Intellectual Property # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # CONTRIBUTORS # # # # Glenn Fowler # # David Korn # # Phong Vo # # Adam Edgar # # Adam Buchsbaum # # Aman Shaikh # # Bala Krishnamurthy # # Brian Russell # # Robin Chen # # Don Caldwell # # Lefty Koutsofios # # Bob Gruber # # Jia Wang # # Jeff Fellin # # Jeff Korn <@google.com> # # Kathleen Fisher # # Ken Church <@microsoft.com> # # Brian Kernigham # # Dennis Ritchie # # Doug McIlroy # # Eduardo Krell # # John Snyder # # Herman Rao # # AST users mailgroup # # AST developers mailgroup # # # ######################################################################## bsd package general copyright notice ######################################################################## # # # This software is part of the BSD package # # Copyright (c) 1979-2012 The Regents of the University of California # # # # 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. # # # # 3. Neither the name of The Regents of the University of California# # names of its contributors may be used to endorse or # # promote products derived from this software without # # specific prior written permission. # # # # 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 OWNER 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. # # # # 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. # # 3. Neither the name of the University nor the names of its # # contributors may be used to endorse or promote products derived # # from this software without specific prior written permission. # # # # THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS # # 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. # # # # CONTRIBUTORS # # # # Bill Joy # # # ######################################################################## zlib package general copyright notice ######################################################################## # # # This software is part of the zlib package # # Copyright (c) 1995-2012 Jean-loup Gailly and Mark Adler # # # # This software is provided 'as-is', without any express or implied # # warranty. In no event will the authors be held liable for any # # damages arising from the use of this software. # # # # Permission is granted to anyone to use this software for any # # purpose, including commercial applications, and to alter it and # # redistribute it freely, subject to the following restrictions: # # # # 1. The origin of this software must not be misrepresented; # # you must not claim that you wrote the original software. If # # you use this software in a product, an acknowledgment in the # # product documentation would be appreciated but is not # # required. # # # # 2. Altered source versions must be plainly marked as such, # # and must not be misrepresented as being the original # # software. # # # # 3. This notice may not be removed or altered from any source # # distribution. # # # # This software is provided "as-is", without any express or implied # # warranty. In no event will the authors be held liable for any damages# # arising from the use of this software. # # # # Permission is granted to anyone to use this software for any purpose,# # including commercial applications, and to alter it and redistribute i# # freely, subject to the following restrictions: # # # # 1. The origin of this software must not be misrepresented; you must n# # claim that you wrote the original software. If you use this softwa# # in a product, an acknowledgment in the product documentation would# # be appreciated but is not required. # # # # 2. Altered source versions must be plainly marked as such, and must n# # be misrepresented as being the original software. # # # # 3. This notice may not be removed or altered from any source # # distribution. # # # # CONTRIBUTORS # # # # Jean-loup Gailly # # Mark Adler # # # ######################################################################## ksh-1.0.0-beta.2/LICENSE.md000066400000000000000000000260201415700074400147540ustar00rootroot00000000000000## Eclipse Public License - v 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. ### 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. ### 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. ### 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. ### 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. ### 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. ### 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ### 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. ksh-1.0.0-beta.2/NEWS000066400000000000000000002005661415700074400140600ustar00rootroot00000000000000This documents significant changes in the 93u+m branch of AT&T ksh93. For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. 2021-12-17: - Release 1.0.0-beta.2. - Ksh no longer behaves badly when parsing a type definition command ('typeset -T' or 'enum') without executing it or when executing it in a subshell. Types can now safely be defined in subshells and defined conditionally as in 'if condition; then enum ...; fi'. - Single digits can now be compared lexically in [[ ... ]] with the < and > operators. 2021-12-16: - Changed the default selection of compiled-in /opt/ast/bin built-in libcmd command to: basename, cat, cp, cut, dirname, getconf, ln, mktemp, mv. Add /opt/ast/bin to your $PATH to use these. Type 'cp --man', etc. for info. - A bug introduced on 2020-09-17 was fixed that caused interactive ksh to exit if Ctrl+C was pressed while SIGINT was being ignored (as in "trap '' INT"). 2021-12-13: - Fixed a bug introduced on 2020-08-09 that prevented '.' and '..' from being completed when using file name tab completion. - Fixed a bug on illumos that caused the chown builtin to fail with 'Invalid argument' after failing to change the ownership of a file twice using an ID that doesn't exist in /etc/passwd. (Note that the chown builtin is not enabled by default.) 2021-12-11: - Fixed two more crashing bugs that occurred if ksh received a signal (such as SIGINT due to Ctrl+C) while the user is entering a multi-line command substitution in an interactive shell. - The shell linter's warning for variable expansion in ((...)) now tells the user which variable is causing performance degradation. - The shell linter now warns the user x=$((expr)) is slower than ((x=expr)) when assigning a value to a variable. 2021-12-09: - Increased the general robustness of discipline function handling, fixing crashing bugs with PS2.get() and .sh.tilde.get() disciplines, among others. - Fixed a crash that occurred on the interactive shell if the PS1 prompt contains multiple command substitutions and the user interrupts input while the shell is on a PS2 prompt waiting for the user to complete a command substitution of the form $( ... ). 2021-12-08: - Fixed: if a function returned with a status > 256 using the 'return' command and the return value corresponded to a value that could have resulted from a signal, and an EXIT trap was active, then the shell mistakenly issued that signal to itself. Depending on the signal, this could cause the shell to terminate ungracefully, e.g. 'return 267' caused SIGSEGV ("memory fault"). - For the 'return' built-in command, you can now freely specify any return value that fits in a signed integer, typically a 32-bit value. Note that $? is truncated to 8 bits when the current (sub)shell exits. - The head and tail builtins now correctly handle files that do not have an ending newline. (Note that the tail builtin is not compiled in by default.) 2021-12-05: - Fixed an issue on illumos that caused some parameters in the getconf builtin to fail. - The cd built-in command now supports a -e option (as specified in https://www.austingroupbugs.net/view.php?id=253). Passing -e alongside -P is used to guarantee the cd built-in returns with exit status 1 if the current working directory couldn't be determined after successfully changing the directory. 2021-12-01: - Fixed a memory fault that occurred when a discipline function exited with an error from a special builtin or when a discipline function exited because of a signal. 2021-11-29: - Fixed a memory fault that prevented ksh from functioning on ARM-based Macs. - A bug that caused the time keyword to override the errexit shell option has been fixed. - Fixed a crash that could occur when a KEYBD trap was set and a multi-line command substitution was input in an interactive shell. - The shell linter's warnings for obsolete arithmetic operators in [[ ... ]] and unnecessary variable expansion in ((...)) have been improved. 2021-11-24: - The --posix mode was amended to stop the '.' command (but not 'source') from looking up functions defined with the 'function' keyword. In the POSIX standard and on other shells, the '.' command finds only script files. - The rm built-in's -d/--directory option has been fixed. It now properly removes empty directories and refuses to remove non-empty directories (as specified in https://www.austingroupbugs.net/view.php?id=802). Note that the rm built-in command isn't compiled in by default. 2021-11-23: - A bug was fixed that allowed arithmetic expressions to assign out-of-range values to variables of an enumeration type defined with the 'enum' command, causing undefined behavior. Within arithmetic expressions, enumeration values translate to index numbers from 0 to the number of elements minus 1. That range is now checked for. Decimal fractions are ignored. 2021-11-21: - It is now possible to use types defined by 'enum' in contexts where the script is entirely parsed before (or without) being executed, such as dotted/sourced scripts and scripts compiled by shcomp. - Added support for the size mode to the stty(1) built-in. This mode is used to display the terminal's number of rows and columns. Note that the stty built-in is not compiled in by default. This can be changed by adding stty to the table of built-ins in src/cmd/ksh93/data/builtins.c. 2021-11-20: - Listing types with 'typeset -T' no longer displays incomplete versions of types created by the enum built-in. 2021-11-18: - The printf built-in command now supports a -v option as on bash and zsh. This allows you to assign formatted output directly to a variable. - Fixed a performance regression introduced on 2021-05-03 that caused the shbench[*] fibonacci benchmark to run slower. [*]: https://github.com/ksh-community/shbench 2021-11-16: - By default, arithmetic expressions in ksh no longer interpret a number with a leading zero as octal in any context. Use 8#octalnumber instead. Before, ksh would arbitrarily recognize the leading octal zero in some contexts but not others, e.g., both of: $ x=010; echo "$((x)), $(($x))" $ set -o letoctal; x=010; let y=$x z=010; echo "$y, $z" would output '10, 8'. These now output '10, 10' and '8, 8', respectively. Arithmetic expressions now also behave identically within and outside ((...)) and $((...)). Setting the --posix compliance option turns on the recognition of the leading octal zero for all arithmetic contexts. 2021-11-15: - In arithmetic evaluation, the --posix compliance option now disables the special floating point constants Inf and NaN so that $((inf)) and $((nan)) refer to the variables by those names as the standard requires. (BUG_ARITHNAN) - Fixed two file descriptor leaks in the hist builtin that occurred when the -s flag ran a command or encountered an error. 2021-11-14: - Fixed: ksh crashed after unsetting .sh.match and then matching a pattern. - Another test/[ fix: "test \( string1 -a string2 \)" and "test \( string1 -o string2 \)" no longer give an incorrect "argument expected" error message. 2021-11-13: - The test/[ built-in command now supports the '<' and '=~' operators from [[. As of now, test/[ supports the same operators as [[ except for the different and/or operators. Note: test/[ remains deprecated due to its many pitfalls. - The test/[ built-in command is fixed so that the binary -a (and) and -o (or) operators, as in [ "$a" -a "$b" ] or [ "$a" -o "$b" ], work even if "$a" is '!' or '('. To avoid breaking backwards compatibility with the nonstandard unary [ -a "$file" ] and [ -o "$option" ] operators in combination with '!' or parentheses, this fix is only activated if the posix option is on. 2021-11-07: - Fixed a bug that could corrupt output if standard output is closed upon initializing the shell. - Improved BUG_PUTIOERR fix (2020-05-14) with more error checking. On systems with the "disk full" error testing device /dev/full, an echo/print/printf to /dev/full now always yields a non-zero exit status. 2021-09-13: - Disable the POSIX arithmetic context while running a command substitution invoked from within an arithmetic expression. This fixes a bug that caused integer arguments with a leading zero to be incorrectly interpreted as octal numbers in non-POSIX arithmetic contexts within such command substitutions. 2021-09-12: - When invoking a script without an interpreter/hashbang path on Linux and macOS, ksh can now update 'ps' output to show longer command lines. 2021-08-13: - An issue was fixed that could cause old-style `backtick` command substitutions to hang in certain cases. 2021-06-03: - Fixed a bug in the [[ compound command: the '!' logical negation operator now correctly negates another '!', e.g., [[ ! ! 1 -eq 1 ]] now returns 0/true. Note that this has always been the case for 'test'/'['. 2021-05-18: - Fixed SHLVL so that replacing ksh by itself (exec ksh) will not increase it. - Fixed a regression introduced on 2020-08-05 that caused a non-interactive shell to exit if an I/O redirection of a function call encountered an error. 2021-05-13: - Fixed a bug with 'test -t 1' that was introduced on 2021-04-26: v=$(test -t 1 >/dev/tty && echo ok) did not assign 'ok' to v. 2021-05-10: - Release 1.0.0-beta.1. 2021-05-07: - Backported three ksh 93v- math.tab changes, allowing for an exp10() arithmetic function if one exists in the C library, a new float() function, and lastly an updated int() function that rounds to zero instead of being an alias to floor(). 2021-05-05: - Fixed: a preceding variable assignment like foo=bar in 'foo=bar command' (with no command arguments after 'command') incorrectly survived the 'command' regular built-in command invocation. - Fixed: 'command -p some_utility' intermittently failed to find the utility under certain conditions due to a memory corruption issue. 2021-05-03: - Subshells (even if non-forked) now keep a properly separated state of the pseudorandom generator used for $RANDOM, so that using $RANDOM in a non-forked subshell no longer influences a reproducible $RANDOM sequence in the parent environment. In addition, upon invoking a subshell, $RANDOM is now reseeded (as mksh and bash do). - Fixed program flow corruption that occurred in scripts on executing a background job in a nested subshell, as in ( ( simple_command & ) ). - Completed the 2021-04-30 fix for ${var'{}'} where is '-', '+', ':-' or ':+' by fixing a bug that caused an extra '}' to be output. - Following the resolution of Austin Group bug 1393[*] that is set to be included in the next version of the POSIX standard, the 'command' prefix in POSIX mode (set -o posix) no longer disables the declaration properties of declaration built-ins. This reverts a change introduced on 2020-09-11. [*] https://austingroupbugs.net/view.php?id=1393 - Fixed arithmetic assignment operations for multidimensional indexed arrays. 2021-04-30: - The emacs 'ESC .' (M-.) and vi '_' commands now take shell quoting into account when repeating a word from the previous command line. For example, if the previous command is 'ls Stairway\ To\ Heaven.mp3', then they now insert 'Stairway\ To\ Heaven.mp3' instead of 'Heaven.mp3'. Thanks to Govind Kamat. - Fixed a bug introduced on 2020-09-05 that caused "echo ${var:+'{}'}" to be misparsed. - Fixed: the effects of 'builtin', 'exec' and 'ulimit' leaked out of a parent virtual subshell if run from a ${ shared-state; } command substitution. 2021-04-26: - Fixed a bug introduced on 2021-02-20 in which a shared-state command substitution stopped sharing its state with the calling shell environment if it executed a command that locally redirected standard output. 2021-04-22: - shcomp (the shell bytecode compiler) was fixed to correctly compile process substitutions used as the file name to a redirection, as in 'cmd < <(cmd)'. - Fixed a bug introduced on 2020-07-13 that set LINENO to the wrong line number after leaving a virtual subshell in which LINENO had been unset. 2021-04-21: - Fixed a bug introduced on 2020-09-28 that caused an interactive ksh to exit if a profile script (such as ~/.kshrc) contains a syntax error. 2021-04-20: - Fixed three problems with the /opt/ast/bin/getconf built-in command: 1. The -l/--lowercase option did not change all variable names to lower case. 2. The -q/--quote option now quotes all string values. Previously, it only quoted string values that had a space or other non-shellsafe character. 3. The -c/--call, -n/--name and -s/--standard options matched all variable names provided by 'getconf -a', even if none were actual matches. - The readonly attribute of ksh variables is no longer imported from or exported to other ksh shell instances through the environment. 2021-04-16: - Fixed a bug in emacs mode: after using tab completion to complete the name of a directory, it was not possible to type numbers after the slash. - Fixed an optimization bug that caused the <>; redirection operator to fail when used with the last command in a -c script. 2021-04-14: - Path-bound built-ins (such as /opt/ast/bin/cat) can now be executed by invoking the canonical path, so the following will now work as expected: $ /opt/ast/bin/cat --version version cat (AT&T Research) 2012-05-31 $ (PATH=/opt/ast/bin:$PATH; "$(whence -p cat)" --version) version cat (AT&T Research) 2012-05-31 Non-canonical paths such as /opt/ast/./bin/cat will not find the built-ins. - Path-bound built-ins will now also be found on a PATH set locally using an assignment preceding the command, so the following will now work as expected: $ PATH=/opt/ast/bin cat --version version cat (AT&T Research) 2012-05-31 2021-04-13: - Fixed a few bugs that could cause ksh to show the wrong error message and/or return the wrong exit status if a command couldn't be executed. In scenarios where the command was found in the PATH but it was not executable, ksh now returns with exit status 126. Otherwise, ksh will return with exit status 127 (such as if the command isn't found or if the command name is too long). 2021-04-12: - Corrected a memory fault when an attempt was made to unset the default nameref KSH_VERSION from the shell environment prior to any other name reference variable creation or modification. 2021-04-11: - Fixed two related regressions introduced on 2020-06-16: 1. The += assignment failed to append the value of variables when used in an invocation-local scope. The following should print '5', but the regression resulted in '3' being printed instead: $ integer foo=2; foo+=3 command eval 'echo $foo' 3 2. Any += assignment used in an invocation-local scope could modify readonly variables. 2021-04-10: - Fixed: the internal count of the recursion level for arithmetic expressions was not reset when certain errors occurred in a virtual subshell. This could cause an erroneous "recursion to deep" error when a loop executed many subshells containing arithmetic expressions with errors, e.g. for testing. 2021-04-09: - Fixed a bug that caused ksh to enable -c during the shell's initialization if the only argument passed was --posix. - Fixed a related bug that caused 'set --posix' to leave the braceexpand and letoctal shell options unchanged. - Fixed a bug that caused 'set --default' to unset the restricted option in restricted shells. 2021-04-08: - Path-bound builtins will now be used by restricted shells if /opt/ast/bin is in the $PATH upon invoking the shell or before setting it to restricted. - Fixed a bug that caused "printf '%T\n' now" to ignore $LC_ALL and $LC_TIME if the current locale was previously set, unset then set again. 2021-04-07: - The $LC_TIME variable is now recognized by ksh and if set to an invalid locale will show an error. - Fixed BUG_CSUBSTDO: If standard output is closed before running a command substitution, redirecting any other file descriptor no longer closes standard output inside of the command substitution. 2021-04-05: - Fixed a regression, introduced in ksh 93t+ 2009-07-31, that caused a command like 'unset arr[3]' to unset not just element 3 of the array but all elements starting from 3, if a range expansion like ${arr[5..10]} was previously used. - Several fixes for arrays of a type created by 'enum' were backported from ksh 93v-, further to the two enum array fixes already applied on 2021-02-01: 1. The array[@]} expansion was fixed for associative arrays of an enum type. 2. Assignments now work correctly for all enum values for both indexed and associative arrays. 3. 'unset' will now completely unset an associative array of an enum type. 2021-04-04: - A bug was fixed that caused a broken prompt display upon redrawing the command line if the last line of the prompt includes an xterm escape sequence that is terminated by $'\a' (the bell character). - Harden readonly variables. Readonly variables or arrays no longer allow attribute changes which would otherwise allow their value to be altered. Expanded support for readonly variables within multidimensional arrays. 2021-04-03: - Fixed a bug that caused the uname builtin's -d option to change the output of the -o option. - Fixed a possible crash that could occur when showing the domain name with the uname builtin's -d option. 2021-03-31: - Fixed a bug that caused 'cd -' to ignore the current value of $OLDPWD when it's set to a different directory in a new scope. - Fixed a related bug that caused ksh to use the wrong value for $PWD when in a new scope. 2021-03-29: - Fixed an intermittent crash that could occur in vi mode when using the 'b' or 'B' commands to go back one word. 2021-03-27: - The 'test' builtin will now show an error message when given the invalid ']]' or '=~' operators; it also properly returns with exit status 2 now (instead of exit status 1). If the invalid operator is supported by [[ ... ]] (such as '=~'), test will now suggest the usage of [[ ... ]] instead. 2021-03-22: - A new --globcasedetect shell option is added to ksh on OSs where we can check for a case-insensitive file system (currently macOS, Windows/Cygwin, Linux and QNX 7.0+). When this option is turned on, file name generation (globbing), as well as file name tab completion on interactive shells, automatically become case-insensitive on file systems where the difference between upper- and lowercase is ignored for file names. This is transparently determined for each directory, so a path pattern that spans multiple file systems can be part case-sensitive and part case-insensitive. The option is not compiled into ksh on systems where we do not know of a method to check for file system case insensitivity. The shell option can be force-compiled by setting SHOPT_GLOBCASEDET to 1 in src/cmd/ksh93/SHOPT.sh, but it won't have any effect on non-supported systems, so this is not recommended. It can be removed from ksh by setting SHOPT_GLOBCASEDET to 0. 2021-03-17: - Fixed a bug with file name completion on the interactive shell in multibyte locales. Upon encountering two filenames with multibyte characters starting with the same byte, a partial multibyte character was autocompleted. 2021-03-16: - Tilde expansion can now be extended or modified by defining a .sh.tilde.get or .sh.tilde.set discipline function. This replaces a 2004 undocumented attempt to add this functionality via a .sh.tilde built-in, which never worked and crashed the shell. See the manual for details on the new method. - Fixed a bug in interactive shells: if a variable used by the shell called a discipline function (such as PS1.get() or COLUMNS.set()), the value of $? was set to the exit status of the discipline function instead of the last command run. 2021-03-15: - If the HOME variable is unset, the bare tilde ~ now expands to the current user's system-configured home directory instead of merely the username. - Tighten up potential invalid typeset attribute combos when more than one numeric type has been requested. In particular, -F and -i are no longer masked over by previously given float types. 2021-03-13: - Fixed a file descriptor leak that occurred when ksh used /dev/fd for process substitutions passed to functions. - Fixed a separate file descriptor leak that happened when a process substitution was passed to a nonexistent command. 2021-03-11: - Fixed an intermittent bug that caused process substitutions to infinitely loop in Linux virtual machines that use systemd. - Fixed a bug that caused process substitutions to leave lingering processes if the command invoking them never reads from them. 2021-03-09: - The ${!foo@} and ${!foo*} expansions yield variable names beginning with foo, but excluded 'foo' itself. The fix for this is now backported from 93v- beta. - test -v var, [ -v var ], and [[ -v var ]] did not correctly test if a variable is set or unset after it has been given a numeric attribute with 'typeset' but not yet assigned a value. This has been fixed so that [[ -v var ]] is now equivalent to [[ -n ${var+set} ]] as documented. 2021-03-07: - Fixed the typeset -p display of short integers without an assigned value. Also, the last -s or -l attribute option supplied for an integer is used. - Fixed a bug with -G/--globstar introduced on 2020-08-09: patterns did not match anything if any pathname component was '.' or '..', e.g. '**/./glob.c' never matched. The 2020-08-09 fix does still apply to patterns like '.*'. - Enhancement to -G/--globstar: symbolic links to directories are now followed if they match a normal (non-**) glob pattern. For example, if '/lnk' is a symlink to a directory, '/lnk/**' and '/l?k/**' now work as you would expect. - Fixed a bug introduced on 2021-02-11 that caused job control on interactive ksh sessions to misbehave if the login shell was replaced by ksh using 'exec'. 2021-03-06: - Fixed an old expansion bug: expansions of type ${var=value} and ${var:=value} did not perform an assignment and yielded the value 0 if 'var' was typeset as numeric (integer or float) but had not yet been assigned a value. - Fixed a bug introduced on 2020-08-19: Ctrl+D would break after an interactive shell received SIGWINCH. - Fixed a bug introduced on 2020-05-21: on an interactive shell, command lines containing a syntax error were not added to the command history file and sometimes corrupted the command history. 2021-03-05: - Unbalanced quotes and backticks now correctly produce a syntax error in -c scripts, 'eval', and backtick-style command substitutions. 2021-03-04: - Fixed an arbitrary command execution vulnerability that occurred when parsing the subscripts of arrays within arithmetic commands and expansion. 2021-03-01: - Fixed the retention of size attributes when 'readonly' or 'typeset -r' was applied to an existing variable. 2021-02-26: - Fixed three long-standing bugs with tab completion in the emacs editor: 1. The editor accepted literal tabs without escaping in certain cases, causing buggy and inconsistent completion behaviour. Details: https://github.com/ksh93/ksh/issues/71#issuecomment-656970959 https://github.com/ksh93/ksh/issues/71#issuecomment-657216472 To enter a literal tab in emacs, you need to escape it with ^V or \. 2. After completing a filename by choosing from a file completion menu, the terminal cursor was placed one position too far to the right, corrupting command line display. This happened with multiline active. Details: https://github.com/ksh93/ksh/issues/71#issue-655093805 3. A completion menu was displayed if the file name to be completed was at the point where the rest of it started with a number, even if that part uniquely identified it so the menu only showed one item. Details: https://www.mail-archive.com/ast-users@lists.research.att.com/msg00436.html - A bug with ${.sh.fun} in combination with the DEBUG trap has been fixed. The ${.sh.fun} variable wrongly continued to contain the name of the last function executed by the DEBUG trap after the trap action completed. 2021-02-21: - Fixed: The way that SIGWINCH was handled (i.e. the signal emitted when the terminal window size changes) could cause strange emacs/vi editor behaviour. 2021-02-20: - Fixed a bug introduced on 2021-01-20: if a DEBUG trap action yielded exit status 2, the execution of the next command was not skipped as documented. - Fixed multiple buffer overflows causing crashes in typeset -L/-R-/-Z. - Fixed typeset -Z zero-filling: if the number was zero, all zeros were skipped when changing the initial size value of the -Z attribute, leaving an empty string. 2021-02-18: - A bug was fixed in the 'read' builtin that caused it to fail to process multibyte characters properly in Shift-JIS locales. 2021-02-17: - Emacs mode fixes: 1. Erasing a backslash while doing a reverse search (^R) no longer deletes extra characters. 2. The backslash now escapes a subsequent interrupt (^C) as documented. - Fixed a longstanding bug with shared-state command substitutions of the form ${ command; }. If these were executed in a subshell, changes made within could survive not only the command substitution but also the parent subshell. 2021-02-15: - Fixed a regression introduced by ksh93 (was not in ksh88): an empty 'case' list on a single line ('case x in esac') was a syntax error. - Fixed a bug in the emacs built-in editor, introduced on 2020-09-17, that made the Meta-D and Meta-H keys delete single characters instead of words. - A new 'backslashctrl' shell option has been added. It is on by default. Turning it off (set +o backslashctrl or set --nobackslashctrl) disables the special escaping behaviour of the backslash character in the emacs and vi built-in editors. Particularly in the emacs editor, this makes it much easier to go back, insert a forgotten backslash into a command, and then continue editing without having your next cursor key replace your backslash with garbage. Note that Ctrl+V (or whatever other character was set using 'stty lnext') always escapes all control characters in either editing mode. 2021-02-14: - Due to a deficiency in some UNIX variants, the 'sleep' built-in command could occasionally sleep for slightly less than the time specified. It now performs an additional check against the system clock to make sure it sleeps at least the given amount of time. Thanks to Lev Kujawski for adding this feature. - A few bugs were fixed that 93u+m introduced along with the new '-o posix' shell option on 2020-09-01: 1. 'set --posix' now works as the expected equivalent of 'set -o posix'. 2. As of 2020-09-18, the posix option turns off braceexpand and turns on letoctal. Any attempt to override that in a single command such as 'set -o posix +o letoctal' was quietly ignored. This now works as long as the overriding option follows the posix option on the command line. 3. The --default option to 'set' now stops the 'posix' option, if set or unset in the same 'set' command, from changing other options. This allows the command output by 'set +o' to correctly restore the current options. 2021-02-11: - Fixed a bug that caused ksh to lose track of all running background jobs if a shared-state command substitution of the form v=${ cmd; } was used twice. - Job control (the -m/-o monitor option) has been fixed for scripts. Background jobs are now correctly assigned their own process group when run from subshells (except command substitutions). The 'fg' command now also works for scripts as it does on other shells, though 'wait' should be preferred. 2021-02-05: - Fixed a longstanding bug that caused redirections that store a file descriptor > 10 in a variable, such as {var}>file, to stop working if brace expansion (the -B or -o braceexpand option) was turned off. (Note that '{var}' is not a brace expansion as it does not contain ',' or '..'.) 2021-02-04: - Fixed ksh crashing if an autoloaded function tried to autoload itself. ksh now errors out gracefully with an "autoload loop" error message. - Fixed crash on trying a very long nonexistent command. 2021-02-01: - Fixed a bug in 'typeset': the '-s' modifier option for short integer will now only be applied if the integer option '-i' is also present, avoiding inconsistent results and a crash. - Fixed: scalar arrays (-a) and associative arrays (-A) of a type created by 'enum' allowed values not specified by the enum type, corrupting results. - Fixed: the "${array[@]}" expansion for associative arrays of a type created by 'enum' expanded to random numbers instead of the array's values. 2021-01-30: - The -x option to the 'command' built-in now causes it to bypass built-ins so that it always runs/queries an external command. See 'command --man'. - Fixed a bug in 'command -x' that caused the minimum exit status to be 1 if a command with many arguments was divided into several command invocations. - The 2020-08-16 fix is improved with a compile-time feature test that detects if the OS requires extra bytes per argument in the arguments list, maximising the efficiency of 'command -x' for the system it runs on. 2021-01-24: - Fixed a bug in 'typeset': combining the -u option with -F or -E caused the variable to become a hexadecimal floating point in error. - Fixed: an unquoted variable expansion evaluated in a DEBUG trap action caused IFS field splitting to be deactivated in code executed after the trap action. This bug was introduced in ksh 93t+ 2009-11-30. 2021-01-23: - Fixed: when the DEBUG trap was redefined in a subshell, the DEBUG trap in the parent environment was corrupted or the shell crashed. When a redirection was used in a DEBUG trap action, the trap was disabled. DEBUG traps were also incorrectly inherited by subshells and ksh functions. All this was caused by a bug introduced in ksh 93t 2008-07-25. 2021-01-22: - Compile-time shell options can now be edited in src/cmd/ksh93/SHOPT.sh before building. 2021-01-20: - Fixed: executing a DEBUG trap in a command substitution had side effects on the exit status ($?) of non-trap commands. This bug was introduced in ksh 93t 2008-11-04. - The typeset builtin command now gives an informative error message if an incompatible combination of options is given. 2021-01-19: - Fixed a crash when using 'cd' in a virtual/non-forking subshell in a situation where the current working directory cannot be determined. 2021-01-08: - Fixed a crash on exceeding the maximum size of the $PS1 prompt. The maximum size is also increased from 160 to 256 bytes. 2021-01-07: - Fixed a crash that could occur while ksh updated ${.sh.match}. - Any changes to the hash table (a.k.a. "tracked aliases", i.e. cached $PATH searches) in a subshell now no longer affect the parent shell's hash table. 2021-01-05: - Fixed a bug in 'cd' that caused 'cd ./foo' to search for 'foo' in $CDPATH. 2021-01-03: - The invocation $ ksh +s caused an infinite loop and corrupted ~/.sh_history. This is now fixed so that the '-s' option is automatically turned on if there are no non-option command arguments, as documented in Bolsky & Korn (1995), p. 261. 2020-10-22: - Fixed: 'typeset -F0', 'typeset -E0', and 'typeset -X0' floating point numerics having a precision of 0 with variable assignment. 'typeset -F0 x; x=4.56' worked but not 'typeset -F0 x=4.56'. 2020-10-21: - Fixed: More concisely correct the exporting of uppercase and lowercase variables when only the export and change case attributes were applied. This fix improves upon the previous 2020-09-30 modifications. 2020-10-06: - The security of virtual/non-forking subshells that locally change the present working directory (PWD) using 'cd' has been improved in two ways. 1. On entering a subshell, if the parent shell's PWD proves inaccessible upon saving it, the subshell will now fork into a separate process so the parent process never changes its PWD, avoiding the need to restore it. 2. If some attack renders the parent shell's PWD unrestorable *after* ksh enters a virtual subshell, ksh will now error out on exiting it, as continuing would mean running arbitrary commands in the wrong PWD. Hopefully this is an acceptable compromise between performance and security. The proper fix would be to always fork a subshell when changing the working directory within it, but the resulting slowdown would likely be unpopular. 2020-09-30: - Fixed: 'typeset -xu' and 'typeset -xl' (export + change case) failed to change the case of a variable's value in certain conditions. - A ksh 93u+ regression was fixed in the combination of ERR trap handling and the 'pipefail' option. A pipeline now triggers the ERR trap correctly again if the 'pipefail' option is active and any of the pipeline elements return a nonzero exit status. Similarly, if both the 'errexit' and 'pipefail' options are active, ksh now correctly exits if any pipeline element returns nonzero. - Autoloading a function no longer causes the calling script's $LINENO to be off by the number of lines in the function definition file that was loaded. This also corrects line numbers in warnings and error messages. 2020-09-28: - While executing a ksh-style function, ksh 93u+ ignored all signals for which the function had not set a local trap, except for SIGINT and SIGQUIT. This was contrary to the manual, which states that a "trap condition that is not caught or ignored by the function causes the function to terminate and the condition to be passed on to the caller". This has now been fixed in 93u+m to match the documentation, so that e.g. global traps work as expected again. 2020-09-27: - The shell's lexical analysis of a 'case' statement within a do...done block within a command substitution of the form $(...) has been fixed so that code like the following no longer throws a spurious syntax error: x=$(for i in 1; do case $i in word) true;; esac; done) Previously, this required a leading parenthesis before 'word', although the syntax error claimed that the ';;' was unexpected. 2020-09-26: - 'whence -f' now completely ignores the existence of functions, as documented. - ksh now does not import environment variables whose names are not valid in the shell language, as it would be impossible to change or unset them. However, they stay in the environment to be passed to child processes. 2020-09-25: - whence -v/-a now reports the path to the file that an "undefined" (i.e. autoloadable) function will be loaded from when invoked, if found in $FPATH. - When ksh invoked a shell script that does not have a leading #!/hashbang/path, 'ps' and /proc//cmdline showed corrupted output if the new script's command line was shorter than that of the invoking script. This has been fixed by wiping the arguments buffer correctly. 2020-09-24: - An omission made it impossible to turn off brace expansion within command substitutions (`...`, $(...) or ${ ...; }) as the code for parsing these did not check the -B/braceexpand option. This check has now been added. 2020-09-23: - Fixed a crash that could occur when running a pipeline containing backtick-style command substitutions with job control enabled. - Fixed a crash that occurred when using 'typeset -u' or 'typeset -l' on a special variable such as PATH, ENV or SHELL. 2020-09-21: - A bug was fixed that caused command substitutions embedded in here-documents to lose the output of the commands they ran. This bug occurred when ksh was compiled with the SHOPT_SPAWN compile-time option. - Bugfix: var=$(< file) now reads the file even if the standard inout, standard output and/or standard error file descriptors are closed. 2020-09-20: - Bugfix: when whence -v/-a found an "undefined" (i.e. autoloadable) function in $FPATH, it actually loaded the function as a side effect of reporting on its existence. Now it only reports, as documented. - 'whence' will now canonicalise paths properly, resolving '.' and '..' elements in paths given to it. It also no longer prefixes a spurious double slash when doing something like 'cd / && whence bin/echo'. 2020-09-18: - Setting the 'posix' option now turns off the 'braceexpand' option, as brace expansion is not specified by POSIX and potentially incompatible with sh scripts. In addition, 'set -o posix' now turns on the 'letoctal' option instead of controlling that behaviour directly. 'set +o posix' does the reverse of these. 2020-09-17: - In the vi and emacs line editors, repeat count parameters can now also be used for the arrow keys and the forward-delete key. E.g., in emacs mode, 7 will now move the cursor seven positions to the left. In vi control mode, this would be entered as: 7 . - When a background job on an interactive shell received SIGINT or SIGPIPE, the job termination message was empty. It now shows "Interrupt" or "Broken Pipe". - The -m (-o monitor) option is no longer ignored when specified on the shell invocation command line. - A script that is interrupted with Ctrl+C now terminates its background jobs as expected, unless the -m (-o monitor) option was turned on. 2020-09-14: - Corrected rounding of floating point values by ksh's printf %f formatting operator. Fix contributed by @hyenias. - The forward-delete key now works as expected in emacs and vi editing modes. 2020-09-11: - The 'command' regular builtin utility (which runs a simple command, removing special properties) has been made fully POSIX compliant. 1. The 'command' name can now result from an expansion (fixing BUG_CMDEXPAN), e.g. 'c=command; "$c" ls' and 'set -- command ls; "$@"' now work. 2. If and only if the POSIX mode (the new -o posix shell option) is active, then the 'command' utility now disables not only "special" but also "declaration" properties of builtin commands that it invokes, meaning: a. arguments that start with a variable name followed by '=' are always treated as regular words subject to normal shell syntax; b. 'command' can now stop the shell from exiting if a command that it invokes tries to modify a readonly variable (fixing BUG_CMDSPEXIT). - The 'history' (== 'hist -l') and 'r' (== 'hist -s') interactive shell history commands have reverted to preset aliases and are now only loaded if the shell is interactive and not initialised in POSIX mode. This avoids unneeded conflicts with external commands by these names, particularly 'r'. 2020-09-09: - Fixed BUG_LOOPRET2 and related bugs. The 'exit' and 'return' commands without an argument now correctly default to passing down the exit status of the last-run command. Tests like the following, in which the last-run command is 'false', now correctly output 1 instead of 0: fn() { return || true; }; false; fn; echo "$?" fn() { while return; do true; done; }; false; fn; echo "$?" fn() { for i in 1; do return; done; }; false; fn; echo "$?" fn() { case 1 in 1) return ;; esac; }; false; fn; echo "$?" fn() { { return; } 2>&1; }; false; fn; echo "$?" 2020-09-05: - Fixed erroneous syntax errors in parameter expansions such as ${var:-wor)d} or ${var+w(ord}. The parentheses now correctly lose their normal grammatical meaning within the braces. Fix by Eric Scrivner backported from ksh2020. 2020-09-04: - Fixed a bug that caused a syntax error to be thrown if the special parameter expansions ${!} and ${$} (including braces) were used within a here-document. Bug reported by @Saikiran-m on GitHub. 2020-09-01: - The bash-style '&>file' redirection shorthand (for '>file 2>&1') is now always recognised and not only when running rc/profile init scripts. It no longer issues a warning. This brings ksh93 in line with mksh, bash and zsh. - A long-form shell option '-o posix' has been added, which implements a mode for better compatibility with the POSIX standard. It is automatically turned on if ksh is invoked under the name 'sh'. For now, it: * disables the &> redirection shorthand * causes the 'let' arithmetic command to recognise octal numbers by leading zeros regardless of the setting of the 'letoctal' option * causes file descriptors > 2 to be left open when invoking another program * makes the <> redirection operator default to stdin instead of stdout (this keeps the 2020-05-13 BUG_REDIRIO fix for the POSIX mode while restoring traditional ksh93 behaviour for backwards compatibility) * disables a noncompliant 'test -t' == 'test -t 1' compatibility hack * disables passing an exported variable's attributes (such as integer or readonly) to a new ksh process through the environment 2020-08-19: - Sped up the 'read' command on most systems by 15-25%. Fixed a hanging bug on reading from a FIFO that could occur on macOS. 2020-08-17: - 'command -p' incorrectly used the hash table entry (a.k.a. tracked alias) for a command if its path was previously hashed. It has now been fixed so it never consults the hash table. 2020-08-16: - Fixed 'command -x' on macOS, Linux and Solaris by accounting for a 16-byte argument alignment. If execution does fail, it now aborts with an internal error message instead of entering an infinite retry loop. 2020-08-13: - Fixed memory leaks and a crashing bug that occurred when defining and running functions in subshells. 2020-08-11: - Fixed an intermittent crash upon running a large number of subshells. 2020-08-10: - A number of fixes have been applied to the printf formatting directives %H and %#H (as well as the undocumented equivalents %(html)q and %(url)q): 1. Both formatters have been made multibyte/UTF-8 aware, and no longer delete multibyte characters. Invalid UTF-8 byte sequences are rendered as ASCII question marks. 2. %H no longer wrongly changes spaces to non-breaking spaces ( ). 3. %H now converts the single quote (') to '%#39;' instead of ''' which is not a valid entity in all HTML versions. 4. %#H failed to encode some reserved characters (e.g. '?') while encoding some unreserved ones (e.g. '~'). It now percent-encodes all characters except those 'unreserved' as per RFC3986 (ASCII alphanumeric plus -._~). - Fixed a crash that occurred intermittently after running an external command from a command substitution expanded from the $PS1 shell prompt. 2020-08-09: - File name generation (a.k.a. pathname expansion, a.k.a. globbing) now never matches the special navigational names '.' (current directory) and '..' (parent directory). This change makes a pattern like .* useful; it now matches all hidden files (dotfiles) in the current directory, without the harmful inclusion of '.' and '..'. 2020-08-08: - Argument checking in the 'redirect' builtin command (see 2020-06-11) has been improved to error out before executing redirections. For example, an error like 'redirect ls >foo.txt' now will not create 'foo.txt' and will not leave your standard output permanently redirected to it. 2020-08-06: - Added the '${.sh.pid}' variable as an alternative to Bash's '$BASHPID'. This variable is set to the current shell's PID, unlike '$$' (which is set to the main shell's PID). In virtual subshells '${.sh.pid}' is not changed from its previous value, while in forked subshells '${.sh.pid}' is set to the subshell's process ID. 2020-08-05: - Fixed a bug in functions that caused ksh to crash when an array with an unset method was turned into a multidimensional array. - Fixed a bug that caused scripts to continue running after over-shifting in a function when the function call had a redirection. - When generating shellquoted strings (such as with 'printf %q'), the hexadecimal value of a quoted unprintable character was not protected with square braces, e.g. 0x12 followed by '3' would be quoted as '\x123', which is a different value. Such strings are now quoted like '\x[12]3' if the next character is a hexadecimal digit. 2020-07-31: - Fixed a bug that caused multidimensional associative arrays to be created with an extra array member. - Fixed a bug that caused the expansions of positional parameters $1 - $9, as well as special parameters such as $? and $-, to corrupt any multibyte characters immediately following the expansion if a UTF-8 locale is active. 2020-07-29: - On a ksh compiled to use fork(2) to run external commands, a bug has been fixed that caused signals (such as SIGINT, Ctrl+C) to be ignored within a non-forked subshell after running an external command within that subshell. 2020-07-25: - Fixed BUG_MULTIBIFS: Multibyte characters can now be used as IFS delimiters. "$*" was incorrectly joining positional parameters on the first byte of a multibyte character. This was due to truncation based on the incorrect assumption the IFS would never be larger than a single byte. - Fixed a bug that caused the sleep builtin to continue after being given an unrecognized option. 'sleep -: 1' will now show a usage message and exit instead of sleep for one second. - Fixed a bug that caused the 'typeset' variable attributes -a, -A, -l, and -u to leak out of a subshell if they were set without assigning a value. 2020-07-23: - Fixed an infinite loop that could occur when ksh is the system's /bin/sh. - A command substitution that is run on the same line as a here-document will no longer cause a syntax error. 2020-07-22: - Fixed two race conditions when running external commands on interactive shells with job control active. 2020-07-20: - If a shell function and a built-in command by the same name exist, 'whence -a' and 'type -a' now report both. - Fixed a bug that caused file descriptors opened with 'redirect' or 'exec' to survive a subshell environment after exiting it. 2020-07-19: - Fixed a crash that occurred in the '.' command when using kshdb. - Fixed a crash that occurred when attempting to use redirection with an invalid file descriptor. 2020-07-16: - The 'history' and 'r' default aliases have been made regular built-ins, leaving zero default aliases. - Fixed a bug that caused 'sleep -s' to have no effect with intervals longer than 30 seconds. - The accuracy of the sleep builtin has been improved. It no longer ignores microseconds and doesn't add extra milliseconds when the interval is less than 31 seconds. 2020-07-15: - The 'autoload', 'compound', 'float', 'functions', 'integer' and 'nameref' default aliases have been converted into regular built-in commands, so that 'unalias -a' does not remove them. Shell functions can now use these names, which improves compatibility with POSIX shell scripts. - The End key escape sequence '^[[F' is now handled in the emacs and vi editing modes. The End key moves the cursor to the end of the line (in contrast to the Home key doing the opposite). 2020-07-14: - Fixed a bug that caused 'set -b' to have no effect. - Following the 'time' keyword, the 'times' builtin command now also supports millisecond precision. 2020-07-13: - Fixed a fork bomb that could occur when the vi editor was sent SIGTSTP while running in a ksh script. - Appending a lone percent to the end of a format specifier no longer causes a syntax error. The extra percent will be treated as a literal '%', like in Bash and zsh. - The 'time' keyword now has proper support for millisecond precision. Although this feature was previously documented, the 'time' keyword only supported up to centisecond precision, which caused a command like the one below to return '0.000' on certain operating systems: $ TIMEFORMAT='%3R'; time sleep .003 - The 'time' keyword now zero-pads seconds less than ten (like mksh). 2020-07-10: - Fixed a bug that caused types created with 'typeset -T' to throw an error when used if the type name started with a lowercase 'a'. - A potential crash due to memory corruption when using many file descriptors has been fixed. 2020-07-09: - Fixed a crash on syntax error when sourcing/dotting multiple files. - Fixed a crash when listing indexed arrays. - Fixed a memory leak when restoring PATH when temporarily setting PATH for a command (e.g. PATH=/foo/bar command ...) or in a virtual subshell. - Combining ((...)) with redirections no longer causes a syntax error due to the parser handling '>' incorrectly. - Fixed a bug that corrupted KIA/CQL cross-reference databases created using ksh's -R option; shell warnings were wrongly included in the database file. - The shell's quoting algorithm (used in xtrace, printf %q, and more) has been fixed for UTF-8 (Unicode) locales; it no longer needlessly and inconsistently encodes normal printable UTF-8 characters into hexadecimal \u[xxxx] codes. 2020-07-07: - Four of the date formats accepted by 'printf %()T' have had their functionality altered to the common behavior of date(1): - '%k' and '%l' print the current hour with blank padding, the former based on a 24-hour clock and the latter a twelve hour clock. These are common extensions present on Linux and *BSD. - '%f' prints a date with the format string '%Y.%m.%d-%H:%M:%S' (BusyBox). - '%q' prints the quarter of the year (GNU). 2020-07-06: - 'notty' is now written to the ksh auditing file instead of '(null)' if the user's tty could not be determined. - Unsetting an associative array no longer causes a memory leak to occur. 2020-07-05: - In UTF-8 locales, fix corruption of the shell's internal string quoting algorithm (as used by xtrace, 'printf %q', and more) that occurred when the processing of a multibyte character was interrupted. 2020-07-03: - Backslashes are no longer escaped in the raw Bourne Shell-like editing mode in multibyte locales, i.e. backslashes are no longer treated like Control-V if the emacs and vi modes are disabled. - Deleting a backslash in vi mode with Control-H or Backspace now only escapes a backslash if it was the previous input. This means erasing a string such as 'ab\\\' will only cause the first backslash to escape a Backspace as '^?', like in emacs mode. - An odd interaction with Backspace when the last character of a separate buffer created with Shift-C was '\' has been fixed. '^?' will no longer be output repeatedly when attempting to erase a separate buffer with a Backspace. Note that buffers created with Shift-C are not meant to be erasable: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html#tag_20_152_13_49 - The 'kill' builtin now supports the SIGINFO signal (on operating systems with support for SIGINFO). 2020-07-02: - Fixed a crash that occurred if a directory named '.paths' existed in any directory listed in $PATH. The fix was to only read '.paths' if it is a regular file or a symlink to a regular file. 2020-06-30: - 'read -u' will no longer crash with a memory fault when given an out of range or negative file descriptor. - The '=~' operator no longer raises an error if a regular expression combines the '{x}' quantifier with a sub-expression. 2020-06-28: - Variables created with 'typeset -RF' no longer cause a memory fault when accessed. - Unsetting an array that was turned into a compound variable will no longer cause silent memory corruption. - Variables created with 'readonly' in functions are now set to the specified value instead of nothing. Note that 'readonly' does not create a function-local scope, unlike 'typeset -r' which does. 2020-06-26: - Changing to a directory that has a name starting with a '.' will no longer fail if preceded by '../' (i.e. 'cd ../.local' will now work). 2020-06-24: - Fixed buggy tab completion of tilde-expanded paths such as ~/some in 'vi' mode. - In the raw/default Bourne Shell-like editing mode that occurs when neither the 'emacs' nor the 'vi' shell option is active: * tab completion is now correctly disabled, instead of enabled and broken; * entering tab characters now moves the cursor the correct amount. 2020-06-23: - Fixed a bug that caused combining process substitution with redirection to create a bizarre file in the user's current working directory. - Using process substitution while the shell is interactive no longer causes the process ID of the asynchronous process to be printed. 2020-06-22: - The 'stop' and 'suspend' default aliases have been converted into regular built-in commands, so that 'unalias -a' does not remove them, 'suspend' can do a couple of sanity checks, and something like cmd=stop; $cmd $! will now work. See 'stop --man' and 'suspend --man' for more information. - Fixed a bug that caused the kill and stop commands to segfault when given a non-existent job. - Nested functions no longer ignore variable assignments that were prefixed to their parent function, i.e. 'VAR=foo func' will now set $VAR to 'foo' in the scope of any nested function 'func' runs. 2020-06-20: - Fixed a bug that caused setting the following variables as readonly in a virtual subshell to affect the environment outside of the subshell: $_ ${.sh.name} ${.sh.subscript} ${.sh.level} $RANDOM $LINENO - Fixed two bugs that caused 'unset .sh.lineno' to always produce a memory fault and '(unset .sh.level)' to memory fault when run in nested functions. 2020-06-18: - A two decade old bug that caused 'whence -a' to base the path of tracked aliases on the user's current working directory has been fixed. Now the real path to tracked aliases is shown when '-a' is passed to the whence command. 2020-06-17: - A bug in 'unset -f' was fixed that prevented shell functions from unsetting themselves while they were running. A POSIX function no longer crashes when doing so, and a KornShell-style function no longer silently ignores an 'unset -f' on itself. A function of either form now continues running after unsetting itself, and is removed at the end of the run. 2020-06-16: - Passing the '-d' flag to the read builtin will no longer cause the '-r' flag to be discarded when 'read -r -d' is run. - Fix BUG_CMDSPASGN: preceding a "special builtin"[*] with 'command' now prevents preceding invocation-local variable assignments from becoming global. [*] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_14 2020-06-15: - The 'source' alias has been converted into a regular built-in command. - Functions that set variables in a virtual subshell will no longer affect variables of the same name outside of the virtual subshell's environment. - Terse usage messages written by builtin commands now point the user to the --help and --man options for more information. 2020-06-14: - 'read -S' is now able to correctly handle strings with double quotes nested inside of double quotes. 2020-06-13: - Fixed a timezone name determination bug on FreeBSD that caused the output from "LC_ALL=C printf '%T\n' now" to print the wrong time zone name. 2020-06-11: - Fixed a bug that caused running 'builtin -d' on a special builtin to delete it. The man page for the 'builtin' command documents that special builtins cannot be deleted. - POSIX compliance fix: It is now possible to set shell functions named 'alias' or 'unalias', overriding the commands by the same names. In technical terms, they are now regular builtins, not special builtins. - The redirect='command exec' alias has been converted to a regular 'redirect' builtin command that only accepts I/O redirections, which persist as in 'exec'. This means that: * 'unlias -a' no longer removes the 'redirect' command; * users no longer accidentally get logged out of their shells if they type something intuitive but wrong, like 'redirect ls >file'. - The undocumented 'login' and 'newgrp' builtin commands have been removed. These replaced your shell session with the external commands by the same name, as in 'exec'. If an error occurred (e.g. due to a typo), you would end up immediately logged out. If you do want this behaviour, you can restore it by setting: alias login='exec login' alias newgrp='exec newgrp' 2020-06-10: - The 'hash' utility is now a regular builtin instead of an alias to 'alias -t --'. The functionality of the old command has been removed from the alias builtin. - 'set +r' is no longer able to unset the restricted option. This change makes the behavior of 'set +r' identical to 'set +o restricted'. 2020-06-09: - The 'unalias' builtin will now return a non-zero status if it tries to remove a previously set alias that is not currently set. 2020-06-08: - Fix an issue with the up arrow key in Emacs editing mode. Emacs editing mode is bugged in ksh93u+ and ksh2020. Let's say you were to run the following commands after starting a fresh instance of ksh: $ alias foo=true $ unalias foo If you type 'a' and then press the up arrow on your keyboard, ksh will complete 'a' to 'alias foo=true' by doing a reverse search for the last command that starts with 'a'. Run the alias command again, then type 'u' and press the up arrow key again. If ksh is in Vi mode, you will get 'unalias foo', but in Emacs mode you will get 'alias foo=true' again. All subsequent commands were ignored as ksh was saving the first command and only based later searches off of it. - If 'set -u'/'set -o nounset' is active, then the shell now errors out if a nonexistent positional parameter such as $1, $2, ... is accessed, as other shells do and POSIX requires. (This does *not* apply to "$@" and "$*".) - If 'set -u'/'set -o nounset' is active, then the shell now errors out if $! is accessed before the shell has launched any background process. - Removed support for an obscure early 1990s Bell Labs file system research project called 3DFS, which has not existed for decades. This removes: - an obnoxious default alias 2d='set -f;_2d' that turned off your file name wildcard expansion and then tried to run a nonexistent '_2d' command - undocumented builtins 'vmap' and 'vpath' that only printed error messages - a non-functional -V unary operator for the test and [[ commands - If the last program run by a ksh script exits with a signal (e.g. crashed), ksh itself now exits normally instead of repeating that same signal. In addition, using 'exit x' for x > 256 no longer makes ksh issue a signal. 2020-06-06: - The 'times' command is now a builtin command that conforms to POSIX instead of an alias for the 'time' command. It displays the accumulated user and system CPU times, one line with the times used by the shell and another with those used by all of the shell's child processes. https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_27 - The default aliases command='command ' and nohup='nohup ' have been removed because they caused breakage in an attempt to circumvent other breakage which is being fixed. In the unlikely even that anyone still needs alias substitution to continue on the command argument following 'command' or 'nohup', it's easy to set these aliases yourself. 2020-06-05: - Fix a bug that caused special variables such as PATH, LANG, LC_ALL, etc. to lose their effect after being unset in a subshell. For example: (unset PATH; PATH=/dev/null; ls); : wrongly ran 'ls' (unset LC_ALL; LC_ALL=badlocale); : failed to print a diagnostic This also fixes BUG_KUNSETIFS: unsetting IFS in a subshell failed if IFS was set to the empty value in the parent shell. - Fix crashes on some systems, including at least a crash in 'print -v' on macOS, by eliminating an invalid/undefined use of memccpy() on overlapping buffers in the commonly used sfputr() function. - Fix the ${.sh.subshell} level counter; it is no longer reset to zero when a non-forked subshell happens to fork into a separate process for some reason (an internal implementation detail that should be unnoticeable to scripts). 2020-06-04: - Fix BUG_KBGPID: the $! special parameter was not set if a background job (somecommand &) or co-process (somecommand |&) was launched as the only command within a braces block with an attached redirection, for example: { somecommand & } >&2 With the bug, $! was unchanged; now it contains the PID of somecommand. 2020-05-31: - Fix a bug in autoloading functions. Directories in the path search list which should be skipped (e.g. because they don't exist) did not interact correctly with autoloaded functions, so that a function to autoload was not always found correctly. Details: https://github.com/att/ast/issues/1454 2020-05-30: - Fix POSIX compliance of 'test'/'[' exit status on error. The command now returns status 2 instead of 1 when given an invalid number or arithmetic expression, e.g.: [ 123 -eq 123x ]; echo $? now outputs 2 instead of 1. 2020-05-29: - Fix BUG_FNSUBSH: functions can now be correctly redefined and unset in subshell environments (such as ( ... ), $(command substitutions), etc). Before this fix, this was silently ignored, causing the function by the same name from the parent shell environment to be executed instead. fn() { echo mainsh; } (fn() { echo subsh; }; fn); fn This now correctly outputs "subsh mainsh" instead of "mainsh mainsh". ls() { echo "ls executed"; } (unset -f ls; ls); ls This now correctly lists your directory and then prints "ls executed", instead of printing "ls executed" twice. - Fix a similar bug with aliases. These can now be correctly unset in subshell environments. 2020-05-21: - Fix truncating of files with the combined redirections '<>;file' and '<#pattern'. The bug was caused by out-of-sync streams. Details and discussion: https://github.com/att/ast/issues/61 - Patched code injection vulnerability CVE-2019-14868. As a result, you can no longer use expressions in imported numeric environment variables; only integer literals are allowed. 2020-05-20: - Fix BUG_ISSETLOOP. Expansions like ${var+set} remained static when used within a 'for', 'while' or 'until' loop; the expansions din't change along with the state of the variable, so they could not be used to check whether a variable is set within a loop if the state of that variable changed in the course of the loop. - Fix BUG_IFSISSET. ${IFS+s} always yielded 's', and [[ -v IFS ]] always yielded true, even if IFS is unset. This applied to IFS only. 2020-05-19: - Fix 'command -p'. The -p option causes the operating system's standard utilities path (as output by 'getconf PATH') to be searched instead of $PATH. Before this fix, this was broken on non-interactive shells as the internal variable holding the default PATH value was not correctly initialised. 2020-05-16: - Fix 'test -t 1', '[ -t 1 ]', '[[ -t 1 ]]' in command substitutions. Standard output (file descriptor 1) tested as being on a terminal within a command substitution, which makes no sense as the command substitution is supposed to be catching standard output. v=$(echo begincomsub [ -t 1 ] && echo oops echo endcomsub) echo "$v" This now does not output "oops". 2020-05-14: - Fix syncing history when print -s -f is used. For example, the following now correctly adds a 'cd' command to the history: print -s -f 'cd -- %q\n' "$PWD" Ref.: https://github.com/att/ast/issues/425 https://github.com/att/ast/pull/442 - Fix BUG_PUTIOERR: Output builtins now correctly detect input/output errors. This allows scripts to check for a nonzero exit status on the 'print', 'printf' and 'echo' builtins and prevent possible infinite loops if SIGPIPE is ignored. - Add a convenient bin/run_ksh_tests script to the source tree that sets up the necessary environment and runs the ksh regression tests. 2020-05-13: - Fix BUG_CASELIT: an undocumented 'case' pattern matching misbehaviour that goes back to the original Bourne shell, but wasn't discovered until 2018. If a pattern doesn't match as a pattern, it was tried again as a literal string. This broke common validation use cases, e.g.: n='[0-9]' case $n in ( [0-9] ) echo "$n is a number" ;; esac would output "[0-9] is a number" as the literal string fallback matches the pattern. As this misbehaviour was never documented anywhere (not for Bourne, ksh88, or ksh93), and it was never replicated in other shells (not even in ksh88 clones pdksh and mksh), it is unlikely any scripts rely on it. Of course, a literal string fallback, should it be needed, is trivial to implement correctly without this breakage: case $n in ( [0-9] | "[0-9]") echo "$n is a number or the number pattern" ;; esac Ref.: https://github.com/att/ast/issues/476 - Fix BUG_REDIRIO: ksh used to redirect standard output by default when no file descriptor was specified with the rarely used '<>' reading/writing redirection operator. It now redirects standard input by default, as POSIX specifies and as all other POSIX shells do. To redirect standard output for reading and writing, you now need '1<>'. Ref.: https://github.com/att/ast/issues/75 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_07 ksh-1.0.0-beta.2/README.md000066400000000000000000000256471415700074400146450ustar00rootroot00000000000000![](https://github.com/ksh93/ksh/workflows/CI/badge.svg) # KornShell 93u+m This repository is used to develop bugfixes to the last stable release (93u+ 2012-08-01) of [ksh93](http://www.kornshell.com/), formerly developed by AT&T Software Technology (AST). The sources in this repository were forked from the GitHub [AST repository](https://github.com/att/ast) which is no longer under active development. For user-visible fixes, see [NEWS](https://github.com/ksh93/ksh/blame/master/NEWS) and click on commit messages for full details. For all fixes, see [the commit log](https://github.com/ksh93/ksh/commits/). To see what's left to fix, see [the issue tracker](https://github.com/ksh93/ksh/issues). ## Policy 1. Fixing bugs is main focus of the 1.x series. Major feature development is for future versions (2.x and up). 2. No major rewrites. No refactoring code that is not fully understood. 3. No changes in documented behaviour, except if required for compliance with the [POSIX shell language standard](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html) which David Korn [intended](http://www.kornshell.com/info/) for ksh to follow. 4. No 100% bug compatibility. Broken and undocumented behaviour gets fixed. 5. No bureaucracy, no formalities. Just fix it, or report it: create issues, send pull requests. Every interested party is invited to contribute. 6. To help increase everyone's understanding of this code base, fixes and significant changes should be fully documented in commit messages. 7. Code style varies somewhat in this historic code base. Your changes should match the style of the code surrounding them. Indent with tabs, assuming an 8-space tab width. Opening braces are on a line of their own, at the same indentation level as their corresponding closing brace. Comments always use `/*`...`*/`. 8. Good judgment may override this policy. ## Why? Between 2017 and 2020 there was an ultimately unsuccessful [attempt](https://github.com/att/ast/tree/2020.0.1) to breathe new life into the KornShell by extensively refactoring the last unstable AST beta version (93v-). While that ksh2020 branch is now abandoned and still has many critical bugs, it also had a lot of bugs fixed. More importantly, the AST issue tracker now contains a lot of documentation on how to fix those bugs, which made it possible to backport many of them to the last stable release instead. This ksh 93u+m reboot now incorporates many of these bugfixes, plus patches from [OpenSUSE](https://github.com/ksh93/ksh/wiki/Patch-Upstream-Report:-OpenSUSE), [Red Hat](https://github.com/ksh93/ksh/wiki/Patch-Upstream-Report:-Red-Hat), and [Solaris](https://github.com/ksh93/ksh/wiki/Patch-Upstream-Report:-Solaris), as well as many new fixes from the community ([1](https://github.com/ksh93/ksh/pulls?q=is%3Apr+is%3Amerged), [2](https://github.com/ksh93/ksh/issues?q=is%3Aissue+is%3Aclosed+label%3Abug)). Though there are many [bugs left to fix](https://github.com/ksh93/ksh/issues), we are confident at this point that 93u+m is already the least buggy branch of ksh93 ever released. ## Build To build ksh with a custom configuration of features, edit [`src/cmd/ksh93/SHOPT.sh`](https://github.com/ksh93/ksh/blob/master/src/cmd/ksh93/SHOPT.sh). Then `cd` to the top directory and run: ```sh bin/package make ``` The compiled binaries are stored in the `arch` directory, in a subdirectory that corresponds to your architecture. The command `bin/package host type` outputs the name of this subdirectory. If you have trouble or want to tune the binaries, you may pass additional compiler and linker flags. It is usually best to export these as environment variables *before* running `bin/package` as they could change the name of the build subdirectory of the `arch` directory, so exporting them is a convenient way to keep them consistent between build and test commands. **Note that this system uses `CCFLAGS` instead of the usual `CFLAGS`.** An example that makes Solaris Studio cc produce a 64-bit binary: ```sh export CCFLAGS="-m64 -O" LDFLAGS="-m64" bin/package make ``` Alternatively you can append these to the command, and they will only be used for that command. You can also specify an alternative shell in which to run the build scripts this way. For example: ```sh bin/package make SHELL=/bin/bash CCFLAGS="-O2 -I/opt/local/include" LDFLAGS="-L/opt/local/lib" ``` For more information run ```sh bin/package help ``` Many other commands in this repo self-document via the `--help`, `--man` and `--html` options; those that do have no separate manual page. ### Test After compiling, you can run the regression tests. Start by reading the information printed by: ```sh bin/shtests --man ``` ### Install Automated installation is not supported yet. To install manually: ```sh cp arch/$(bin/package host type)/bin/ksh /usr/local/bin/ cp src/cmd/ksh93/sh.1 /usr/local/share/man/man1/ksh.1 ``` (adapting the destination directories as required). ## What is ksh93? The following is the official AT&T description from 1993 that came with the ast-open distribution. The text is original, but hyperlinks were added here. ---- KSH-93 is the most recent version of the KornShell Language described in "The KornShell Command and Programming Language," by Morris Bolsky and David Korn of AT&T Bell Laboratories, ISBN 0-13-182700-6. The KornShell is a shell programming language, which is upward compatible with "sh" (the Bourne Shell), and is intended to conform to the IEEE P1003.2/ISO 9945.2 [Shell and Utilities standard](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html). KSH-93 provides an enhanced programming environment in addition to the major command-entry features of the BSD shell "csh". With KSH-93, medium-sized programming tasks can be performed at shell-level without a significant loss in performance. In addition, "sh" scripts can be run on KSH-93 without modification. The code should conform to the [IEEE POSIX 1003.1 standard](http://www.opengroup.org/austin/papers/posix_faq.html) and to the proposed ANSI C standard so that it should be portable to all such systems. Like the previous version, KSH-88, it is designed to accept eight bit character sets transparently, thereby making it internationally compatible. It can support multi-byte characters sets with some characteristics of the character set given at run time. KSH-93 provides the following features, many of which were also inherent in KSH-88: * Enhanced Command Re-entry Capability: The KSH-93 history function records commands entered at any shell level and stores them, up to a user-specified limit, even after you log off. This allows you to re-enter long commands with a few keystrokes - even those commands you entered yesterday. The history file allows for eight bit characters in commands and supports essentially unlimited size histories. * In-line Editing: In "sh", the only way to fix mistyped commands is to backspace or retype the line. KSH-93 allows you to edit a command line using a choice of EMACS-TC or "vi" functions. You can use the in-line editors to complete filenames as you type them. You may also use this editing feature when entering command lines from your history file. A user can capture keystrokes and rebind keys to customize the editing interface. * Extended I/O Capabilities: KSH-93 provides several I/O capabilities not available in "sh", including the ability to: * specify a file descriptor for input and output * start up and run co-processes * produce a prompt at the terminal before a read * easily format and interpret responses to a menu * echo lines exactly as output without escape processing * format output using printf formats. * read and echo lines ending in "\\". * Improved performance: KSH-93 executes many scripts faster than the System V Bourne shell. A major reason for this is that many of the standard utilities are built-in. To reduce the time to initiate a command, KSH-93 allows commands to be added as built-ins at run time on systems that support dynamic loading such as System V Release 4. * Arithmetic: KSH-93 allows you to do integer arithmetic in any base from two to sixty-four. You can also do double precision floating point arithmetic. Almost the complete set of C language operators are available with the same syntax and precedence. Arithmetic expressions can be used to as an argument expansion or as a separate command. In addition, there is an arithmetic for command that works like the for statement in C. * Arrays: KSH-93 supports both indexed and associative arrays. The subscript for an indexed array is an arithmetic expression, whereas, the subscript for an associative array is a string. * Shell Functions and Aliases: Two mechanisms - functions and aliases - can be used to assign a user-selected identifier to an existing command or shell script. Functions allow local variables and provide scoping for exception handling. Functions can be searched for and loaded on first reference the way scripts are. * Substring Capabilities: KSH-93 allows you to create a substring of any given string either by specifying the starting offset and length, or by stripping off leading or trailing substrings during parameter substitution. You can also specify attributes, such as upper and lower case, field width, and justification to shell variables. * More pattern matching capabilities: KSH-93 allows you to specify extended regular expressions for file and string matches. * KSH-93 uses a hierarchical name space for variables. Compound variables can be defined and variables can be passed by reference. In addition, each variable can have one or more disciplines associated with it to intercept assignments and references. * Improved debugging: KSH-93 can generate line numbers on execution traces. Also, I/O redirections are now traced. There is a DEBUG trap that gets evaluated before each command so that errors can be localized. * Job Control: On systems that support job control, including System V Release 4, KSH-93 provides a job-control mechanism almost identical to that of the BSD "csh", version 4.1. This feature allows you to stop and restart programs, and to move programs between the foreground and the background. * Added security: KSH-93 can execute scripts which do not have read permission and scripts which have the setuid and/or setgid set when invoked by name, rather than as an argument to the shell. It is possible to log or control the execution of setuid and/or setgid scripts. The noclobber option prevents you from accidentally erasing a file by redirecting to an existing file. * KSH-93 can be extended by adding built-in commands at run time. In addition, KSH-93 can be used as a library that can be embedded into an application to allow scripting. Documentation for KSH-93 consists of an "Introduction to KSH-93", "Compatibility with the Bourne Shell" and a manual page and a README file. In addition, the "New KornShell Command and Programming Language" book is available from Prentice Hall. ksh-1.0.0-beta.2/TODO000066400000000000000000000104221415700074400140370ustar00rootroot00000000000000TODO for ksh 93u+m See the issue tracker for up-to-date information: https://github.com/ksh93/ksh/issues ______ Enhancements to do: * Add -T (-o functrace) option as in bash https://github.com/ksh93/ksh/issues/162 * History pattern search menu (SHOPT_EDPREDICT) needs work https://github.com/ksh93/ksh/issues/233 * Use real pipes instead of sockets https://github.com/ksh93/ksh/issues/327 ______ Known bugs in ksh 93u+m 1.0.0-beta.2 (HELP IS WANTED to fix these): * Memory leak when initialising associative array in subshell https://github.com/ksh93/ksh/issues/94 * command substitution botches output of non-waited-for child processes https://github.com/ksh93/ksh/issues/124 * Intermittent coprocess hang on Debian/Ubuntu and Solaris https://github.com/ksh93/ksh/issues/132 * wrong typeset -p output after unsetting multidimensional array elements https://github.com/ksh93/ksh/issues/148 * File descriptor is unexpectedly closed after exec in subshell https://github.com/ksh93/ksh/issues/161 * printf %T date parsing: GNU-style "ago" date spec completely broken https://github.com/ksh93/ksh/issues/182 * typeset -L/-R: string length breaks on multibyte characters https://github.com/ksh93/ksh/issues/189 * Linux i386: variable expansion corruption in single-line function https://github.com/ksh93/ksh/issues/203 * Segfault with very large extended glob patterns https://github.com/ksh93/ksh/issues/207 * funcname.ksh crashes under standard malloc https://github.com/ksh93/ksh/issues/212 * process substitution cannot be part of a larger argument https://github.com/ksh93/ksh/issues/215 * Compound array regression on OpenBSD with standard malloc https://github.com/ksh93/ksh/issues/229 * 'typeset -m'-related crash on OpenBSD compiled with standard malloc https://github.com/ksh93/ksh/issues/231 * Freeze/crash on OpenBSD with -D_std_malloc involving typeset and command substitution https://github.com/ksh93/ksh/issues/264 * Nested compound assignment misparsed in $(...) command substitution https://github.com/ksh93/ksh/issues/269 * Crash on bin/shtests -px heredoc https://github.com/ksh93/ksh/issues/306 * Multibyte characters get corrupted when KEYBD trap is set https://github.com/ksh93/ksh/issues/307 * .sh.match index array result issues, crash after unset https://github.com/ksh93/ksh/issues/308 * Builtins don't handle I/O errors https://github.com/ksh93/ksh/issues/313 * block devices not seekable when open on fd 0, 1 or 2 https://github.com/ksh93/ksh/issues/318 * bug in printf when %b and %x$ are used in same format https://github.com/ksh93/ksh/issues/324 * namespaces don't work properly when defined within functions https://github.com/ksh93/ksh/issues/325 * Associative arrays of various types fail to be unset https://github.com/ksh93/ksh/issues/345 * types survive exec of hashbangless script https://github.com/ksh93/ksh/issues/350 * Backtick command substitutions can't nest double quotes https://github.com/ksh93/ksh/issues/352 * Line continuation breakage within $(comsub) https://github.com/ksh93/ksh/issues/367 ______ Fix regression test failures: - There are some serious regression test failures on OpenBSD when ksh is compiled with AST vmalloc disabled, so the system standard malloc(3) is used. These probably represent real ksh93 bugs exposed by OpenBSD's security hardening mechanisms. - Several known memory leaks have their tests disabled in tests/leaks.sh and are marked TODO. These need tracking down and fixing. ______ Fix currently known bugs affecting shell scripting. These are identified by their modernish IDs. For exact details, see code/comments in: https://github.com/modernish/modernish/tree/0.16/lib/modernish/cap/ - BUG_BRACQUOT: shell quoting within bracket patterns has no effect. This bug means the '-' retains it special meaning of 'character range', and an initial ! (and, on some shells, ^) retains the meaning of negation, even in quoted strings within bracket patterns, including quoted variables. - BUG_IFSGLOBS: In glob pattern matching (as in case or parameter substitution with # and %), if IFS starts with ? or * and the "$*" parameter expansion inserts any IFS separator characters, those characters are erroneously interpreted as wildcards when quoted "$*" is used as the glob pattern. ksh-1.0.0-beta.2/bin/000077500000000000000000000000001415700074400141205ustar00rootroot00000000000000ksh-1.0.0-beta.2/bin/Mamfile_indent000077500000000000000000000013661415700074400167670ustar00rootroot00000000000000#!/usr/bin/env sh IFS=''; set -fCu # safe mode: no split/glob = no quoting headaches let() { return $((!($1))); } # Automatically (re-)indent make...done blocks in a Mamfile. # Usage: Mamfile_indent Mamfile.new # # Should work on all current POSIX compliant shells. # By Martijn Dekker , 2021. Public domain. # Spacing per indentation level. Edit to change style. indent=' ' # one tab # Remove existing indentation, add new indentation. indentlvl=0 sed 's/^[[:space:]]*//' \ | while read -r line do case $line in '') continue ;; done*) let "indentlvl -= 1" ;; esac spc= i=0 while let "(i += 1) <= indentlvl" do spc=$indent$spc done printf '%s\n' $spc$line case $line in make*) let "indentlvl += 1" ;; esac done ksh-1.0.0-beta.2/bin/Mamfile_rm_unused_vars000077500000000000000000000017351415700074400205420ustar00rootroot00000000000000#!/usr/bin/env sh IFS=''; set -fCu # safe mode: no split/glob = no quoting headaches CCn=' ' # newline let() { return $((!($1))); } # Remove unused variable definitions from a Mamfile. # Usage: Mamfile_rm_unused_vars Mamfile.new # # Should work on all current POSIX compliant shells. # By Martijn Dekker , 2021. Public domain. # # All variables are declared with 'setv' and they are used if an expansion # of the form ${varname} exists (the braces are mandatory in Mamfiles). mamfile=$(let $# && cat "$1" || cat) vars=$(printf '%s\n' $mamfile | awk '$1 == "setv" { print $2; }') rm_unused_ere= IFS=$CCn; for varname in $vars; do IFS= case $mamfile in *"\${$varname}"* ) ;; * ) # add with '|' separator for Extended Regular Expression rm_unused_ere="${rm_unused_ere:+$rm_unused_ere|}setv[[:blank:]]+$varname([[:blank:]]|$)" ;; esac done case $rm_unused_ere in '') printf '%s\n' $mamfile ;; *) printf '%s\n' $mamfile | grep -vE $rm_unused_ere ;; esac ksh-1.0.0-beta.2/bin/ignore000077500000000000000000000035441415700074400153370ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## # non-ksh script for the nmake ignore prefix # @(#)ignore (AT&T Research) 1992-08-11 (command set -o posix) 2>/dev/null && set -o posix modern_export=`v=; export v=ok 2>/dev/null; echo "$v"` while : do case $# in 0) exit 0 ;; esac case $1 in *=*) case $modern_export in ok) export "$1" ;; *) `echo $1 | sed "s/\\([^=]*\\)=\\(.*\\)/eval \\1='\\2'; export \\1/"` ;; esac shift ;; *) break ;; esac done "$@" exit 0 ksh-1.0.0-beta.2/bin/mamprobe000077500000000000000000000150561415700074400156570ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## ### this script contains archaic constructs that work with all sh variants ### # mamprobe - generate MAM cc probe info # Glenn Fowler (command set -o posix) 2>/dev/null && set -o posix command=mamprobe bins=` ( userPATH=$PATH PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH getconf PATH 2>/dev/null && echo "$userPATH" || echo /bin:/usr/bin:/sbin:/usr/sbin:"$userPATH" ) | sed 's/:/ /g' ` || exit # check the options opt= case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) USAGE=$' [-? @(#)$Id: mamprobe (AT&T Labs Research) 2011-02-11 $ ] [+NAME?mamprobe - generate MAM cc probe info] [+DESCRIPTION?\bmamprobe\b generates MAM (make abstract machine) \bcc\b(1) probe information for use by \bmamake\b(1). \acc-path\a is the absolute path of the probed compiler and \ainfo-file\a is where the information is placed. \ainfo-file\a is usually \b$INSTALLROOT/lib/probe/C/mam/\b\ahash\a, where \ahash\a is a hash of \acc-path\a. Any \ainfo-file\a directories are created if needed. If \ainfo-file\a is \b-\b then the probe information is written to the standard output.] [+?\bmamprobe\b and \bmamake\b are used in the bootstrap phase of \bpackage\b(1) installation before \bnmake\b(1) is built. The probed variable names are the \bnmake\b(1) names with a \bmam_\b prefix, \bCC\b converted to \bcc\b, and \b.\b converted to \b_\b. Additional variables are:]{ [+_hosttype_?the \bpackage\b(1) host type] [+mam_cc_L?\b-L\b\adir\a supported] [+STDCAT?command to execute for \bcat\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCHMOD?command to execute for \bchmod\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCMP?command to execute for \bcmp\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCP?command to execute for \bcp\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDED?command to execute for \bed\b(1) or \bex\b(1)] [+STDEDFLAGS?flags for \bSTDED\b] [+STDLN?command to execute for \bln\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDMV?command to execute for \bmv\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDRM?command to execute for \brm\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] } [d:debug?Enable probe script debug trace.] info-file cc-path [+SEE ALSO?\bexecrate\b(1), \bpackage\b(1), \bmamake\b(1), \bnmake\b(1), \bprobe\b(1)] ' while getopts -a "$command" "$USAGE" OPT do case $OPT in d) opt=-d ;; esac done shift `expr $OPTIND - 1` ;; *) while : do case $# in 0) break ;; esac case $1 in --) shift break ;; -) break ;; -d) opt=-d ;; -*) echo $command: $1: unknown option >&2 ;; *) break ;; esac set '' break done ;; esac # check the args case $1 in -) ;; /*) ;; *) set '' ;; esac case $2 in /*) ;; *) set '' ;; esac case $# in 0|1) echo "Usage: $command info-file cc-path" >&2; exit 2 ;; esac info=$1 shift cc=$* # find the make probe script ifs=${IFS-' '} IFS=: set $PATH IFS=$ifs script=lib/probe/C/make/probe while : do case $# in 0) echo "$0: ../$script: probe script not found on PATH" >&2 exit 1 ;; esac case $1 in '') continue ;; esac makeprobe=`echo $1 | sed 's,[^/]*$,'$script,` if test -x $makeprobe then break fi shift done # create the info dir if necessary case $info in /*) i=X$info ifs=${IFS-' '} IFS=/ set $i IFS=$ifs while : do i=$1 shift case $i in X) break ;; esac done case $info in //*) path=/ ;; *) path= ;; esac while : do case $# in 0|1) break ;; esac comp=$1 shift case $comp in '') continue ;; esac path=$path/$comp if test ! -d $path then mkdir $path || exit fi done ;; esac # generate info in a tmp file and rename when finished case $info in -) ;; *) tmp=${TMPDIR:-/tmp}/mam$$ trap "exec >/dev/null; rm -f $tmp" 0 1 2 3 15 exec > $tmp echo "probing C language processor $cc for mam information" >&2 ;; esac echo "note generated by $0 for $cc" ( set '' $opt $cc shift . $makeprobe "$@" case " $CC_DIALECT " in *" -L "*) echo "CC.L = 1" ;; esac ) | sed \ -e '/^CC\./!d' \ -e 's/^CC./setv mam_cc_/' \ -e 's/^\([^=.]*\)\./\1_/' \ -e 's/^\([^=.]*\)\./\1_/' \ -e 's/ =//' \ -e 's/\$("\([^"]*\)")/\1/g' \ -e 's/\$(\([^)]*\))/${\1}/g' \ -e 's/\${CC\./${mam_cc_}/g' echo 'setv _hosttype_ ${mam_cc_HOSTTYPE}' # STD* are standard commands/flags with possible execrate(1) if ( ed < /dev/null 2>&1 then STDED=ed else STDED=ex fi STDEDFLAGS=- set STDCAT cat STDCHMOD chmod STDCMP cmp STDCP cp STDLN ln STDMV mv STDRM rm while : do case $# in 0|1) break ;; esac p=$2 for d in $bins do if test -x $d/$p then p=$d/$p break fi done eval $1=\$p shift shift done if execrate then for n in STDCAT STDCHMOD STDCMP STDCP STDLN STDMV STDRM do eval $n=\"execrate \$$n\" done fi for n in STDCAT STDCHMOD STDCMP STDCP STDED STDEDFLAGS STDLN STDMV STDRM do eval echo setv \$n \$$n done # all done case $info in -) ;; *) exec >/dev/null test -f "$info" && rm -f "$info" cp "$tmp" "$info" chmod -w "$info" ;; esac ksh-1.0.0-beta.2/bin/package000077500000000000000000002424011415700074400154440ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2012 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## ### this sh script is POSIX compliant and compatible with shell bugs ### # KornShell 93u+m build system, main control script # # based on AST 'package' by Glenn Fowler # # simplified and rewritten by Martijn Dekker # ######################################################################## command=package # Escape from a non-POSIX shell min_posix='path=Bad && case $PATH in (Bad) exit 1;; esac && '\ 'PWD=Bad && cd -P -- / && case $PWD in (/) ;; (*) exit 1;; esac && '\ '! { ! case x in ( x ) : ${0##*/} || : $( : ) ;; esac; } && '\ 'trap "exit 0" 0 && exit 1' if (eval "$min_posix") 2>/dev/null then : good shell else "$SHELL" -c "$min_posix" 2>/dev/null && exec "$SHELL" -- "$0" ${1+"$@"} sh -c "$min_posix" 2>/dev/null && exec sh -- "$0" ${1+"$@"} DEFPATH=`getconf PATH` 2>/dev/null || DEFPATH=/usr/xpg4/bin:/bin:/usr/bin:/sbin:/usr/sbin PATH=$DEFPATH:$PATH export PATH sh -c "$min_posix" 2>/dev/null && exec sh -- "$0" ${1+"$@"} echo "$0: Can't escape from obsolete or broken shell. Run me with a POSIX shell." >&2 exit 128 fi readonly min_posix # use for checksh() # Set standards compliance mode (command set -o posix) 2>/dev/null && set -o posix # Sanitize 'cd' unset CDPATH # Make the package root the current working directory # This makes it possible to run '/my/path/package make' without cd'ing first # (for all its featuritis, the AT&T version never could manage this) case $0 in [0123456789+-]*) echo "dodgy \$0: $0" >&2 exit 128 ;; */*) me=$0 ;; *) me=$(command -v "$0") || exit 128 ;; esac me=$(dirname "$me") cd "$me" || exit unset -v me case $PWD in */arch/*/*/bin) cd .. ;; */arch/*/bin) cd ../../.. ;; */bin) cd .. ;; *) echo "this script must live in bin/" >&2 exit 1 ;; esac || exit # shell checks checksh() { "$1" -c "$min_posix" 2>/dev/null || return 1 } LC_ALL=C export LC_ALL TMPDIR=${TMPDIR:-/tmp} export TMPDIR src="cmd contrib etc lib" use="/usr/common /exp /usr/local /usr/add-on /usr/addon /usr/tools /usr /opt" usr="/home" lib="" # need /usr/local/lib /usr/local/shlib ccs="/usr/kvm /usr/ccs/bin" org="gnu GNU" makefiles="Mamfile" # ksh 93u+m no longer uses these: Nmakefile nmakefile Makefile makefile env="HOSTTYPE NPROC PACKAGEROOT INSTALLROOT PATH" package_use='=$HOSTTYPE=$PACKAGEROOT=$INSTALLROOT=$EXECROOT=$CC=' CROSS=0 MAKESKIP=${MAKESKIP:-"*[-.]*"} SED= TR= all_types='*.*|sun4' # all but sun4 match *.* case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in 0123) USAGE=$' [-? @(#)$Id: '$command$' (ksh 93u+m) 2021-12-15 $ ] [-author?Glenn Fowler ] [-author?Contributors to https://github.com/ksh93/ksh] [-copyright?(c) 1994-2012 AT&T Intellectual Property] [-copyright?(c) 2020-2021 Contributors to https://github.com/ksh93/ksh] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?'$command$' - build, test and install ksh 93u+m] [+DESCRIPTION?The \b'$command$'\b command is the main control script for building and installing KornShell 93u+m. It is a POSIX \bsh\b(1) script coded for maximal portability. A POSIX shell and C compiler installation are the only requirements. All package files are in the \b$PACKAGEROOT\b directory tree. Binary package files are in the \b$INSTALLROOT\b (\b$PACKAGEROOT/arch/\b\ahosttype\a) tree, where \ahosttpe\a=$(\bbin/package host type\b). See \bDETAILS\b for more information.] [+?Note that no environment variables need be set by the user; \b'$command$'\b determines the environment based on the current working directory. The \buse\b action starts a \bsh\b(1) with the environment initialized. \bCC\b, \bCCFLAGS\b, \bHOSTTYPE\b and \bSHELL\b may be set by explicit command argument assignments to override the defaults.] [+?The command arguments are composed of a sequence of words: zero or more \aqualifiers\a, one \aaction\a, and zero or more action-specific \aarguments\a, and zero or more \aname=value\a definitions. \boptget\b(3) documentation options such as \b--man\b, \b--html\b and \b--nroff\b are also supported. The default with no arguments is \bhost type\b.] [+?The qualifiers are:] { [+debug|environment?Show environment and actions but do not execute.] [+force?Force the action to override saved state.] [+never?Run make -N and show other actions.] [+only?Only operate on the specified packages.] [+quiet?Do not list captured action output.] [+show?Run make -n and show other actions.] [+verbose?Provide detailed action output.] [+DEBUG?Trace the package script actions in detail.] } [+?The actions are:] { [+clean | clobber?Delete the \barch/\b\aHOSTTYPE\a hierarchy; this deletes all generated files and directories for \aHOSTTYPE\a. The hierarchy can be rebuilt by \b'$command$' make\b.] [+export\b [ \avariable\a ...]]?List \aname\a=\avalue\a for \avariable\a, one per line. If the \bonly\b attribute is specified then only the variable values are listed. If no variables are specified then \b'$env$'\b are assumed.] [+help\b [ \aaction\a ]]?Display help text on the standard error (standard output for \aaction\a).] [+host\b [ \aattribute\a ... ]]?List architecture/implementation dependent host information on the standard output. \btype\b is listed if no attributes are specified. Information is listed on a single line in \aattribute\a order. The attributes are:] { [+canon \aname\a?An external host type name to be converted to \b'$command$'\b syntax.] [+cpu?The number of CPUs; 1 if the host is not a multiprocessor.] [+name?The host name.] [+rating?The CPU rating in pseudo mips; the value is useful useful only in comparisons with rating values of other hosts. Other than a vax rating (mercifully) fixed at 1, ratings can vary wildly but consistently from vendor mips ratings. \bcc\b(1) may be required to determine the rating.] [+type?The host type, usually in the form \avendor\a.\aarchitecture\a, with an optional trailing -\aversion\a. The main theme is that type names within a family of architectures are named in a similar, predictable style. OS point release information is avoided as much as possible, but vendor resistance to release incompatibilities has for the most part been futile.] } [+install\b To be reimplemented.] [+make\b [ \apackage\a ]] [ \aoption\a ... ]] [ \atarget\a ... ]]?Build and install. The default \atarget\a is \binstall\b, which makes and installs \apackage\a. If the standard output is a terminal then the output is also captured in \b$INSTALLROOT/lib/package/gen/make.out\b. The build is done in the \b$INSTALLROOT\b directory tree viewpathed on top of the \b$PACKAGEROOT\b directory tree. Leaf directory names matching the \b|\b-separated shell pattern \b$MAKESKIP\b are ignored. The \bview\b action is done before making. \aoption\a operands are passed to the underlying make command.] [+results\b [ \bfailed\b ]] [ \bpath\b ]] [ \bold\b ]] [\bmake\b | \btest\b | \bwrite\b ]]?List results and interesting messages captured by the most recent \bmake\b (default), \btest\b or \bwrite\b action. \bold\b specifies the previous results, if any (current and previous results are retained). \b$HOME/.pkgresults\b, if it exists, must contain an \begrep\b(1) expression of result lines to be ignored. \bfailed\b lists failures only and \bpath\b lists the results file path name only.] [+test\b [ \aargument\a ... ]]?Run the regression tests for \bksh\b. If the standard output is a terminal then the output is also captured in \b$INSTALLROOT/lib/package/gen/test.out\b. \bksh\b must be made before it can be tested. All \aargument\as following \atest\a are passed to \bbin/shtests\b. See \bbin/shtests --man\b for more information.] [+use\b [ \auid\a | \apackage\a | . [ 32 | 64 ]] | 32 | 64 | - ]] [ command ...]]?Run \acommand\a, or an interactive shell if \acommand\a is omitted, with the environment initialized for using the package (can you say \ashared\a \alibrary\a or \adll\a without cussing?) If \auid\a or \apackage\a or \a.\a is specified then it is used to determine a \b$PACKAGEROOT\b, possibly different from the current directory. For example, to try out bozo'\'$'s package: \bpackage use bozo\b. The \buse\b action may be run from any directory. If the file \b$INSTALLROOT/lib/package/profile\b is readable then it is sourced to initialize the environment. 32 or 64 implies \b$PACKAGEROOT\b of . and specifies the target architecture word size (which may be silently ignored).] [+view\b?Initialize the architecture specific viewpath hierarchy. The \bmake\b action implicitly calls this action.] } [+DETAILS?The package directory hierarchy is rooted at \b$PACKAGEROOT\b. All source and binaries reside under this tree. A two level viewpath is used to separate source and binaries. The top view is architecture specific, the bottom view is shared source. All building is done in the architecture specific view; no source view files are intentionally changed. This means that many different binary architectures can be made from a single copy of the source.] [+?Independent \b$PACKAGEROOT\b hierarchies can be combined by appending \b$INSTALLROOT:$PACKAGEROOT\b pairs to \bVPATH\b. The \bVPATH\b viewing order is from left to right.] [+?\b$HOSTYPE\b names the current binary architecture and is determined by the output of \b'$command$'\b (no arguments). The \b$HOSTTYPE\b naming scheme is used to separate incompatible executable and object formats. All architecture specific binaries are placed under \b$INSTALLROOT\b (\b$PACKAGEROOT/arch/$HOSTTYPE\b). There are a few places that match against \b$HOSTTYPE\b when making binaries; these are limited to makefile compiler workarounds, e.g., if \b$HOSTTYPE\b matches \bhp.*\b then turn off the optimizer for these objects. All other architecture dependent logic is handled either by the \bAST\b \biffe\b(1) command or by component specific configure scripts. Explicit \b$HOSTYPE\b values matching *,*cc*[,-*,...]] optionally set the default \bCC\b and \bCCFLAGS\b. This is handy for build farms that support different compilers on the same architecture.] [+?Each component contains a \bMAM\b (make abstract machine) file (\bMamfile\b). A Mamfile contains a portable makefile description written in a simple dependency tree language using indented \bmake\b...\bdone\b blocks.] [+?Most component C source is prototyped. If \b$CC\b (default value \bcc\b) is not a prototyping C compiler then \b'$command$' make\b runs \bproto\b(1) on portions of the \b$PACKAGEROOT/src\b tree and places the converted output files in the \b$PACKAGEROOT/proto/src\b tree. Converted files are then viewpathed over the original source. \bproto\b(1) converts an ANSI C subset to code that is compatible with K&R, ANSI, and C++ dialects.] [+?All scripts and commands under \b$PACKAGEROOT\b use \b$PATH\b relative pathnames (via the \bAST\b \bpathpath\b(3) function); there are no embedded absolute pathnames. This means that binaries generated under \b$PACKAGEROOT\b may be copied to a different root; users need only change their \b$PATH\b variable to reference the new installation root \bbin\b directory. \b'$command$' install\b installs binary packages in a new \b$INSTALLROOT\b.] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ] [+SEE ALSO?\bautoconfig\b(1), \bcksum\b(1), \bexecrate\b(1), \bexpmake\b(1), \bgzip\b(1), \bmake\b(1), \bmamake\b(1), \bpax\b(1), \bpkgadd\b(1), \bpkgmk\b(1), \bproto\b(1), \bratz\b(1), \brpm\b(1), \bsh\b(1), \btar\b(1), \boptget\b(3)] ' case $* in help) set -- --man ;; esac while getopts -a "$command" "$USAGE" OPT do : done shift $((OPTIND-1)) ;; esac # check the args case $AR in '') AR=ar ;; esac case $CC in '') CC=cc ;; esac case $LD in '') LD=ld ;; esac case $NM in '') NM=nm ;; esac action= bit= exec= force=0 global= hi= ifs=${IFS-' '} lo= make= makeflags='-K' nl=" " noexec= only=0 output= quiet=0 show=: tab=" " verbose=0 AUTHORIZE= DEBUG= PROTOROOT=- SHELLMAGIC=- unset FIGNORE BINDIR DLLDIR ETCDIR FUNDIR INCLUDEDIR LIBDIR LOCALEDIR MANDIR SHAREDIR 2>/dev/null || true while : do case $# in 0) set host type ;; esac case $1 in clean|clobber|export|host|install|make|remove|results|test|use|view) action=$1 shift break ;; debug|environment) exec=echo make=echo show=echo ;; force) force=1 ;; never) exec=echo noexec=-N ;; only) only=1 ;; quiet) quiet=1 ;; show) exec=echo noexec=-n ;; verbose)verbose=1 ;; DEBUG) DEBUG=1 PS4='+$LINENO:$SECONDS+ ' set -x ;; help|HELP|html|man|--[?m]*) case $1 in help) code=0 case $2 in '') exec 1>&2 ;; esac ;; html) code=0 html=1 echo "$command help

$command help

"
			;;
		*)	code=2
			exec 1>&2
			;;
		esac
		echo 'NAME
  package - build, test and install ksh 93u+m

SYNOPSIS
  package [ options ] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ]

DESCRIPTION
  The package command is the main control script for building and installing
  KornShell 93u+m. It is a POSIX sh(1) script coded for maximal portability. A
  POSIX shell and C compiler installation are the only requirements. All
  package files are in the $PACKAGEROOT directory tree. Binary package files
  are in the $INSTALLROOT ($PACKAGEROOT/arch/hosttype) tree, where
  hosttpe=$(bin/package host type). See DETAILS for more information.

  Note that no environment variables need be set by the user; package
  determines the environment based on the current working directory. The use
  action starts a sh(1) with the environment initialized. CC, CCFLAGS, HOSTTYPE
  and SHELL may be set by explicit command argument assignments to override the
  defaults.

  The command arguments are composed of a sequence of words: zero or more
  qualifiers, one action, and zero or more action-specific arguments, and zero
  or more name=value definitions. optget(3) documentation options such as
  --man, --html and --nroff are also supported. The default with no arguments
  is host type.

  The qualifiers are:
    debug|environment
          Show environment and actions but do not execute.
    force Force the action to override saved state.
    never Run make -N and show other actions.
    only  Only operate on the specified packages.
    quiet Do not list captured action output.
    show  Run make -n and show other actions.
    verbose
          Provide detailed action output.
    DEBUG Trace the package script actions in detail.

  The actions are:
    clean | clobber
          Delete the arch/HOSTTYPE hierarchy; this deletes all generated files
          and directories for HOSTTYPE. The hierarchy can be rebuilt by package
          make.
    export [ variable ...]
          List name=value for variable, one per line. If the only attribute is
          specified then only the variable values are listed. If no variables
          are specified then HOSTTYPE NPROC PACKAGEROOT INSTALLROOT PATH are
          assumed.
    help [ action ]
          Display help text on the standard error (standard output for action).
    host [ attribute ... ]
          List architecture/implementation dependent host information on the
          standard output. type is listed if no attributes are specified.
          Information is listed on a single line in attribute order. The
          attributes are:
            canon name
                  An external host type name to be converted to package syntax.
            cpu   The number of CPUs; 1 if the host is not a multiprocessor.
            name  The host name.
            rating
                  The CPU rating in pseudo mips; the value is useful useful
                  only in comparisons with rating values of other hosts. Other
                  than a vax rating (mercifully) fixed at 1, ratings can vary
                  wildly but consistently from vendor mips ratings. cc(1) may
                  be required to determine the rating.
            type  The host type, usually in the form vendor.architecture, with
                  an optional trailing -version. The main theme is that type
                  names within a family of architectures are named in a
                  similar, predictable style. OS point release information is
                  avoided as much as possible, but vendor resistance to release
                  incompatibilities has for the most part been futile.
    install To be reimplemented.
    make [ package ] [ option ... ] [ target ... ]
          Build and install. The default target is install, which makes and
          installs package. If the standard output is a terminal then the
          output is also captured in $INSTALLROOT/lib/package/gen/make.out. The
          build is done in the $INSTALLROOT directory tree viewpathed on top of
          the $PACKAGEROOT directory tree. Leaf directory names matching the
          |-separated shell pattern $MAKESKIP are ignored. The view action is
          done before making. option operands are passed to the underlying make
          command.
    results [ failed ] [ path ] [ old ] [make | test | write ]
          List results and interesting messages captured by the most recent
          make (default), test or write action. old specifies the previous
          results, if any (current and previous results are retained).
          $HOME/.pkgresults, if it exists, must contain an egrep(1) expression
          of result lines to be ignored. failed lists failures only and path
          lists the results file path name only.
    test [ argument ... ]
          Run the regression tests for ksh. If the standard output is a
          terminal then the output is also captured in
          $INSTALLROOT/lib/package/gen/test.out. ksh must be made before it can
          be tested. All arguments following test are passed to bin/shtests.
          See bin/shtests --man for more information.
    use [ uid | package | . [ 32 | 64 ] | 32 | 64 | - ] [ command ...]
          Run command, or an interactive shell if command is omitted, with the
          environment initialized for using the package (can you say shared
          library or dll without cussing?) If uid or package or . is specified
          then it is used to determine a $PACKAGEROOT, possibly different from
          the current directory. For example, to try out bozo'\''s package:
          package use bozo. The use action may be run from any directory. If
          the file $INSTALLROOT/lib/package/profile is readable then it is
          sourced to initialize the environment. 32 or 64 implies $PACKAGEROOT
          of . and specifies the target architecture word size (which may be
          silently ignored).
    view  Initialize the architecture specific viewpath hierarchy. The make
          action implicitly calls this action.

DETAILS
  The package directory hierarchy is rooted at $PACKAGEROOT. All source and
  binaries reside under this tree. A two level viewpath is used to separate
  source and binaries. The top view is architecture specific, the bottom view
  is shared source. All building is done in the architecture specific view; no
  source view files are intentionally changed. This means that many different
  binary architectures can be made from a single copy of the source.

  Independent $PACKAGEROOT hierarchies can be combined by appending
  $INSTALLROOT:$PACKAGEROOT pairs to VPATH. The VPATH viewing order is from
  left to right.

  $HOSTYPE names the current binary architecture and is determined by the
  output of package (no arguments). The $HOSTTYPE naming scheme is used to
  separate incompatible executable and object formats. All architecture
  specific binaries are placed under $INSTALLROOT
  ($PACKAGEROOT/arch/$HOSTTYPE). There are a few places that match against
  $HOSTTYPE when making binaries; these are limited to makefile compiler
  workarounds, e.g., if $HOSTTYPE matches hp.* then turn off the optimizer for
  these objects. All other architecture dependent logic is handled either by
  the AST iffe(1) command or by component specific configure scripts. Explicit
  $HOSTYPE values matching *,*cc*[,-*,...] optionally set the default CC and
  CCFLAGS. This is handy for build farms that support different compilers on
  the same architecture.

  Each component contains a MAM (make abstract machine) file (Mamfile). A
  Mamfile contains a portable makefile description written in a simple
  dependency tree language using indented make...done blocks.

  Most component C source is prototyped. If $CC (default value cc) is not a
  prototyping C compiler then package make runs proto(1) on portions of the
  $PACKAGEROOT/src tree and places the converted output files in the
  $PACKAGEROOT/proto/src tree. Converted files are then viewpathed over the
  original source. proto(1) converts an ANSI C subset to code that is
  compatible with K&R, ANSI, and C++ dialects.

  All scripts and commands under $PACKAGEROOT use $PATH relative pathnames (via
  the AST pathpath(3) function); there are no embedded absolute pathnames. This
  means that binaries generated under $PACKAGEROOT may be copied to a different
  root; users need only change their $PATH variable to reference the new
  installation root bin directory. package install installs binary packages in
  a new $INSTALLROOT.

SEE ALSO
  autoconfig(1), cksum(1), execrate(1), expmake(1), gzip(1), make(1),
  mamake(1), pax(1), pkgadd(1), pkgmk(1), proto(1), ratz(1), rpm(1), sh(1),
  tar(1), optget(3)

IMPLEMENTATION
  version         package (ksh 93u+m) 2021-12-15
  author          Glenn Fowler 
  author          Contributors to https://github.com/ksh93/ksh
  copyright       (c) 1994-2012 AT&T Intellectual Property
  copyright       (c) 2020-2021 Contributors to https://github.com/ksh93/ksh
  license         http://www.eclipse.org/org/documents/epl-v10.html'
		case $1 in
		html)	echo "
" ;; esac exit $code ;; *=*) set DEFAULT host type "$@" ;; *) # simulate AST getopt(3) usage output echo "Usage: $command [ options ] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ]" >&2 echo " Help: $command [ --help | --man ] 2>&1" >&2 exit 2 ;; esac global="$global $1" shift done # gather HOSTTYPE *,* options # ,*cc*,-*,... set CC and CCFLAGS hostopts() { _ifs_=$IFS IFS=, set '' $HOSTTYPE IFS=$_ifs_ shift while : do case $# in 0|1) break ;; esac shift case $1 in *cc*) CC=$1 while : do case $# in 0|1) break ;; esac case $2 in -*) case $assign_CCFLAGS in ?*) assign_CCFLAGS="$assign_CCFLAGS " ;; esac assign_CCFLAGS="$assign_CCFLAGS$2" shift ;; *) break ;; esac done ;; esac done } # collect command line targets and definitions case $_PACKAGE_HOSTTYPE_ in ?*) HOSTTYPE=$_PACKAGE_HOSTTYPE_ KEEP_HOSTTYPE=1 ;; *) KEEP_HOSTTYPE=0 ;; esac KEEP_PACKAGEROOT=0 KEEP_SHELL=0 USER_VPATH= args= assign= assign_CCFLAGS= for i do case $i in *:*=*) args="$args $i" continue ;; *=*) eval $(echo ' ' "$i" | sed 's,^[ ]*\([^=]*\)=\(.*\),n=\1 v='\''\2'\'',') ;; esac case $i in AR=*|LD=*|NM=*) assign="$assign $n='$v'" eval $n='$'v ;; CC=*) eval $n='$'v ;; CCFLAGS=*) eval $n='$'v assign_CCFLAGS="CCFLAGS=\"\$CCFLAGS\"" ;; HOSTTYPE=*) eval $n='$'v case $HOSTTYPE in ?*) KEEP_HOSTTYPE=1 ;; esac ;; PACKAGEROOT=*) eval $n='$'v case $PACKAGEROOT in ?*) KEEP_PACKAGEROOT=1 ;; esac ;; SHELL=*)eval $n='$'v case $SHELL in ?*) KEEP_SHELL=1 ;; esac ;; VPATH=*)eval USER_$n='$'v ;; 'debug=1') makeflags="$makeflags --debug-symbols" ;; 'strip=1') makeflags="$makeflags --strip-symbols" ;; *=*) assign="$assign $n='$v'" ;; *) args="$args $i" ;; esac done case $HOSTTYPE in *,*) hostopts $HOSTTYPE ;; esac case $assign_CCFLAGS in ?*) assign="$assign $assign_CCFLAGS" esac case $CC in ''|cc) ;; *) export CC ;; esac # Add build type flags via KSH_RELFLAGS, which is used in src/cmd/ksh93/Mamfile. # (Avoid using CCFLAGS; setting it would overwrite autodetected optimization flags.) ksh_relflags= case $(git branch 2>/dev/null) in '' | *\*\ [0-9]*.[0-9]*) # If we're not on a git branch (tarball) or on a branch that starts # with a number (release branch), then compile as a release version ksh_relflags="${ksh_relflags:+$ksh_relflags }-D_AST_ksh_release" ;; *) # Otherwise, add 8-character git commit hash if available, and if the working dir is clean git_commit=$(git status >/dev/null 2>&1 && git diff-index --quiet HEAD && git rev-parse --short=8 HEAD) case $git_commit in ????????) ksh_relflags="${ksh_relflags:+$ksh_relflags }-D_AST_git_commit=\\\"$git_commit\\\"" ;; esac unset git_commit ;; esac case $ksh_relflags in ?*) # add the extra flags as an argument to mamake assign="${assign:+$assign }KSH_RELFLAGS=\"\$ksh_relflags\"" ;; esac # Add ksh compile-options via KSH_SHOPTFLAGS. SHOPT() { case $1 in *=?*) ksh_shoptflags="${ksh_shoptflags:+$ksh_shoptflags }-DSHOPT_$1" ;; esac } ksh_shoptflags= shopt_sh='src/cmd/ksh93/SHOPT.sh' # this script calls SHOPT() to set options if test -f "$shopt_sh" then . "$shopt_sh" else echo "WARNING: $shopt_sh is missing" >&2 fi case $ksh_shoptflags in ?*) # add the extra flags as an argument to mamake assign="${assign:+$assign }KSH_SHOPTFLAGS=\"\$ksh_shoptflags\"" ;; esac # grab action specific args case $action in use) case $1 in .|32|64)case $1 in 32|64) bit=$1 ;; esac shift # HOSTTYPE specific setup case $HOSTTYPE in win32.*)sys=uwin wow=$(uname -i) case $bit in 32) case $HOSTTYPE in *-64) HOSTTYPE=${HOSTTYPE%-64} ;; esac ;; 64) case $HOSTTYPE in *-64) ;; *) HOSTTYPE=$HOSTTYPE-64 ;; esac case $wow in */32) echo $command: cannot build $bit-bit on $wow $sys >&2; exit 2 ;; esac ;; esac case $bit in '') PS1="($sys) " ;; *) PS1="($sys-$bit) " ;; esac $exec umask 002 $exec unset MAKESKIP $exec export P=$PWD $exec export A=$P/arch/$HOSTTYPE $exec export CDPATH=:..:$A/src/cmd:$A/src/lib:$A/src/uwin:$P/lib/package $exec export INSTALLROOT=$A $exec export PACKAGEROOT=$P $exec export PATH=$A/bin:$P/bin:$PATH $exec export PS1="$PS1" $exec export VPATH=$A:$P $exec export nativepp=/usr/lib if test '' != "$INSTALLROOT" -a -d $INSTALLROOT/include/ast then $exec export PACKAGE_ast=$INSTALLROOT elif test -d ${PWD%/*}/ast/arch/$HOSTTYPE then $exec export PACKAGE_ast=${PWD%/*}/ast/arch/$HOSTTYPE fi # run the command case $# in 0) case $show in ':') $exec exec $SHELL ;; esac ;; *) $exec exec $SHELL -c "$@" ;; esac exit ;; esac PACKAGEROOT=$PWD $show export PACKAGEROOT esac ;; esac # true if arg is a valid PACKAGEROOT packageroot() # dir { test -d $1/lib/$command -o -x $1/bin/$command } # true if arg is executable executable() # [!] command { case $1 in '!') test ! -x "$2" -a ! -x "$2.exe"; return ;; *) test -x "$1" -o -x "$1.exe"; return ;; esac } # initialize SHELLMAGIC # tangible proof of Cygwin's disdain for Unix (well, this and execrate) shellmagic() { case $SHELLMAGIC in '') ;; -) if test -f /emx/bin/sh.exe then SHELLMAGIC='#!/emx/bin/sh.exe'$nl elif test -f /bin/env.exe then SHELLMAGIC='#!/bin/env sh'$nl else SHELLMAGIC= fi ;; esac } # true if arg is executable command on $PATH onpath() # command { _onpath_b=$1 case $_onpath_b in /*) if executable $_onpath_b then _onpath_=$_onpath_b return 0 fi return 1 ;; esac IFS=':' set '' $PATH IFS=$ifs shift for _onpath_d do case $_onpath_d in '') _onpath_d=. ;; esac if executable "$_onpath_d/$_onpath_b" then _onpath_=$_onpath_d/$_onpath_b return 0 fi done return 1 } # determine local host attributes hostinfo() # attribute ... { case $DEBUG in 1) set -x ;; esac map= something= path=$PATH for i in $ccs do PATH=$PATH:$i done for i in $use do for j in $org do PATH=$PATH:$i/$j/bin done PATH=$PATH:$i/bin done # LD_LIBRARY_PATH may be out of sync with PATH here case $SED in '') SED=sed $SED 1d < /dev/null > /dev/null 2>&1 || for dir in /bin /usr/bin do if test -x $dir/$SED then SED=$dir/$SED break fi done TR=tr $TR < /dev/null > /dev/null 2>&1 || for dir in /bin /usr/bin do if test -x $dir/$TR then TR=$dir/$TR break fi done ;; esac case $PACKAGE_PATH in ?*) for i in $(echo "$PACKAGE_PATH" | "$SED" 's,:, ,g') do PATH=$PATH:$i/bin done ;; esac # validate the args canon= cc=$CC for info do case $canon in -) canon=$info ;; *) case $info in */*|*[cC][cC]) cc=$info ;; canon) canon=- something=1 ;; cpu|name|rating|type) something=1 ;; *) echo "$command: $action: $info: unknown attribute" >&2 exit 1 ;; esac ;; esac done case $canon in -) echo "$command: $action: canon: host type name expected" >&2 exit 1 ;; esac case $something in "") set "$@" type ;; esac case $DEBUG in '') exec 9>&2 exec 2>/dev/null ;; esac # compute the info _hostinfo_= for info do case $info in cpu) case $NPROC in [123456789]*) _hostinfo_="$_hostinfo_ $NPROC" continue ;; esac cpu=$(sysctl -n hw.ncpu) case $cpu in [123456789]*) _hostinfo_="$_hostinfo_ $cpu" continue ;; esac cpu=$(grep -ic '^processor[ ][ ]*:[ ]*[0123456789]' /proc/cpuinfo) case $cpu in [123456789]*) _hostinfo_="$_hostinfo_ $cpu" continue ;; esac cpu=1 # exact match set \ hinv '^Processor [0123456789]' \ psrinfo 'on-line' \ 'cat /reg/LOCAL_MACHINE/Hardware/Description/System/CentralProcessor' '.' \ 'cat /proc/registry/HKEY_LOCAL_MACHINE/Hardware/Description/System/CentralProcessor' '.' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | grep -c "$2") case $i in [123456789]*) cpu=$i break ;; esac shift;shift done case $cpu in 0|1) set \ /bin/mpstat while : do case $# in 0) break ;; esac if executable $1 then case $($1 | grep -ic '^cpu ') in 1) cpu=$($1 | grep -ic '^ *[0123456789][0123456789]* ') break ;; esac fi shift done ;; esac case $cpu in 0|1) # token match set \ /usr/kvm/mpstat 'cpu[0123456789]' \ /usr/etc/cpustatus 'enable' \ /usr/alliant/showsched 'CE' \ 'ls /config/hw/system/cpu' 'cpu' \ prtconf 'cpu-unit' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | $TR ' ' ' ' | grep -c "^$2") case $i in [123456789]*) cpu=$i break ;; esac shift;shift done ;; esac case $cpu in 0|1) # special match set \ \ hinv \ '/^[0123456789][0123456789]* .* Processors*$/' \ '/[ ].*//' \ \ /usr/bin/hostinfo \ '/^[0123456789][0123456789]* .* physically available\.*$/' \ '/[ ].*//' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | $SED -e "${2}!d" -e "s${3}") case $i in [123456789]*) cpu=$i break ;; esac shift;shift;shift done ;; esac case $cpu in 0|1) cpu=$( cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.c < #include int main() { printf("%d\n", pthread_num_processors_np()); return 0; } ! for o in -lpthread '' do if $CC $o -O -o $tmp.exe $tmp.c $o >/dev/null 2>&1 || gcc $o -O -o $tmp.exe $tmp.c $o >/dev/null 2>&1 then ./$tmp.exe break fi done ) case $cpu in [0123456789]*) ;; *) cpu=1 ;; esac ;; esac _hostinfo_="$_hostinfo_ $cpu" ;; name) _name_=$(hostname || uname -n || cat /etc/whoami || echo local) _hostinfo_="$_hostinfo_ $_name_" ;; rating) for rating in $(grep -i ^bogomips /proc/cpuinfo 2>/dev/null | $SED -e 's,.*:[ ]*,,' -e 's,\(...*\)\..*,\1,' -e 's,\(\..\).*,\1,') do case $rating in [0123456789]*) break ;; esac done case $rating in [0123456789]*) ;; *) cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.c < #include #if TD || TZ #include #else extern time_t time(); #endif int main() { register unsigned long i; register unsigned long j; register unsigned long k; unsigned long l; unsigned long m; unsigned long t; int x; #if TD || TZ struct timeval b; struct timeval e; #if TZ struct timezone z; #endif #endif l = 500; m = 890; x = 0; for (;;) { #if TD || TZ #if TZ gettimeofday(&b, &z); #else gettimeofday(&b); #endif #else t = (unsigned long)time((time_t*)0); #endif k = 0; for (i = 0; i < l; i++) for (j = 0; j < 50000; j++) k += j; #if TD || TZ #if TZ gettimeofday(&e, &z); #else gettimeofday(&e); #endif t = (e.tv_sec - b.tv_sec) * 1000 + (e.tv_usec - b.tv_usec) / 1000; if (!x++ && t < 1000) { t = 10000 / t; l = (l * t) / 10; continue; } #else t = ((unsigned long)time((time_t*)0) - t) * 1000; if (!x++ && t < 20000) { t = 200000l / t; l = (l * t) / 10; continue; } #endif #if PR printf("[ k=%lu l=%lu m=%lu t=%lu ] ", k, l, m, t); #endif if (t == 0) t = 1; break; } printf("%lu\n", ((l * m) / 10) / t); return k == 0; } ! rating= for o in -DTZ -DTD '' do if $CC $o -O -o $tmp.exe $tmp.c >/dev/null 2>&1 || gcc $o -O -o $tmp.exe $tmp.c >/dev/null 2>&1 then rating=$(./$tmp.exe) break fi done case $rating in [0123456789]*) ;; *) rating=1 ;; esac ;; esac _hostinfo_="$_hostinfo_ $rating" ;; type|canon) case $CROSS:$canon in 0:) case $cc in cc) case $KEEP_HOSTTYPE:$HOSTTYPE in 0:?*) if test -d ${PACKAGEROOT:-.}/arch/$HOSTTYPE then KEEP_HOSTTYPE=1 fi ;; esac ;; esac case $KEEP_HOSTTYPE in 1) _hostinfo_="$_hostinfo_ $HOSTTYPE" continue ;; esac ;; esac case $cc in /*) a=$($cc -dumpmachine $CCFLAGS 2>/dev/null) case $a in '') case $CCFLAGS in ?*) a=$($cc -dumpmachine 2>/dev/null) ;; esac ;; esac case $a in ''|*' '*|*/*:*) ;; *.*-*) _hostinfo_="$_hostinfo_ $a" continue ;; *-*-*) case $canon in '') canon=$a ;; esac ;; *) _hostinfo_="$_hostinfo_ $a" continue ;; esac ;; esac IFS=: set /$IFS$PATH IFS=$ifs shift f=../lib/hostinfo/typemap for i do case $i in "") i=. ;; esac case $canon in '') case $cc in /*|cc) ;; *) if executable $i/$cc then a=$($i/$cc -dumpmachine $CCFLAGS 2>/dev/null) case $a in '') case $CCFLAGS in ?*) a=$($cc -dumpmachine 2>/dev/null) ;; esac ;; esac case $a in ''|*' '*|*/*:*) ;; *-*) canon=$a ;; *) _hostinfo_="$_hostinfo_ $a" continue 2 ;; esac fi ;; esac ;; esac if test -f "$i/$f" then map="$(grep -v '^#' $i/$f) $map" fi done # inconsistent -dumpmachine filtered here case -${canon}- in --|*-powerpc-*) h=$(hostname || uname -n || cat /etc/whoami) case $h in '') h=local ;; esac a=$(arch || uname -m || att uname -m || uname -s || att uname -s) case $a in *[\ \ ]*) a=$(echo $a | $SED "s/[ ]/-/g") ;; esac case $a in '') a=unknown ;; esac m=$(mach || machine || uname -p || att uname -p) case $m in *[\ \ ]*) m=$(echo $m | $SED "s/[ ]/-/g") ;; esac case $m in '') m=unknown ;; esac x=$(uname -a || att uname -a) case $x in '') x="unknown $host unknown unknown unknown unknown unknown" ;; esac set "" $h $a $m $x expected=$1 host=$2 arch=$3 mach=$4 os=$5 sys=$6 rel=$7 ver=$8 ;; *) case $canon in *-*) IFS=- set "" $canon shift IFS=$ifs case $# in 2) host= mach= arch=$1 os=$2 sys= rel= ;; *) host= mach=$2 arch=$1 os=$3 sys= rel= ;; esac case $os in [abcdefghijklmnopqrstuvwxyz]*[0123456789]) eval $(echo $os | $SED -e 's/^\([^0123456789.]*\)\.*\(.*\)/os=\1 rel=\2/') ;; esac ;; *) arch=$canon mach= os= sys= rel= ;; esac ;; esac type=unknown case $host in *.*) host=$(echo $host | $SED -e 's/\..*//') ;; esac case $mach in unknown) mach= ;; [Rr][0123][0123456789][0123456789][0123456789]) mach=mips1 ;; [Rr][4][0123456789][0123456789][0123456789]) mach=mips2 ;; [Rr][56789][0123456789][0123456789][0123456789]|[Rr][123456789][0123456789][0123456789][0123456789][0123456789]) mach=mips4 ;; pc) arch=i386 mach= ;; [Pp][Oo][Ww][Ee][Rr][Pp][Cc]) arch=ppc mach= ;; *) case $arch in 34[0123456789][0123456789]) os=ncr arch=i386 ;; esac ;; esac case $canon in '') set \ \ /NextDeveloper -d next - \ /config/hw/system/cpu -d tandem mach \ while : do case $# in 0) break ;; esac if test $2 $1 then os=$3 case $4 in arch) mach=$arch ;; mach) arch=$mach ;; esac break fi shift;shift;shift;shift done ;; esac case $os in AIX*|aix*) type=ibm.risc ;; HP-UX) case $arch in 9000/[78]*) type=hp.pa ;; */*) type=hp.$(echo $arch | $SED 's,/,_,g') ;; *) type=hp.$arch ;; esac ;; [Ii][Rr][Ii][Xx]*) set xx $(hinv | $SED -e '/^CPU:/!d' -e 's/CPU:[ ]*\([^ ]*\)[ ]*\([^ ]*\).*/\1 \2/' -e q | $TR ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) shift type=$1 n= case $2 in r[0123][0123456789][0123456789][0123456789]) n=1 ;; r[4][0123][0123456789][0123456789]) n=2 ;; r[4][456789][0123456789][0123456789]|r[5][0123456789][0123456789][0123456789]) n=3 ;; r[6789][0123456789][0123456789][0123456789]|r[123456789][0123456789][0123456789][0123456789][0123456789]) n=4 ;; esac case $rel in [01234].*|5.[012]|5.[012].*) case $n in 1) ;; *) n=2 ;; esac ;; 5.*) case $n in 2) n=3 ;; esac ;; esac if executable $cc then a=$cc else IFS=: set /$IFS$PATH IFS=$ifs shift for i do a=$i/$cc if executable $a then break fi done fi split=' ' a=$(strings $a < /dev/null | $SED -e 's/[^abcdefghijklmnopqrstuvwxyz0123456789]/ /g' -e 's/[ ][ ]*/\'"$split"'/g' | $SED -e "/^${type}[0123456789]$/!d" -e "s/^${type}//" -e q) case $a in [0123456789]) n=$a ;; esac case $n in 4) a=$($cc -${type}3 2>&1) case $a in *unknown*|*install*|*conflict*) ;; *) n=3 ;; esac ;; esac a=$($cc -show F0oB@r.c 2>&1) case $n:$a in [!2]:*mips2*) n=2 ;; [!23]:*mips3*) n=3 ;; [!234]:*mips4*) n=4 ;; esac case $n:$a in [!2]:*[Oo]32*) abi=-o32 ;; [!3]:*[Nn]32*) abi=-n32 ;; esac mach=${type}$n type=sgi.$mach ;; OSx*|SMP*|pyramid) type=pyr ;; OS/390) type=mvs.390 ;; [Ss][Cc][Oo]*) type=sco ;; [Ss]ol*) v=$(echo $rel | $SED -e 's/^[25]\.//' -e 's/\.[^.]*$//') case $v in [6789]|[1-9][0-9]) ;; *) v= ;; esac case $arch in '') case $mach in '') arch=sun4 ;; *) arch=$mach ;; esac ;; esac case $arch in sparc) arch=sun4 ;; esac type=sol$v.$arch ;; [Ss]un*)type=$(echo $arch | $SED -e 's/\(sun.\).*/\1/') case $type in sparc) type=sun4 ;; esac case $rel in [01234]*) ;; '') case $os in *[Oo][Ss]) ;; *) type=sol.$type ;; esac ;; *) case $type in '') case $mach in sparc*) type=sun4 ;; *) type=$mach ;; esac ;; esac v=$(echo $rel | $SED -e 's/^[25]\.//' -e 's/\.[^.]*$//') case $v in [6789]|[1-9][0-9]) ;; *) v= ;; esac type=sol$v.$type ;; esac case $type in sun*|*.*) ;; *) type=sun.$type ;; esac ;; [Uu][Nn][Ii][Xx]_[Ss][Vv]) type=unixware ;; UTS*|uts*) if test -x /bin/u370 -o -x /bin/u390 then type=uts.390 else case $arch in '') arch=$mach ;; esac type=uts.$arch fi ;; $host) type=$arch case $type in *.*|*[0123456789]*86|*68*) ;; *) case $mach in *[0123456789]*86|*68*|mips) type=$type.$mach ;; esac ;; esac ;; unknown) case $arch in ?*) case $arch in sun*) mach= ;; esac type=$arch case $mach in ?*) type=$type.$mach ;; esac ;; esac ;; *) case $ver in FTX*|ftx*) case $mach in *[0123456789][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*) mach=$(echo $mach | $SED -e 's/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*$//') ;; esac type=stratus.$mach ;; *) case $arch in [Oo][Ss][-/.]2) type=os2 arch=$rel ;; *) type=$(echo $os | $SED -e 's/[0123456789].*//' -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789.].*//') ;; esac case $type in [Cc][Yy][Gg][Ww][Ii][Nn]_*) type=cygwin ;; [Uu][Ww][Ii][Nn]*|[Ww]indows_[0123456789][0123456789]|[Ww]indows_[Nn][Tt]) type=win32 arch=$(echo $arch | $SED -e 's/_[^_]*$//') ;; esac case $arch in '') case $mach in ?*) type=$type.$mach ;; esac ;; *) type=$type.$arch ;; esac ;; esac esac case $type in [0123456789]*) case $mach in ?*) type=$mach ;; esac case $type in */MC) type=ncr.$type ;; esac ;; *.*) ;; *[0123456789]*86|*68*) case $rel in [34].[0123456789]*) type=att.$type ;; esac ;; [abcdefghijklmnopqrstuvwxyz]*[0123456789]) ;; [abcdefghijklmnopqrstuvwxyz]*) case $mach in $type) case $ver in Fault*|fault*|FAULT*) type=ft.$type ;; esac ;; ?*) case $arch in '') type=$type.$mach ;; *) type=$type.$arch ;; esac ;; esac ;; esac case $type in *[-_]32|*[-_]64|*[-_]128) bits=$(echo $type | $SED 's,.*[-_],,') type=$(echo $type | $SED 's,[-_][0-9]*$,,') ;; *) bits= ;; esac type=$(echo $type | $SED -e 's%[-+/].*%%' | $TR ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) case $type in *.*) lhs=$(echo $type | $SED -e 's/\..*//') rhs=$(echo $type | $SED -e 's/.*\.//') case $rhs in [x0123456789]*86) rhs=i$rhs ;; 68*) rhs=m$rhs ;; esac case $rhs in i[x23456789]86|i?[x23456789]86|*86pc) rhs=i386 ;; powerpc) rhs=ppc ;; s[0123456789]*[0123456789]x) rhs=$(echo $rhs | $SED -e 's/x$/-64/') ;; esac case $rhs in arm[abcdefghijklmnopqrstuvwxyz_][0123456789]*) rhs=arm ;; hppa) rhs=pa ;; esac case $lhs in ?*coff|?*dwarf|?*elf) case $lhs in ?*coff) x=coff ;; ?*dwarf)x=coff ;; ?*elf) x=elf ;; esac lhs=$(echo ${lhs}XXX | $SED -e "s/${x}XXX//") ;; esac case $lhs in bsdi) lhs=bsd ;; darwin) case $(/usr/bin/cc --version) in *'(GCC)'*) case $rel in [0-9].*|10.*) lhs=darwin07 ;; *) lhs=darwin11 ;; esac ;; esac ;; freebsd) case $rel in [01234].*) lhs=${lhs}4 ;; [123456789]*.*) lhs=${lhs}$(echo $rel | $SED -e 's/\..*//') ;; esac ;; hpux) lhs=hp ;; mvs) rhs=390 ;; esac case $lhs in '') type=$rhs ;; $rhs) type=$lhs ;; *) type=$lhs.$rhs ;; esac ;; esac case $type in sgi.mips*) case $mach in mips2) type=sgi.$mach abi=-o32 ;; mips3) type=sgi.$mach abi=-n32 ;; mips[456789]) type=sgi.$mach case $abi in *-n32) ;; *) abi=-64 ;; esac ;; *) pwd=$PWD cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.a.c < $tmp.b.c </dev/null 2>&1 rm -f $tmp.* trap - 0 1 2 cd $pwd ;; esac case $type$abi in sgi.mips2-o32) ;; sgi.mips3) type=$type-o32 ;; sgi.mips3-n32) ;; sgi.mips4) type=$type-o32 ;; sgi.mips[456789]-64) ;; *) type=$type$abi ;; esac ;; *) case $bits in '') bits=$( cd "$TMPDIR" LC_ALL=C export LC_ALL tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 echo 'int main() { return 0; }' > $tmp.a.c $cc $CCFLAGS -o $tmp.a.exe $tmp.a.c /dev/null 2>&1 file $tmp.a.exe 2>/dev/null | sed "s/$tmp\.a\.exe//g" ) case $bits in *\ 64-bit* | *\ 64\ bit* | *\ 64bit*) bits=64 ;; *) bits= ;; esac ;; esac ;; esac case $bits in 32) case $type in *.i386) bits= ;; esac ;; esac case $bits in ?*) type=$type-$bits ;; esac # last chance mapping set "" "" $map while : do case $# in [012]) break ;; esac shift;shift eval " case \$type in $1) type=\$2; break ;; esac" done _hostinfo_="$_hostinfo_ $type" ;; esac done set '' $_hostinfo_ shift _hostinfo_=$* # restore the global state PATH=$path case $DEBUG in '') exec 2>&9 exec 9>&- ;; esac } # info message note() # message ... { echo $command: "$@" >&2 } # cc checks # # CC: compiler base name name # cc: full path, empty if not found checkcc() { cc= if onpath $CC then cc=$_onpath_ else case $CC in cc) if onpath gcc then CC=gcc cc=$_onpath_ fi ;; esac fi case $cc in '') case $action in make|test) note "$CC: not found"; exit 1 ;; *) note "warning: $CC: not found" ;; esac ;; esac } # some actions have their own PACKAGEROOT or kick out early case $action in host) eval u=$package_use case $u in $PACKAGE_USE) ;; *) if onpath $0 then case $_onpath_ in */arch/$HOSTTYPE/bin/package) KEEP_HOSTTYPE=1 ;; *) KEEP_HOSTTYPE=0 ;; esac else KEEP_HOSTTYPE=0 fi ;; esac hostinfo $args echo $_hostinfo_ exit 0 ;; export|setup|use) x= ;; *) x= eval u=$package_use case $u in $PACKAGE_USE) case :$PATH: in *:$INSTALLROOT/bin:*) case $LIBPATH: in $INSTALLROOT/bin:$INSTALLROOT/lib:*) case $SHLIB_PATH: in $INSTALLROOT/lib:*) x=1 ;; esac ;; esac ;; esac ;; esac ;; esac run=- case $x in 1) : accept the current package use environment OK=ok KSH=$EXECROOT/bin/ksh MAKE=mamake SUM=$EXECROOT/bin/sum TEE=$EXECROOT/bin/tee INITROOT=$PACKAGEROOT/src/cmd/INIT checkcc ;; *) hosttype= case $KEEP_PACKAGEROOT in 0) case $action in use) PACKAGEROOT= case $show in echo) exec=echo make=echo show=echo ;; esac set '' $args shift case $# in 0) ;; *) case $1 in -|.) ;; /*) PACKAGEROOT=$1 ;; *) i=$(echo ~$1) if packageroot $i then PACKAGEROOT=$i else for i in $(echo $HOME | sed -e 's,/[^/]*$,,') $usr $use do if packageroot $i/$1 then PACKAGEROOT=$i/$1 break fi done case $PACKAGEROOT in '') hosttype=$1 ;; esac fi ;; esac shift ;; esac run="$@" ;; esac case $PACKAGEROOT in '') PACKAGEROOT=$PWD ;; esac # . must be within the PACKAGEROOT tree i=X$PACKAGEROOT IFS=/ set $i IFS=$ifs while : do i=$1 shift case $i in X) break ;; esac done case $PACKAGEROOT in //*) d=/ ;; *) d= ;; esac case $1 in home) k=1 ;; *) k=0 ;; esac for i do case $i in '') continue ;; esac d=$d/$i case $k in 2) k=1 ;; 1) k=0 ;; 0) case $i in arch) k=2 ;; *) if packageroot $d then PACKAGEROOT=$d fi ;; esac ;; esac done ;; esac INITROOT=$PACKAGEROOT/src/cmd/INIT $show PACKAGEROOT=$PACKAGEROOT $show export PACKAGEROOT export PACKAGEROOT # initialize the architecture environment case $KEEP_HOSTTYPE in 0) hostinfo type HOSTTYPE=$_hostinfo_ ;; 1) _PACKAGE_HOSTTYPE_=$HOSTTYPE export _PACKAGE_HOSTTYPE_ ;; esac $show HOSTTYPE=$HOSTTYPE $show export HOSTTYPE export HOSTTYPE INSTALLROOT=$PACKAGEROOT/arch/$HOSTTYPE case $action in install|make|remove|test|view) ;; *) if test ! -d $INSTALLROOT then INSTALLROOT=$PACKAGEROOT fi ;; esac $show INSTALLROOT=$INSTALLROOT $show export INSTALLROOT export INSTALLROOT # check the basic package hierarchy case $action in export|use) packageroot $PACKAGEROOT || { echo "$command: $PACKAGEROOT: invalid package root directory" >&2 exit 1 } case $KEEP_HOSTTYPE:$hosttype in 0:?*) if test -d ${PACKAGEROOT:-.}/arch/$hosttype then KEEP_HOSTTYPE=1 HOSTTYPE=$hosttype else echo "$command: $hosttype: package root not found" >&2 exit 1 fi ;; esac ;; *) packageroot $PACKAGEROOT || { case $KEEP_PACKAGEROOT in 1) ;; *) echo "$command: $PACKAGEROOT: must be in the package root directory tree" >&2 exit 1 ;; esac } for i in arch arch/$HOSTTYPE do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || exit done for i in lib do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done # no $INITROOT means INIT already installed elsewhere if test -d $INITROOT then # update the basic package commands for i in execrate ignore mamprobe silent do test -h $PACKAGEROOT/bin/$i 2>/dev/null || case $(ls -t $INITROOT/$i.sh $PACKAGEROOT/bin/$i 2>/dev/null) in "$INITROOT/$i.sh"*) note update $PACKAGEROOT/bin/$i shellmagic case $SHELLMAGIC in '') $exec cp $INITROOT/$i.sh $PACKAGEROOT/bin/$i || exit ;; *) case $exec in '') { echo "$SHELLMAGIC" cat $INITROOT/$i.sh } > $PACKAGEROOT/bin/$i || exit ;; *) echo "{ echo \"$SHELLMAGIC\" cat $INITROOT/$i.sh } > $PACKAGEROOT/bin/$i" ;; esac ;; esac $exec chmod +x $PACKAGEROOT/bin/$i || exit ;; esac done fi ;; esac path=$PATH PATH=$INSTALLROOT/bin:$PACKAGEROOT/bin:$PATH checkcc PATH=$path case $cc in ?*) if test -f $INITROOT/hello.c then # check if $CC (full path $cc) is a cross compiler ( cd "$TMPDIR" || exit 3 cp $INITROOT/hello.c pkg$$.c || exit 3 $cc -o pkg$$.exe pkg$$.c > pkg$$.e 2>&1 || { if $cc -Dnew=old -o pkg$$.exe pkg$$.c > /dev/null 2>&1 then echo "$command: ${warn}$CC: must be a C compiler (not C++)" >&2 else cat pkg$$.e echo "$command: ${warn}$CC: failed to compile and link $INITROOT/hello.c -- is it a C compiler?" >&2 fi exit 2 } if ./pkg$$.exe >/dev/null 2>&1 then code=0 else code=1 fi rm -f pkg$$.* exit $code ) code=$? case $code in 1) CROSS=1 ;; esac fi ;; esac EXECTYPE=$HOSTTYPE EXECROOT=$INSTALLROOT case $CROSS in 0) # dll hackery -- why is this so complicated? abi= case $HOSTTYPE in sgi.mips[0123456789]*) x=rld if executable /lib32/$x || executable /lib64/$x then case $INSTALLROOT in */sgi.mips[0123456789]*) u=$(echo $INSTALLROOT | sed -e 's,-[^-/]*$,,' -e 's,.$,,') ;; *) u= ;; esac for a in "n=2 v= l=" "n=3 v=N32 l=lib32" "n=4-n32 v=N32 l=lib32" "n=4 v=64 l=lib64" do eval $a case $v in N32) case $n:$HOSTTYPE in *-n32:*-n32) ;; *-n32:*) continue ;; *:*-n32) continue ;; esac ;; esac case $l in ?*) if executable ! /$l/$x then continue fi ;; esac case $u in '') case $HOSTTYPE in sgi.mips$n|sgi.mips$n-*) abi="$abi 'd=$INSTALLROOT v=$v'" ;; *) continue ;; esac ;; *) if test -d $u$n then abi="$abi 'd=$u$n v=$v'" fi ;; esac done fi ;; esac case $abi in '') abi="'d=$INSTALLROOT v='" ;; esac p=0 eval " for a in $abi do eval \$a eval \" case \\\$LD_LIBRARY\${v}_PATH: in \\\$d/lib:*) ;; *) x=\\\$LD_LIBRARY\${v}_PATH case \\\$x in ''|:*) ;; *) x=:\\\$x ;; esac LD_LIBRARY\${v}_PATH=\$d/lib\\\$x export LD_LIBRARY\${v}_PATH p=1 ;; esac \" done " case $LD_LIBRARY_PATH in '') ;; *) for d in $lib do case $HOSTTYPE in *64) if test -d ${d}64 then d=${d}64 fi ;; esac case :$LD_LIBRARY_PATH: in *:$d:*) ;; *) if test -d $d then LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$d p=1 fi ;; esac done ;; esac case $p in 1) $show LD_LIBRARY_PATH=$LD_LIBRARY_PATH $show export LD_LIBRARY_PATH export LD_LIBRARY_PATH ;; esac case $LIBPATH: in $INSTALLROOT/bin:$INSTALLROOT/lib:*) ;; *) case $LIBPATH in '') LIBPATH=/usr/lib:/lib ;; esac LIBPATH=$INSTALLROOT/bin:$INSTALLROOT/lib:$LIBPATH $show LIBPATH=$LIBPATH $show export LIBPATH export LIBPATH ;; esac case $SHLIB_PATH: in $INSTALLROOT/lib:*) ;; *) SHLIB_PATH=$INSTALLROOT/lib${SHLIB_PATH:+:$SHLIB_PATH} $show SHLIB_PATH=$SHLIB_PATH $show export SHLIB_PATH export SHLIB_PATH ;; esac case $DYLD_LIBRARY_PATH: in $INSTALLROOT/lib:*) ;; *) DYLD_LIBRARY_PATH=$INSTALLROOT/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH} $show DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH $show export DYLD_LIBRARY_PATH export DYLD_LIBRARY_PATH ;; esac case $_RLD_ROOT in $INSTALLROOT/arch*) ;; ':') _RLD_ROOT=$INSTALLROOT/arch:/ ;; /|*:/) _RLD_ROOT=$INSTALLROOT/arch:$_RLD_ROOT ;; *) _RLD_ROOT=$INSTALLROOT/arch:$_RLD_ROOT:/ ;; esac $show _RLD_ROOT=$_RLD_ROOT $show export _RLD_ROOT export _RLD_ROOT # now set up PATH # # NOTE: PACKAGEROOT==INSTALLROOT is possible for binary installations case $PATH: in $PACKAGEROOT/bin:*) ;; *) PATH=$PACKAGEROOT/bin:$PATH ;; esac case $PATH: in $INSTALLROOT/bin:*) ;; *) PATH=$INSTALLROOT/bin:$PATH ;; esac $show PATH=$PATH $show export PATH export PATH ;; *) for i in package proto do if onpath $i then EXECROOT=$(echo $_onpath_ | sed -e 's,//*[^/]*//*[^/]*$,,') EXECTYPE=$(echo $EXECROOT | sed -e 's,.*/,,') break fi done case $HOSTTYPE in $EXECTYPE) OCC=$CC CC=cc hostinfo type EXECTYPE=$_hostinfo_ case $HOSTTYPE in $EXECTYPE) echo "$command: $CC: seems to be a cross-compiler" >&2 echo "$command: set HOSTTYPE to something other than the native $EXECTYPE" >&2 echo "$command: If not, your $TMPDIR directory may be mounted without execute permission." >&2 echo "$command: Try exporting TMPDIR as a directory where you can execute binary files." >&2 exit 1 ;; esac ;; esac $show EXECTYPE=$EXECTYPE $show export EXECTYPE export EXECTYPE ;; esac $show EXECROOT=$EXECROOT $show export EXECROOT export EXECROOT # use these if possible OK=ok KSH=$EXECROOT/bin/ksh MAKE=mamake SUM=$EXECROOT/bin/sum TEE=$EXECROOT/bin/tee # grab a decent default shell checksh "$SHELL" || KEEP_SHELL=0 case $KEEP_SHELL in 0) save_PATH=$PATH if PATH=$(getconf PATH 2>/dev/null) then PATH=$PATH:$path else PATH=/bin:/usr/bin:/sbin:/usr/sbin:$path fi for i in ksh ksh93 mksh yash bash sh do if onpath "$i" && checksh "$_onpath_" then SHELL=$_onpath_ KEEP_SHELL=1 break fi done PATH=$save_PATH unset save_PATH case $KEEP_SHELL in 0) echo "Cannot find good default shell, please supply SHELL=/path/to/shell" >&2 exit 1 ;; esac ;; esac export SHELL $show SHELL=$SHELL $show export SHELL # tame the environment case $action in use) ;; *) ENV= ERROR_OPTIONS= export ENV ERROR_OPTIONS ;; esac # finalize the views case $USER_VPATH in '') case $VPATH in ?*) IFS=':' set '' $VPATH shift IFS=$ifs USER_VPATH= for i do case $i in */arch/$HOSTTYPE) ;; */arch/*/*) ;; */arch/*) continue ;; esac if packageroot $i then case $USER_VPATH in '') USER_VPATH=$i ;; ?*) USER_VPATH=$USER_VPATH:$i ;; esac fi done esac ;; esac case $USER_VPATH in ?*) IFS=':' set '' $USER_VPATH shift IFS=$ifs USER_VPATH= USER_VPATH_CHAIN= p=$PACKAGEROOT for i do case $i in ''|$PACKAGEROOT|$INSTALLROOT) ;; ?*) USER_VPATH=$USER_VPATH:$i USER_VPATH_CHAIN="$USER_VPATH_CHAIN $p $i" p=$i case $PROTOROOT in -) executable $i/bin/mamake && PROTOROOT= ;; esac ;; esac done ;; esac ;; esac PACKAGEBIN=$INSTALLROOT/lib/package case $action:$run in use:-) set '' $args shift case $# in 0) ;; *) shift ;; esac run="$@" ;; esac # HOSTTYPE specific package profile if test -r $INSTALLROOT/lib/package/profile then . $INSTALLROOT/lib/package/profile fi # more Cygwin hassles case $HOSTTYPE in cygwin.*) lose= case $CYGWIN in *nontsec*) lose=ntsec ;; *ntsec*);; *) exe=$TMPDIR/pkg$$.exe rm -f "$exe" : > "$exe" if test -x "$exe" then lose=ntsec fi ;; esac case $CYGWIN in *nobinmode*) case $lose in '') lose=binmode ;; *) lose="$lose binmode" ;; esac ;; esac case $lose in ?*) echo "$command: $HOSTTYPE: export '$lose' in CYGWIN or languish in Windows" >&2 exit 1 ;; esac ;; esac # set up the view state VIEW_bin=$INSTALLROOT VIEW_src=$PACKAGEROOT VIEW_all="$INSTALLROOT $PACKAGEROOT" VPATH=$INSTALLROOT:$PACKAGEROOT$USER_VPATH $show VPATH=$VPATH $show export VPATH export VPATH IFS=':' set '' $VPATH shift IFS=$ifs for i do case $i in */arch/*/*) VIEW_src="$VIEW_src $i" ;; */arch/*) VIEW_bin="$VIEW_bin $i" ;; *) VIEW_src="$VIEW_src $i" ;; esac VIEW_all="$VIEW_all $i" done # return 0 if arg in src|bin|all view view() # [test] [-|type] [src|bin|all] file { case $1 in -[dfsx])_view_T_=$1; shift ;; *) _view_T_=-f ;; esac case $1 in -) _view_t_= ;; *) _view_t_=$1 ;; esac shift case $1 in all) shift; _view_v_=$VIEW_all ;; bin) shift; _view_v_=$VIEW_bin ;; src) shift; _view_v_=$VIEW_src ;; *) _view_v_=$VIEW_all ;; esac case $1 in /*) if test $_view_T_ $1 then _view_=$1 return 0 fi ;; *) for _view_d_ in $_view_v_ do if test $_view_T_ $_view_d_/$1 then _view_=$_view_d_/$1 return 0 fi done ;; esac _view_= case $_view_t_ in ?*) echo $command: $1: $_view_t_ not found >&2 ;; esac return 1 } # determine the package and targets case $action in *) package= target= set '' $args while : do shift case $# in 0) break ;; esac case $1 in ''|-) target="$target $package" package= ;; *) if view - src "lib/package/$1.pkg" then package="$package $1" else target="$target $package $1" package= fi ;; esac done ;; esac # check that cmd args are up to date a.out's checkaout() # cmd ... { case $PROTOROOT in -) PROTOROOT= case $* in ratz) if test -f $INITROOT/ratz.c -a -w $PACKAGEROOT then test -f $INITROOT/hello.c || { cat > $INITROOT/hello.c <<'!' #ifndef printf #include #endif int main() { int new = 0; printf("hello world\n"); return new;} ! } test -f $INITROOT/p.c || { cat > $INITROOT/p.c <<'!' /* * small test for prototyping cc */ int main(int argc, char** argv) { return argc || argv; } ! } fi ;; esac test -f $INITROOT/hello.c -a -f $INITROOT/p.c -a -w $PACKAGEROOT || { for i do onpath $i || { echo "$command: $i: command not found" >&2 return 1 } done return 0 } case $cc in '') _PACKAGE_cc=0 ;; *) _PACKAGE_cc=1 test -f $INITROOT/hello.c -a -f $INITROOT/p.c || { echo "$command: $INITROOT: INIT package source not found" >&2 return 1 } # check for prototyping cc # NOTE: proto.c must be K&R compatible $CC -c $INITROOT/p.c >/dev/null 2>&1 c=$? rm -f p.* test 0 != "$c" && { checkaout proto || return PROTOROOT=$PACKAGEROOT/proto $show PROTOROOT=$PACKAGEROOT/proto export PROTOROOT INITPROTO=$PROTOROOT/src/cmd/INIT note proto convert $PACKAGEROOT/src into $PROTOROOT/src dirs="src" ( if test -f $PROTOROOT/UPDATE then newer="-newer $PROTOROOT/UPDATE" else newer="" fi case $exec in '') cd $PACKAGEROOT find $dirs -name '*.[CcHh]' $newer -print | proto -v -L - -C proto ;; *) $exec cd $PACKAGEROOT $exec "find $dirs -name '*.[CcHh]' $newer -print | proto -L - -C proto" ;; esac $exec touch $PROTOROOT/UPDATE ) VPATH=$INSTALLROOT:$PROTOROOT:$PACKAGEROOT$USER_VPATH $show VPATH=$VPATH export VPATH } for i in arch arch/$HOSTTYPE arch/$HOSTTYPE/bin do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || return done ;; esac ;; esac case $_PACKAGE_cc in '') case $cc in '') _PACKAGE_cc=0 ;; *) _PACKAGE_cc=1 ;; esac ;; esac for i do eval j=\$_PACKAGE_AOUT_$i case $j in '') eval _PACKAGE_AOUT_$i=1 ;; *) continue ;; esac k=$_PACKAGE_cc if test -f $INITROOT/$i.c then k=${k}1 else k=${k}0 fi if executable $EXECROOT/bin/$i then k=${k}1 else k=${k}0 fi : $k : compiler : source : binary : case $k in *00) view - bin/$i && continue ;; esac case $k in 000) echo "$command: $i: not found: download the INIT package $HOSTTYPE binary to continue" >&2 return 1 ;; 010) echo "$command: $i: not found: set CC=C-compiler or download the INIT package $HOSTTYPE binary to continue" >&2 return 1 ;; 100) echo "$command: $i: not found: download the INIT package source or $HOSTTYPE binary to continue" >&2 return 1 ;; 110) case $CROSS in 1) echo "$command: $i: not found: make the local $EXECTYPE binary package before $HOSTTYPE" >&2 return 1 ;; esac ;; ?01) : accept binary continue ;; 011) : accept binary continue ;; ??1) case $CROSS in 1) continue ;; esac ;; esac case $(ls -t $INITROOT/$i.c $INSTALLROOT/bin/$i 2>/dev/null) in "$INITROOT/$i.c"*) note update $INSTALLROOT/bin/$i if test proto != "$i" && executable $INSTALLROOT/bin/proto then case $exec in '') $INSTALLROOT/bin/proto -p $INITROOT/$i.c > $i.c || return ;; *) $exec "$INSTALLROOT/bin/proto -p $INITROOT/$i.c > $i.c" ;; esac $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $i.c || return $exec rm -f $i.c else if test ! -d $INSTALLROOT/bin then for j in arch arch/$HOSTTYPE arch/$HOSTTYPE/bin do test -d $PACKAGEROOT/$j || $exec mkdir $PACKAGEROOT/$j || return done fi if test '' != "$PROTOROOT" -a -f $INITPROTO/$i.c then $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $INITPROTO/$i.c || return else $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $INITROOT/$i.c || return fi case $i:$exec in proto:) test -d $INSTALLROOT/include || mkdir $INSTALLROOT/include $INSTALLROOT/bin/proto -f /dev/null > $i.c cmp -s $i.c $INSTALLROOT/include/prototyped.h 2>/dev/null || cp $i.c $INSTALLROOT/include/prototyped.h rm $i.c ;; esac fi test -f $i.o && $exec rm -f $i.o i=$PATH PATH=/bin PATH=$i ;; esac done return 0 } # list main environment values showenv() { case $1 in ''|make)for __i__ in CC SHELL $env do eval echo $__i__='$'$__i__ done ;; esac } # capture command output capture() # file command ... { tee_pid= case $make:$noexec in :) case $action in install|make|view) o=$action ;; *) case $package in ''|*' '*) o=$action ;; *) o=$package ;; esac ;; esac d=$PACKAGEBIN/gen test -d $d || $exec mkdir $d o=$d/$o case $o in $output)o=$o.out s= ;; *) output=$o if test -f $o.old then mv $o.old $o.out.1 if test -f $o.out then mv $o.out $o.out.2 fi elif test -f $o.out then for i in $(ls -t $o.out.? 2>/dev/null) do break done case $i in *.1) i=2 ;; *.2) i=3 ;; *.3) i=4 ;; *.4) i=5 ;; *.5) i=6 ;; *.6) i=7 ;; *.7) i=8 ;; *.8) i=9 ;; *) i=1 ;; esac mv $o.out $o.out.$i fi o=$o.out : > $o note $action output captured in $o s="$command: $action start at $(date) in $INSTALLROOT" case $quiet in 0) cmd="echo \"$command: $action done at \$(date)\" in $INSTALLROOT 2>&1 | \$TEE -a $o" ;; *) cmd="echo \"$command: $action done at \$(date)\" in $INSTALLROOT >> $o" ;; esac trap "$cmd" 0 trap "$cmd; trap 1 0; kill -1 $$" 1 trap "$cmd; trap 2 0; kill -2 $$" 2 ;; esac case $quiet in 0) if executable ! $TEE then TEE=tee fi # Connect 'tee' to a FIFO instead of a pipe, so that we can obtain # the build's exit status and use it for $error_status rm -f $o.fifo mkfifo -m 600 $o.fifo || exit ( sleep 1 # unlink early exec rm $o.fifo ) & $TEE -a $o < $o.fifo & tee_pid=$! o=$o.fifo ;; esac { case $s in ?*) echo "$s" ;; esac showenv $action "$@" } < /dev/null > $o 2>&1 ;; *) $make "$@" ;; esac exit_status=$? if test "$exit_status" -gt "$error_status" then error_status=$exit_status fi case $tee_pid in ?*) # allow 'tee' to catch up before returning to prompt wait "$tee_pid" ;; esac } make_recurse() # dir { for _make_recurse_j in $makefiles do if view - $1/$_make_recurse_j then return fi done } # check for native ASCII 0:yes 1:no __isascii__= isascii() { case $__isascii__ in '') case $(echo A | od -o | sed -e 's/[ ]*$//' -e '/[ ]/!d' -e 's/.*[ ]//') in 005101|040412) __isascii__=0 ;; *) __isascii__=1 ;; esac esac return $__isascii__ } error_status=0 case $action in clean|clobber) cd $PACKAGEROOT $exec rm -rf arch/$HOSTTYPE exit ;; export) case $INSTALLROOT in $PACKAGEROOT) INSTALLROOT=$INSTALLROOT/arch/$HOSTTYPE ;; esac case $only in 0) v='$i=' ;; *) v= ;; esac set '' $target $package case $# in 1) set '' $env ;; esac while : do case $# in 1) break ;; esac shift i=$1 eval echo ${v}'$'${i} done ;; install)cd $PACKAGEROOT echo "A proper installation command is coming back soon, sorry." >&2 echo "Meanwhile, copy ksh and shcomp from: $INSTALLROOT/arch/$HOSTTYPE/bin" >&2 exit 1 ;; make|view) cd $PACKAGEROOT # check for some required commands must="$AR" warn="$NM yacc bison" test="$must $warn" have= IFS=: set /$IFS$PATH IFS=$ifs shift for t in $test do if executable $t then have="$have $t" fi done for d do for t in $test do case " $have " in *" $t "*) ;; *) if executable $d/$t then have="$have $t" fi ;; esac done done case " $have " in *" bison "*) ;; *" yacc "*) have="$have bison" ;; esac case " $have " in *" yacc "*) ;; *" bison "*) have="$have yacc" ;; esac for t in $test do case " $have " in *" $t "*) ;; *) case " $must " in *" $t "*) echo "$command: $t: not found -- must be on PATH to $action" >&2 exit 1 ;; *) echo "$command: warning: $t: not found -- some $action actions may fail" >&2 ;; esac ;; esac done # verify the top view if test ! -d $PACKAGEROOT/src then note no source packages to make exit 0 elif test ! -d $INSTALLROOT/src then note initialize the $INSTALLROOT view fi for i in arch arch/$HOSTTYPE do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || exit done for i in bin bin/$OK bin/$OK/lib fun include lib lib/package lib/package/gen src man man/man1 man/man3 man/man8 do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done make_recurse src o= k= for i in $makefiles do case $o in ?*) o="$o -o" k="$k|" ;; esac o="$o -name $i" k="$k$i" done o="( $o ) -print" for d in $src do i=src/$d if test -d $i then test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit make_recurse $i for j in $(cd $i; find . $o 2>/dev/null | sed -e 's,^\./,,' -e '/\//!d' -e 's,/[^/]*$,,' | sort -u) do case $j in $k|$MAKESKIP) continue ;; esac test -d $INSTALLROOT/$i/$j || $exec mkdir -p $INSTALLROOT/$i/$j || exit done fi done # check $CC and { ar cc ld ldd } intercepts h="${HOSTTYPE} ${HOSTTYPE}.*" case $HOSTTYPE in *.*) t=$(echo $HOSTTYPE | sed 's/[.][^.]*//') h="$h $t" ;; *) t=$HOSTTYPE ;; esac case $t in *[0123456789]) t=$(echo $t | sed 's/[0123456789]*$//') h="$h $t" ;; esac case $CC in cc) c=cc b=$INSTALLROOT/bin/$c t=$INSTALLROOT/lib/package/gen/$c.tim intercept=0 for k in $h do for s in $INITROOT/$c.$k do test -x "$s" || continue if cmp -s "$s" "$b" >/dev/null 2>&1 then intercept=1 break 2 fi case $(ls -t "$t" "$b" "$s" 2>/dev/null) in $t*) ;; $b*) cc=$b ;; $s*) $exec cd $INSTALLROOT/lib/package/gen tmp=pkg$$ $exec eval "echo 'int main(){return 0;}' > $tmp.c" if $exec $s -o $tmp.exe $tmp.c >/dev/null 2>&1 && test -x $tmp.exe then case $HOSTTYPE in *.mips*)$s -version >/dev/null 2>&1 || s= ;; esac case $s in ?*) $exec sed "s/^HOSTTYPE=.*/HOSTTYPE=$HOSTTYPE/" < "$s" > "$b" || exit $exec chmod +x "$b" || exit cc=$b intercept=1 note update $b ;; esac fi $exec rm -f $tmp.* $exec touch "$t" cd $PACKAGEROOT ;; esac break 2 done done case $intercept in 1) c=ld b=$INSTALLROOT/bin/$c for k in $h do for s in $INITROOT/$c.$k do test -x "$s" || continue case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done done ;; esac ;; esac c=ldd b=$INSTALLROOT/bin/$c for t in $h do s=$INITROOT/$c.$t test -x "$s" || continue onpath $c || case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done c=ar b=$INSTALLROOT/bin/$c for t in $h do s=$INITROOT/$c.$t test -x "$s" || continue case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done case $cc in /*) ;; *) echo "$command: $CC: not found -- set CC=C-compiler" >&2 exit 1 ;; esac case $exec in '') cd $INSTALLROOT/lib/package/gen tmp=pkg$$ echo 'int main(){return 0;}' > $tmp.c if $CC -o $tmp.exe $tmp.c > /dev/null 2> $tmp.err && test -x $tmp.exe then : ok else echo "$command: $CC: failed to compile this program:" >&2 cat $tmp.c >&2 if test -s $tmp.err then cat $tmp.err >&2 else echo "$command: $CC: not a C compiler" >&2 fi rm -f $tmp.* exit 1 fi rm -f $tmp.* cd $PACKAGEROOT ;; esac # remember the default $CC case $CC in cc) ;; *) if test -x $INSTALLROOT/bin/cc then case $(sed 1q $INSTALLROOT/bin/cc) in ": $CC :") CC=cc export CC ;; *) assign="$assign CC=\"\$CC\"" ;; esac else case $CROSS in 1) assign="$assign CC=\"\$CC\"" ;; *) case $exec in '') { echo ": $CC :" echo "$CC \"\$@\"" } > $INSTALLROOT/bin/cc chmod +x $INSTALLROOT/bin/cc ;; *) note generate a $INSTALLROOT/bin/cc wrapper for $CC ;; esac CC=cc export CC ;; esac fi ;; esac # no $INITROOT means INIT already installed elsewhere if test -d $INITROOT then # update probe scripts for i in lib/probe lib/probe/C lib/probe/C/make do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done i=$INSTALLROOT/lib/probe/C/make/probe j=$INITROOT/C+probe k=$INITROOT/make.probe case $(ls -t $i $j $k 2>/dev/null) in $i*) ;; *) if test -f $j -a -f $k then note update $i shellmagic case $exec in '') { case $SHELLMAGIC in ?*) echo "$SHELLMAGIC" ;; esac cat $j $k } > $i || exit ;; *) echo "{ echo $SHELLMAGIC cat $j $k } > $i" ;; esac $exec chmod +x $i || exit fi ;; esac fi # initialize a few mamake related commands checkaout mamake proto ratz || exit # execrate if necessary if (execrate) >/dev/null 2>&1 then execrate=execrate $make cd $INSTALLROOT/bin for i in chmod chgrp cmp cp ln mv rm do if test ! -x $OK/$i -a -x /bin/$i.exe then shellmagic case $exec in '') echo "$SHELLMAGIC"'execrate /bin/'$i' "$@"' > $OK/$i chmod +x $OK/$i ;; *) $exec echo \'"$SHELLMAGIC"'execrate /bin/'$i' "$@"'\'' >' $OK/$i $exec chmod +x $OK/$i ;; esac fi done PATH=$INSTALLROOT/bin/$OK:$PATH export PATH else execrate= fi case $action in view) exit 0 ;; esac # check against previous compiler and flags err= for var in CC CCFLAGS CCLDFLAGS LDFLAGS KSH_RELFLAGS do store=$INSTALLROOT/lib/package/gen/$var eval "new=\$$var" if test -f $store then old=$(cat $store) case $old in "$new") ;; *) case $old in '') old="(none)" ;; *) old="'$old'" ;; esac case $new in '') new="(none)" ;; *) new="'$new'" ;; esac echo "$command: $var changed from $old to $new" >&2 err=y ;; esac else test -d $INSTALLROOT/lib/package/gen && case $new in '') ;; *) echo "$new" ;; esac > $store fi done case $err,${FORCE_FLAGS+f} in y,) echo "$command: This would likely break the build. Restore the flag(s)," >&2 echo "$command: or delete the build directory and rebuild from scratch." >&2 exit 1 ;; esac unset err var store old new # all work under $INSTALLROOT/src $make cd $INSTALLROOT/src # record the build host name case $exec in '') hostinfo name echo "$_hostinfo_" | sed 's,\..*,,' > $PACKAGEBIN/gen/host ;; esac # make in parallel if possible case $NPROC in '') hostinfo cpu case $_hostinfo_ in 0|1) ;; *) NPROC=$_hostinfo_ $show NPROC=$NPROC $show export NPROC export NPROC ;; esac ;; esac # separate flags from target list case $target in *-*) a= for t in $target do case $t in -*) makeflags="$makeflags $t" ;; *) a="$a $t" ;; esac done target=$a ;; esac # mamprobe data should have been generated by this point case $exec in '') if test ! -f $INSTALLROOT/bin/.paths -o -w $INSTALLROOT/bin/.paths then N=' ' b= f= h= n= p= u= B= L= if test -f $INSTALLROOT/bin/.paths then exec < $INSTALLROOT/bin/.paths while read x do case $x in '#'?*) case $h in '') h=$x ;; esac ;; *BUILTIN_LIB=*) b=$x ;; *FPATH=*) f=$x ;; *PLUGIN_LIB=*) p=$x ;; *) case $u in ?*) u=$u$N ;; esac u=$u$x ;; esac done fi ifs=$IFS m= case $p in ?*) b= ;; esac case $b in ?*) IFS='=' set $b IFS=$ifs shift p="PLUGIN_LIB=$*" case $b in [Nn][Oo]*) p=no$p ;; esac m=1 ;; esac case $f in '') f="FPATH=../fun" m=1 ;; esac case $h in '') h='# use { no NO } prefix to permanently disable #' ;; esac case $p in '') p="PLUGIN_LIB=cmd" if grep '^setv mam_cc_DIALECT .* EXPORT=[AD]LL' $INSTALLROOT/lib/probe/C/mam/* >/dev/null 2>&1 then p=no$p fi m=1 ;; esac case $m in 1) case $u in ?*) u=$N$u ;; esac echo "$h$N$p$N$f$N$u" > $INSTALLROOT/bin/.paths ;; esac fi ;; esac # run from separate copies since ksh may be rebuilt case $EXECROOT in $INSTALLROOT) $make cd $INSTALLROOT/bin if executable /bin/cp then cp=/bin/cp else cp=cp fi if executable /bin/mv then mv=/bin/mv else mv=mv fi if executable /bin/rm then rm=/bin/rm else rm=rm fi for i in \ ksh tee cp ln mv rm \ *ast*.dll *cmd*.dll *dll*.dll *shell*.dll do executable $i && { cmp -s $i $OK/$i 2>/dev/null || { test -f $OK/$i && $exec $execrate $rm $OK/$i &2 exit 1 ;; esac $exec $execrate $cp $i $OK/$i } } done if executable $OK/tee then TEE=$INSTALLROOT/bin/$OK/tee fi if test "$KEEP_SHELL" != 1 && executable $OK/ksh then SHELL=$INSTALLROOT/bin/$OK/ksh export SHELL fi case :$PATH: in *:$INSTALLROOT/bin/$OK:*) ;; *) PATH=$INSTALLROOT/bin/$OK:$PATH export PATH ;; esac $make cd $INSTALLROOT/src ;; esac # build with mamake note make with mamake case $target in '') target="install" ;; esac eval capture mamake \$makeflags \$noexec \$target $assign ;; remove) echo "$command: $action: not implemented yet" >&2 exit 1 ;; results)set '' $target shift def=make dir=$PACKAGEBIN/gen case $verbose in 0) filter=yes ;; *) filter=cat ;; esac path=0 suf=out on= while : do case $# in 0) break ;; esac case $1 in --) shift break ;; error*|fail*) filter=errors ;; make|test|view) def=$1 case $filter:$1:$SHELL in errors:*:*) ;; *:test:*/ksh*) filter=rt ;; esac ;; old) suf=old ;; on) case $# in 1) echo $command: $action: $1: host pattern argument expected >&2 exit 1 ;; esac shift case $on in ?*) on="$on|" ;; esac on="$on$1" ;; path) path=1 ;; test) def=test filter=rt ;; *) break ;; esac shift done case $dir in */admin)case $on in '') on="*" ;; *) on="@($on)" ;; esac def=$def.log/$on ;; esac case $# in 0) set "$def" ;; esac m= t= for i do k=0 eval set '""' $i - $i.$suf - $dir/$i - $dir/$i.$suf - shift for j do case $j in -) case $k in 1) continue 2 ;; esac ;; *) if test -f $j then k=1 case /$j in */test.*) t="$t $j" ;; *) m="$m $j" ;; esac fi ;; esac done echo "$command: $i action output not found" >&2 exit 1 done sep= case $t in ?*) case $path in 0) for j in $t do echo "$sep==> $j <==" sep=$nl case $filter in cat) $exec cat $j ;; errors) $exec egrep -i '\*\*\*|FAIL[ES]|^TEST.* [123456789][0123456789]* error|core.*dump' $j | sed -e '/^TEST.\//s,/[^ ]*/,,' ;; rt) $exec $KSH rt - $j ;; *) $exec egrep -i '^TEST|FAIL' $j ;; esac done ;; 1) echo $t ;; esac ;; esac case $m in ?*) case $path in 0) case $filter in cat) cat $m ;; *) if test -f $HOME/.pkgresults then i=$(cat $HOME/.pkgresults) case $i in '|'*) ;; *) i="|$i" ;; esac else i= fi for j in $m do echo "$sep==> $j <==" sep=$nl case $filter in errors) $exeg egrep '^pax:|\*\*\*' $j ;; *) $exec egrep -iv '^($||[\+\[]|cc[^-:]|kill |make.*(file system time|has been replaced)|so|[0123456789]+ error|uncrate |[0123456789]+ block|ar: creat|iffe: test: |conf: (check|generate|test)|[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*=|gsf@research|ar:.*warning|cpio:|ld:.*(duplicate symbol|to obtain more information)|[0123456789]*$|(checking|creating|touch) [/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789])| obsolete predefined symbol | is (almost always misused|dangerous|deprecated|not implemented)| trigraph| assigned to | cast .* different size| integer overflow .*<<| optimization may be attained | passed as |::__builtin|pragma.*prototyped|^creating.*\.a$|warning.*not optimized|exceeds size thresh|ld:.*preempts|is unchanged|with value >=|(-l|lib)\*|/(ast|sys)/(dir|limits|param|stropts)\.h.*redefined|usage|base registers|`\.\.\.` obsolete'"$i" $j | $exec grep : ;; esac done ;; esac ;; 1) echo $m ;; esac esac ;; test) # pass control to ksh 93u+m test script capture "$PACKAGEROOT/bin/shtests" $args ;; use) # finalize the environment x=:.. for d in $( cd $PACKAGEROOT; ls src/*/Mamfile 2>/dev/null | sed 's,/[^/]*$,,' | sort -u ) do x=$x:$INSTALLROOT/$d done x=$x:$INSTALLROOT case $CDPATH: in $x:*) ;; *) CDPATH=$x:$CDPATH $show CDPATH=$CDPATH $show export CDPATH export CDPATH ;; esac P=$PACKAGEROOT $show P=$P $show export P export P A=$INSTALLROOT $show A=$A $show export A export A case $NPROC in '') hostinfo cpu case $_hostinfo_ in 0|1) ;; *) NPROC=$_hostinfo_ $show NPROC=$NPROC $show export NPROC export NPROC ;; esac ;; esac eval PACKAGE_USE=$package_use export PACKAGE_USE # run the command case $run in '') case $show in ':') $exec exec $SHELL ;; esac ;; *) $exec exec $SHELL -c "$run" ;; esac ;; *) echo "$command: $action: internal error" >&2 exit 1 ;; esac exit "$error_status" ksh-1.0.0-beta.2/bin/shtests000077500000000000000000000031321415700074400155420ustar00rootroot00000000000000#! /bin/sh # Wrapper script to run the ksh93 regression tests without requiring nmake. # By Martijn Dekker 2020-05-14 # Public domain. http://creativecommons.org/publicdomain/zero/1.0/ # # The manual: bin/shtests --man # Brief help: bin/shtests --help # # By default, this runs your compiled arch/*/bin/ksh. # # Note: The test suite actually uses $SHELL to indicate the shell to test. But # we cannot use the $SHELL environment value on entry to this wrapper script, # as that is already used for the user's default login shell on most systems. # Process and remove any assignment-argument indicating the shell to test for arg do case $arg in ( SHELL=* | KSH=* ) KSH=${arg#*=} ;; ( * ) set -- "$@" "$1" ;; esac shift done # Find root dir of ksh source mydir=$(dirname "$0") \ && mydir=$(CDPATH='' cd -P -- "$mydir/.." && printf '%sX' "$PWD") \ && mydir=${mydir%X} \ || exit myarch=$("$mydir/bin/package" host type) || exit # Check if there is a ksh to test. case ${KSH+set} in ( '' ) KSH=$mydir/arch/$myarch/bin/ksh ;; esac if ! test -x "$KSH" || ! test -f "$KSH"; then printf '%s: shell not found: %s\n' "${0##*/}" "$KSH" >&2 printf 'Specify a shell like: KSH=path/to/ksh bin/shtests\n' >&2 exit 1 fi # Ensure absolute path to ksh KSH=$(CDPATH='' cd -P -- "$(dirname "$KSH")" \ && printf '%s/%sX' "$PWD" "${KSH##*/}") \ && KSH=${KSH%X} # Run the test suite CDPATH='' cd -P -- "$mydir/src/cmd/ksh93/tests" || exit SHELL=$KSH INSTALLROOT=${INSTALLROOT:-$mydir/arch/$myarch} export SHELL INSTALLROOT unset -v KSH printf '#### Regression-testing %s ####\n' "$SHELL" exec "$SHELL" shtests "$@" ksh-1.0.0-beta.2/bin/silent000077500000000000000000000035331415700074400153500ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## # non-ksh stub for the nmake silent prefix # @(#)silent (AT&T Research) 1992-08-11 (command set -o posix) 2>/dev/null && set -o posix modern_export=`v=; export v=ok 2>/dev/null; echo "$v"` while : do case $# in 0) exit 0 ;; esac case $1 in *=*) case $modern_export in ok) export "$1" ;; *) `echo $1 | sed "s/\\([^=]*\\)=\\(.*\\)/eval \\1='\\2'; export \\1/"` ;; esac shift ;; *) break ;; esac done "$@" ksh-1.0.0-beta.2/docs/000077500000000000000000000000001415700074400143005ustar00rootroot00000000000000ksh-1.0.0-beta.2/docs/index.html000066400000000000000000000001661415700074400163000ustar00rootroot00000000000000 AST Software The KornShell
ksh-1.0.0-beta.2/docs/ksh/000077500000000000000000000000001415700074400150655ustar00rootroot00000000000000ksh-1.0.0-beta.2/docs/ksh/builtins.html000066400000000000000000000711031415700074400176060ustar00rootroot00000000000000 www/ksh/builtins.mm mm document

Guidelines for writing ksh-93 built-in commands


David G. Korn

Abstract

One of the features of ksh93, the latest version of ksh, is the ability to add built-in commands at run time. This feature only works on operating systems that have the ability to load and link code into the current process at run time. Some examples of the systems that have this feature are Linux, System V Release 4, Solaris, Sun OS, HP-UX Release 8 and above, AIX 3.2 and above, and Microsoft Windows systems.

This memo describes how to write and compile programs that can be loaded into ksh at run time as built-in commands.


INTRODUCTION

A built-in command is executed without creating a separate process. Instead, the command is invoked as a C function by ksh. If this function has no side effects in the shell process, then the behavior of this built-in is identical to that of the equivalent stand-alone command. The primary difference in this case is performance. The overhead of process creation is eliminated. For commands of short duration, the effect can be dramatic. For example, on SUN OS 4.1, the time to run wc on a small file of about 1000 bytes, runs about 50 times faster as a built-in command.

In addition, built-in commands may have side effects on the shell environment. This is usually done to extend the application domain for shell programming. For example, there is a group of X-windows extension built-ins that make heavy use of the shell variable namespace. These built-ins are added at run time and result in a windowing shell that can be used to write X-windows applications.

While there are definite advantages to adding built-in commands, there are some disadvantages as well. Since the built-in command and ksh share the same address space, a coding error in the built-in program may affect the behavior of ksh; perhaps causing it to core dump or hang. Debugging is also more complex since your code is now a part of a larger entity. The isolation provided by a separate process guarantees that all resources used by the command will be freed when the command completes. Resources used by a built-in must be meticulously maintained and freed. Also, since the address space of ksh will be larger when built-in are loaded, it may increase the time it takes ksh to fork() and exec() non-built-in commands. It makes no sense to add a built-in command that takes a long time to run or that is run only once, since the performance benefits will be negligible. Built-ins that have side effects in the current shell environment have the disadvantage of increasing the coupling between the built-in and ksh, making the overall system less modular and more monolithic.

Despite these drawbacks, in many cases extending ksh by adding built-in commands makes sense and allows reuse of the shell scripting ability in an application specific domain. This memo describes how to write ksh extensions.


WRITING BUILT-IN COMMANDS

There is a development kit available for writing ksh built-ins as part of the AST (AT&T Software Technology) Toolkit. The development kit has three directories, include, lib, and bin. It is best to set the value of the environment variable PACKAGE_ast to the pathname of the directory containing the development kit. The include directory contains a subdirectory named ast that contains interface prototypes for functions that you can call from built-ins. The lib directory contains the ast library and a library named cmd that contains a version of several of the standard POSIX[1] utilities that can be made run time built-ins. The lib/ksh directory contains shared libraries that implement other ksh built-ins. The bin directory contains build tools such as nmake[2]. To add built-ins at runtime, it is necessary to build a shared library containing one or more built-ins that you wish to add. The built-ins are then added by running builtin -f shared_lib. Since the procedure for building share libraries is system dependent, it is best to use nmake using the sample nmake makefile below as a prototype. The AST Toolkit also contains some examples of built-in libraries under the src/cmd/kshlib directory.

There are two ways to code adding built-ins. One method is to replace the function main with a function b_name, where name is the name of the built-in you wish to define. A built-in command has a calling convention similar to the main function of a program, int main(int argc, char *argv[]). except that it takes a third argument of type Shbltin_t* which can be passed as NULL if it is not used. The definition for Shbltin_t* is in <ast/shcmd.h>. Instead of exit, you need to use return to terminate your command. The return value will become the exit status of the command. The open built-in, installed in lib/ksh in the AST Toolkit, uses this method. The Shbltin_t structure contains a field named shp which is a pointer to the shell data that is needed for shell library callbacks. It also contains the fields, shrun, shtrap, shexit, and shbltin that are function pointers to the shell library functions sh_run, sh_trap sh_exit, and sh_addbuiltin, respectively. These functions can be invoked without the need for runtime symbol lookup when the shell is statically linked with libshell.

The alternative method is to create a function lib_init and use the Shbltin_t.shbltin() function to add one or more built-ins. The lib_init function will be called with two arguments. The first argument will be 0 when the library is loaded and the second argument will be of type Shbltin_t*. The dbm_t and dss shell built-ins use this method.

No matter which way you add built-ins you should add the line SHLIB(identifier) as the last line of one of the built-in source file, where identifier is any C identifier. This line provides version information to the shell builtin command that it uses to verify compatibility between the built-in and ksh implementation versions. builtin fails with a diagnostic on version mismatch. The diagnostic helps determine whether ksh is out of date and requires an upgrade or the built-in is out of date and requires recompilation.

The steps necessary to create and add a run time built-in are illustrated in the following simple example. Suppose you wish to add a built-in command named hello which requires one argument and prints the word hello followed by its argument. First, write the following program in the file hello.c:

#include     <stdio.h>
int b_hello(int argc, char *argv[], void *context)
{
        if(argc != 2)
        {
                fprintf(stderr,"Usage: hello arg\n");
                return(2);
        }
        printf("hello %s\n",argv[1]);
        return(0);
}
SHLIB(hello)

Next, the program needs to be compiled. If you are building with AT&T nmake use the following Makefile:

:PACKAGE: --shared ast
hello plugin=ksh :LIBRARY: hello.c
and run nmake install to compile, link, and install the built-in shared library in lib/ksh/ under PACKAGE_ast. If the built-in extension uses several .c files, list all of these on the :LIBRARY: line.

Otherwise you will have to compile hello.c with an option to pick up the AST include directory (since the AST <stdio.h> is required for ksh compatibility) and options required for generating shared libraries. For example, on Linux use this to compile:

cc -fpic -I$PACKAGE_ast/include/ast -c hello.c
and use the appropriate link line. It really is best to use nmake because the 2 line Makefile above will work on all systems that have ksh installed.

If you have several built-ins, it is desirable to build a shared library that contains them all.

The final step is using the built-in. This can be done with the ksh command builtin. To load the shared library libhello.so from the current directory and add the built-in hello, invoke the command,

builtin -f ./libhello.so hello
The shared library prefix (lib here) and suffix (.so here) be omitted; the shell will add an appropriate suffix for the system that it is loading from. If you install the shared library in lib/ksh/, where ../lib/ksh/ is a directory on $PATH, the command
builtin -f hello hello
will automatically find, load and install the built-in on any system. Once this command has been invoked, you can invoke hello as you do any other command. If you are using lib_init method to add built-ins then no arguments follow the -f option.

It is often desirable to make a command built-in the first time that it is referenced. The first time hello is invoked, ksh should load and execute it, whereas for subsequent invocations ksh should just execute the built-in. This can be done by creating a file named hello with the following contents:

function hello
{
        unset -f hello
        builtin -f hello hello
        hello "$@"
}
This file hello needs to be placed in a directory that is in your FPATH variable, and the built-in shared library should be installed in lib/ksh/, as described above.


CODING REQUIREMENTS AND CONVENTIONS

As mentioned above, the entry point for built-ins must either be of the form b_name or else be loaded from a function named lib_init. Your built-ins can call functions from the standard C library, the ast library, interface functions provided by ksh, and your own functions. You should avoid using any global symbols beginning with sh_, nv_, and ed_ since these are used by ksh itself. #define constants in ksh interface files use symbols beginning with SH_ and NV_, so avoid using names beginning with these too.

Header Files

The development kit provides a portable interface to the C library and to libast. The header files in the development kit are compatible with K&R C[3], ANSI C[4], and C++[5].

The best thing to do is to include the header file <shell.h>. This header file causes the <ast.h> header, the <error.h> header and the <stak.h> header to be included as well as defining prototypes for functions that you can call to get shell services for your builtins. The header file <ast.h> provides prototypes for many libast functions and all the symbol and function definitions from the ANSI C headers, <stddef.h>, <stdlib.h>, <stdarg.h>, <limits.h>, and <string.h>. It also provides all the symbols and definitions for the POSIX[6] headers <sys/types.h>, <fcntl.h>, and <unistd.h>. You should include <ast.h> instead of one or more of these headers. The <error.h> header provides the interface to the error and option parsing routines defined below. The <stak.h> header provides the interface to the memory allocation routines described below.

Programs that want to use the information in <sys/stat.h> should include the file <ls.h> instead. This provides the complete POSIX interface to stat() related functions even on non-POSIX systems.

Input/Output

ksh uses sfio, the Safe/Fast I/O library[7], to perform all I/O operations. The sfio library, which is part of libast, provides a superset of the functionality provided by the standard I/O library defined in ANSI C. If none of the additional functionality is required, and if you are not familiar with sfio and you do not want to spend the time learning it, then you can use sfio via the stdio library interface. The development kit contains the header <stdio.h> which maps stdio calls to sfio calls. In most instances the mapping is done by macros or inline functions so that there is no overhead. The man page for the sfio library is in an Appendix.

However, there are some very nice extensions and performance improvements in sfio and if you plan any major extensions I recommend that you use it natively.

Error Handling

For error messages it is best to use the ast library function errormsg() rather that sending output to stderr or the equivalent sfstderr directly. Using errormsg() will make error message appear more uniform to the user. Furthermore, using errormsg() should make it easier to do error message translation for other locales in future versions of ksh.

The first argument to errormsg() specifies the dictionary in which the string will be searched for translation. The second argument to errormsg() contains that error type and value. The third argument is a printf style format and the remaining arguments are arguments to be printed as part of the message. A new-line is inserted at the end of each message and therefore, should not appear as part of the format string. The second argument should be one of the following:

ERROR_exit(n):

If n is not-zero, the builtin will exit value n after printing the message.
ERROR_system(n):

Exit builtin with exit value n after printing the message. The message will display the message corresponding to errno enclosed within [ ] at the end of the message.
ERROR_usage(n):

Will generate a usage message and exit. If n is non-zero, the exit value will be 2. Otherwise the exit value will be 0.
ERROR_debug(n):

Will print a level n debugging message and will then continue.
ERROR_warn(n):

Prints a warning message. n is ignored.

Option Parsing

The first thing that a built-in should do is to check the arguments for correctness and to print any usage messages on standard error. For consistency with the rest of ksh, it is best to use the libast functions optget() and optusage()for this purpose. The header <error.h> includes prototypes for these functions. The optget() function is similar to the System V C library function getopt(), but provides some additional capabilities. Built-ins that use optget() provide a more consistent user interface.

The optget() function is invoked as

int optget(char *argv[], const char *optstring)
where argv is the argument list and optstring is a string that specifies the allowable arguments and additional information that is used to format usage messages. In fact a complete man page in troff or html can be generated by passing a usage string as described by the getopts command. Like getopt(), single letter options are represented by the letter itself, and options that take a string argument are followed by the : character. Option strings have the following special characters:
:
Used after a letter option to indicate that the option takes an option argument. The variable opt_info.arg will point to this value after the given argument is encountered.
#
Used after a letter option to indicate that the option can only take a numerical value. The variable opt_info.num will contain this value after the given argument is encountered.
?
Used after a : or # (and after the optional ?) to indicate the preceding option argument is not required.
[...]

After a : or #, the characters contained inside the brackets are used to identify the option argument when generating a usage message.
space

The remainder of the string will only be used when generating usage messages.

The optget() function returns the matching option letter if one of the legal option is matched. Otherwise, optget() returns

':'
If there is an error. In this case the variable opt_info.arg contains the error string.
0
Indicates the end of options. The variable opt_info.index contains the number of arguments processed.
'?'
A usage message has been required. You normally call optusage() to generate and display the usage message.

The following is an example of the option parsing portion of the wc utility.

#include <shell.h>
while(1) switch(n=optget(argv,"xf:[file]"))
{
	case 'f':
		file = opt_info.arg;
		break;
	case ':':
		error(ERROR_exit(0), opt_info.arg);
		break;
	case '?':
		error(ERROR_usage(2), opt_info.arg);
		UNREACHABLE();
}

Storage Management

It is important that any memory used by your built-in be returned. Otherwise, if your built-in is called frequently, ksh will eventually run out of memory. You should avoid using malloc() for memory that must be freed before returning from you built-in, because by default, ksh will terminate you built-in in the event of an interrupt and the memory will not be freed.

The best way to allocate variable sized storage is through calls to the stak library which is included in libast and which is used extensively by ksh itself. Objects allocated with the stakalloc() function are freed when you function completes or aborts. The stak library provides a convenient way to build variable length strings and other objects dynamically. The man page for the stak library is contained in the Appendix.

Before ksh calls each built-in command, it saves the current stack location and restores it after it returns. It is not necessary to save and restore the stack location in the b_ entry function, but you may want to write functions that use this stack are restore it when leaving the function. The following coding convention will do this in an efficient manner:

yourfunction()
{
        char	*savebase;
        int	saveoffset;
        if(saveoffset=staktell())
        	savebase = stakfreeze(0);
        ...
        if(saveoffset)
        	stakset(savebase,saveoffset);
        else
        	stakseek(0);
}


CALLING ksh SERVICES

Some of the more interesting applications are those that extend the functionality of ksh in application specific directions. A prime example of this is the X-windows extension which adds builtins to create and delete widgets. The nval library is used to interface with the shell name space. The shell library is used to access other shell services.

The nval library

A great deal of power is derived from the ability to use portions of the hierarchical variable namespace provided by ksh-93 and turn these names into active objects.

The nval library is used to interface with shell variables. A man page for this file is provided in an Appendix. You need to include the header <nval.h> to access the functions defined in the nval library. All the functions provided by the nval library begin with the prefix nv_. Each shell variable is an object in an associative table that is referenced by name. The type Namval_t* is pointer to a shell variable. To operate on a shell variable, you first get a handle to the variable with the nv_open() function and then supply the handle returned as the first argument of the function that provides an operation on the variable. You must call nv_close() when you are finished using this handle so that the space can be freed once the value is unset. The two most frequent operations are to get the value of the variable, and to assign value to the variable. The nv_getval() function returns a pointer to the value of the variable. In some cases the pointer returned is to a region that will be overwritten by the next nv_getval() call so that if the value isn't used immediately, it should be copied. Many variables can also generate a numeric value. The nv_getnum() function returns a numeric value for the given variable pointer, calling the arithmetic evaluator if necessary.

The nv_putval() function is used to assign a new value to a given variable. The second argument to putval() is the value to be assigned and the third argument is a flag which is used in interpreting the second argument.

Each shell variable can have one or more attributes. The nv_isattr() is used to test for the existence of one or more attributes. See the appendix for a complete list of attributes.

By default, each shell variable passively stores the string you give with with nv_putval(), and returns the value with getval(). However, it is possible to turn any node into an active entity by assigning functions to it that will be called whenever nv_putval() and/or nv_getval() is called. In fact there are up to five functions that can associated with each variable to override the default actions. The type Namfun_t is used to define these functions. Only those that are non-NULL override the default actions. To override the default actions, you must allocate an instance of Namfun_t, and then assign the functions that you wish to override. The putval() function is called by the nv_putval() function. A NULL for the value argument indicates a request to unset the variable. The type argument might contain the NV_INTEGER bit so you should be prepared to do a conversion if necessary. The getval() function is called by nv_getval() value and must return a string. The getnum() function is called by the arithmetic evaluator and must return double. If omitted, then it will call nv_getval() and convert the result to a number.

The functionality of a variable can further be increased by adding discipline functions that can be associated with the variable. A discipline function allows a script that uses your variable to define functions whose name is varname.discname where varname is the name of the variable, and discname is the name of the discipline. When the user defines such a function, the settrap() function will be called with the name of the discipline and a pointer to the parse tree corresponding to the discipline function. The application determines when these functions are actually executed. By default, ksh defines get, set, and unset as discipline functions.

In addition, it is possible to provide a data area that will be passed as an argument to each of these functions whenever any of these functions are called. To have private data, you need to define and allocate a structure that looks like

struct yours
{
        Namfun_t	fun;
	your_data_fields;
};

The shell library

There are several functions that are used by ksh itself that can also be called from built-in commands. The man page for these routines are in the Appendix.

The sh_addbuiltin() function can be used to add or delete builtin commands. It takes the name of the built-in, the address of the function that implements the built-in, and a void* pointer that will be passed to this function as the third argument whenever it is invoked. If the function address is NULL, the specified built-in will be deleted. However, special built-in functions cannot be deleted or modified.

The sh_fmtq() function takes a string and returns a string that is quoted as necessary so that it can be used as shell input. This function is used to implement the %q option of the shell built-in printf command.

The sh_parse() function returns a parse tree corresponding to a give file stream. The tree can be executed by supplying it as the first argument to the sh_trap() function and giving a value of 1 as the second argument. Alternatively, the sh_trap() function can parse and execute a string by passing the string as the first argument and giving 0 as the second argument.

The sh_isoption() function can be used to set to see whether one or more of the option settings is enabled.


References

[1]
POSIX - Part 2: Shell and Utilities, IEEE Std 1003.2-1992, ISO/IEC 9945-2:1993.
[2]
Glenn Fowler, A Case for make, Software - Practice and Experience, Vol. 20 No. S1, pp. 30-46, June 1990.
[3]
Brian W. Kernighan and Dennis M. Ritchie, The C Programming Language, Prentice Hall, 1978.
[4]
American National Standard for Information Systems - Programming Language - C, ANSI X3.159-1989.
[5]
Bjarne Stroustroup, C++, Addison Wesley, xxxx
[6]
POSIX - Part 1: System Application Program Interface, IEEE Std 1003.1-1990, ISO/IEC 9945-1:1990.
[7]
David Korn and Kiem-Phong Vo, SFIO - A Safe/Fast Input/Output library, Proceedings of the Summer Usenix, pp. , 1991.


March 13, 2012

ksh-1.0.0-beta.2/docs/ksh/examples.html000066400000000000000000000053411415700074400175740ustar00rootroot00000000000000 www/ksh/examples.mm mm document

Sample Functions

dirs    getopt    popd    title
emacs_keybind    keybind    pushd    vi_keybind


Sample Scripts

cgi-lib.ksh    env    which     
dump-cgi.ksh    line          


March 13, 2012

ksh-1.0.0-beta.2/docs/ksh/faq.html000066400000000000000000001017311415700074400165250ustar00rootroot00000000000000 general shell

general

What is KornShell?
KornShell is a command and scripting language that is a superset of the System V UNIX shell, aka, BourneShell (or sh).
What is ksh?
ksh is the name of the program that implements the KornShell language.
What is the history of ksh?
ksh was written by David Korn at Bell Telephone Laboratories. David Korn is currently at AT&T Research. The first version of ksh was in 1983. It was the first shell to have command line editing with both emacs and vi style interaction. The 1986 version was the first to offer multibyte support. The 1988 version of ksh is the version that was adopted by System V Release 4 UNIX and was a source document for the IEEE POSIX and ISO shell standards. The 1993 version is a major rewrite of the 1988 version and focuses more on scripting.
Where is the official description of the KornShell language?
The Bolsky and Korn book, The KornShell Command and Programming Language, published by Prentice Hall, defines the 1988 version. The newer Bolsky and Korn book, The New KornShell Command and Programming Language, also published by Prentice Hall, describes the 1993 version. There are many new features since this book was published and the man page for ksh93 is kept up to date.
What are the major new features of KornShell 1993?
The only major new interactive features are key binding and tab completion. Major new language features are floating point arithmetic, associative arrays, complete ANSI C printf, name reference variables, new expansion operators, dynamic loading of built-in commands, active variables, and compound variables. Active and compound variables allow shell variables to behave like objects. The ability to define types was added in 2009. In addition, ksh93 has been written to be extensible with an C language API for programming extensions.
Are any further releases of ksh planned?
Yes, the KornShell language and ksh implementation are in active development. Most of the focus will be on scripting and reusability.
Why are newer release of ksh still called ksh93?
We started the AST/ksh OpenSource release process in the late 90's. At that point ksh93 was the well-known name for ksh. The OpenSource release was finally granted in March 2000. No one has since volunteered to repeat that process for kshXX.
How can I determine the release or version of a particular ksh?
The current version and release string may be accessed by ${.sh.version} and $KSH_VERSION. The format is Version features 93version[-/+] release:
  • features -- compile time features, typically enabled by SHOPT_foo state variables in the ksh93 Makefile. A single letter represents each feature:
    • A (SHOPT_AUDIT)
    • B (SHOPT_BASH) bash compatibility mode.
    • J (SHOPT_COSHELL) -lcoshell job pools.
    • j (SHOPT_BGX)
    • L (SHOPT_ACCT)
    • M (SHOPT_MULTIBYTE)
    • P (SHOPT_PFSH)
    • R (SHOPT_REGRESS)
  • version-- a lowercase letter signifying major release points. An optional - following features signifies an alpha release. The first stable release has no -. An optional + signifies a stable release with bug patches and minor enhancements.
  • release-- the release date in YYYY-MM-DD form. This date corresponds to AST package and git repository releases.
KSH_VERSION in a numeric context is an integer that encodes the release YYYYMMDD.
What new features are planned for ksh?
We are in the early stage of planning but the likely additions are namespaces, ability to read XML and JSON object into shell variables, and handling of queued signals. Support for multi-threading is also being considered.
Is KornShell public domain?
Yes, the language description is public domain and can be reimplemented. Some of the KornShell language features have been reimplemented in the GNU shell, bash, in zsh and mksh, and in pdksh, a public domain implementation.
Is ksh public domain?
No, earlier versions were owned by both AT&T and Novell. The 1993 version is owned by both Lucent and AT&T.
Is source code available?
Starting in March 2000, the ksh93 source is available as part of a larger collection of software called the ast-open software package which can be downloaded from the github page.
What are the licensing terms?
The exact license terms can be found on the licence page.
Does the license allow binaries to be freely redistributed?
Yes, provided you make the license terms available to everyone you distribute binaries to.
If I make changes to the code, do I have to make them public?
No, you do not have to make them public. However, if you distribute the changes, you must allow us to be able to get these changes and distribute them along with the source.
Why do some vendors still ship ksh88, not ksh93?
Since ksh88 was included in System V release 4, most vendors have just included this version. However most Linux systems and Mac OS provide ksh93 version 's' or later. Solaris11 uses ksh93 as /bin/sh.
Do you provide support for ksh?
No, we will try to fix any bugs we hear about in future releases, but we do not provide any official support.
Is ksh supported commercially?
Software vendors that supply ksh with their systems typically support it for that system.
What is pdksh and is it related to ksh or KornShell?
pdksh is a public domain version of a UNIX shell that is unrelated to ksh. It supports most of the 1988 KornShell language features and some of the 1993 features. Some KornShell scripts will not run with pdksh.
How is the MKS Toolkit KornShell related to KornShell?
MKS Toolkit KornShell is a completely independent implementation that supports a subset of the 1988 KornShell language.
What systems does ksh run on?
ksh has been written to be portable. It has been ported to virtually run on every known UNIX system. In addition, it runs on non-UNIX systems such as IBM's MVS using OpenEdition, and Microsoft's Windows 9X, Windows NT and Windows 2000. ksh is part of the UWIN (Unix for Windows) software,
Does ksh conform to the IEEE POSIX and ISO shell standard?
The 1993 version should conform to the 1992 standard. At one point it had passed the test suite created by X/OPEN.
Will KornShell 88 scripts run with KornShell 93?
In almost all cases, the answer is yes. However, the IEEE POSIX and ISO standards required a few changes that could cause scripts to fail. There is a separate document that lists all known incompatibilities.
Can ksh run as /bin/sh?
We have installed ksh as /bin/sh on several systems without encountering any problems. It is /bin/sh on Solaris11. Our Linux systems use this instead of bash.


interactive

How do I get separate history files for shell?
ksh uses a shared history file for all shells that use the same history file name. This means that commands entered in one window will be seen by shells in other windows. To get separate windows, the HISTFILE variable needs to be set to different name before the first history command is created.
How do I get the time of day in my prompt?
You can use printf with supports the %T format for time and date formatting. For example, the format %(%H:%M:%S)T specifies time in hour, minute, second format and if no argument is specified, the current time is used. Thus setting PS1='$(printf "%(%H:%M:%S)T" $' will output the time of day before the $ prompt.
Why does the screen width not function correctly when non-printing characters are in my prompt?
The shell computes the screen width by subtracting the width of the prompt from the screen width. To account for non-printing characters, for example escape sequences that display in the title bar, follow these characters with a carriage return. The shell starts recomputing the width after each carriage return.
What is the PS4 prompt and how is it used?
The PS4 prompt is evaluated and displayed before each line when running an execution trace. If unset, a + and a <space> will be output before each line in the trace. Putting '$LINENO' inside PS4 will cause the line number to be displayed. Putting '$SECONDS' in the PS4 prompt will cause the elapsed time to be displayed before each line. Note that single quotes are used to prevent the expansion from happening when PS4 is defined.
How is keybinding done?
ksh93 provides a KEYBD trap that gets executed whenever a key is entered from the keyboard. Using this trap, and the associative array feature of ksh93, a keybind function can easily be written which will map any entered key sequence to another key sequence.
How do I get the arrow keys to work?
Starting with the 'h' point release, on most keyboards you do not have to do anything to get the arrow keys to work. However, if they do not generate standard escape sequences, then you will have to use a keybinding function to get them to work.
Does ksh support file name completion?
Yes, it does. The default key binding is <ESC><ESC> however, starting with the 'g' point release, <TAB> also works for completion.
Does ksh support command completion?
If you perform completion on the first word of a command, ksh will do completion using aliases, functions, and commands.
Is completion programmable?
Yes, using the key binding mechanism, you can script the behavior of any key and therefore cause the current contents of any line to be replaced by any other line.
Is there any way to get the command-line editor to go to more than a single line?
The multiline option (now on by default) allows lines longer than the width of the screen to be displayed on multiple lines on the screen. Also in vi-mode, if you hit 'v' while in control mode, it will bring up a full screen version of vi on the current command. The command will execute when you exit vi.
What is predictive editing?
In 2010, a compile option was added that cause the shell to try to predict what you were trying to type by looking in the history file for all lines that matched and presenting them as a menu. Any line starting with # would use the characters you type to find matching lines from the history file. If you find the line you wanted, you can enter the number followed by <TAB> or newline. However bugs in earlier version led to core dumps.
Can I use the shell line editor on other commands?
The command ie, that comes along with shell, can be used to run line input oriented commands with command line editing.
When I do echo $?, I am getting 267. What does this mean?
ksh93 reports process that terminate with a signal as 256+signo. Earlier versions used 128+signo but this makes it impossible to distinguish from a command exit with that value. If you run
kill -l $?
on this signal number, it will give the name of the signal that caused this exit.
When I type builtin, I notice that some of these are full pathnames. What does this mean?
Builtins that are not bound to pathnames are always searched for before doing a path search. Builtins that are bound to pathnames are only executed when the path search would bind to this pathname.
What is a self generating man page?
A self generating man page is one that is generated by the option parser within that command using an extended version of the getopts function. The man page can be generated in html, troff, or directly for the terminal. Most builtin commands in the shell have self generating man pages so that you can run for example, kill --man or kill --html to get the description of kill to the screen or as an html file. All self-documenting output is to the standard error, so you must redirect 2>... to capture the output.

This same method can also be used for shell scripts. Run getopts --man for more details.

What is autoloading?
Autoloading was a method used in ksh88, and still permitted in ksh93 to declare that a name corresponded to a function. The function would be loaded and executed when first referenced. This was necessary since FPATH was always searched after PATH with ksh88 and therefore if you defined a function whose name was the same as that of a program on your path, the program on your path would have been executed. With ksh93, when a pathname is encountered that is on PATH, but also is in FPATH, this directory is assumed to be a function directory. Thus, you can have function directories searched before program directories so that autoloading is no longer needed.
Why does the output from 'time command 2> file' come out on the screen?
The time command is a compound command in ksh and time is a reserved word It can be followed by any pipeline. Thus, redirections applied at the end are for the command, not to time itself. You can use time {...;} 2> file to capture the timing output to a file. Note, that with ksh, time works with all commands, for example, time for i; do xxx;done.
When I run 'mv * ../elsewhere' I so that get '-ksh: mv: cannot execute [Arg list too long]', what causes this?
UNIX systems have a limit to the space consumed by command arguments and environment variables when running commands that are not built into the shell. The configuration parameter ARG_MAX defines this limit. You can run 'getconf ARG_MAX' to find the limit for your system. Note that the shell expands * to the list of files in the current directory before running mv. In many case the xargs or tw command can be used to work around this problem by splitting the line into chunks and invoking the command. Another way to work around this limit is to make the command a builtin. On systems in which the cmd library is installed, you can invoke 'builtin -f cmd mv' to make mv a shell builtin in which case the line length limit no longer applies. Another alternative is to use a for loop and invoke the mv command for each file, for example, 'for i in *;do mv $i ../elsewhere;done'. Starting with ksh93o+, a new feature was added to ksh to overcome this limit in some cases. If a command is preceded by 'command -x', and it fails because there are two many arguments, the command will be run multiple times with subsets of the arguments. However, the change in ksh93o+ does not work in the above case because the ../elsewhere is not used for each subset. This problem was resolved starting in ksh93p so that command -x mv * ../elsewhere should work. Note that it is possible to do alias mv='command -x mv'
Is there any way to generate the list of .c files in the current directory and all the subdirectories?
Starting with ksh93o+, the globstar option (set -G or set -o globstar) was added. With globstar enabled, ** by itself matches zero or more directories or files, and **/ matches zero or more directories so that **/*.c will match all .c files under the current directory.
Is there any way to prevent sending a HUP signal to a job when I log out if I didn't nohup the job?
Yes, the disown command tells ksh not to forward the HUP signal to the specified jobs when it disconnects.


programming

What is the difference between * and @, for example, and ?
When used outside of "", they are equivalent. However, within double quotes, "$@" produces one argument for each positional parameter, and "$* produces a single argument. Note that "$@" preserves arguments lists, whereas $* may not unless both word splitting and pathname expansion are disabled.
Why do I need spaces around { and } but not around ( and )?
The characters ( and ) are shell metacharacters and are always treated specially. For historical reasons, { and } were treated as reserved words and are only special as separate words at locations in which a command can begin.
How do I get read to maintain the \ characters?
Use read -r instead.
How can I a write a ksh script that responds directly to each character so that you user just has to enter y, not y<return>?
There are two ways to do this. The easiest is to use
read -n1 x
Alternatively, you could do
function keytrap
{
	.sh.edchar=${sh.edchar}$'
}
trap keytrap KEYBD
and then
read x
What is the purpose of $'...'?
The $'...' string literal syntax was added to ksh93 to solve the problem of entering special characters in scripts. It uses ANSI C rules to translate the string between the '...'. It would have been cleaner to have all "..." strings handle ANSI C escapes, but that would not be backward compatible.
What is the -n option used for?
You should always run ksh -n on each script you write. The -n option will check for syntax errors on paths that might not even be checked when you run the script. It also produces a number of warning messages.
Why are both `...` and $(...) used for command substitution?
The `...` method has some rather strange quoting rules and does not nest easily. $(...) was added to ksh88 to make command substitution easy to use. `...` is provided for backwards compatibility only.
How can I tell if all the commands of a pipeline have succeeded?
The pipefail option was added to the 'g' point release of ksh93. With pipefail set, a pipeline will fail if any element of the pipeline fails. The exit status will be that of the first command that has failed.
What is the difference between [...] and [[...]]?
The [[...]] is processed as part of the shell grammar whereas [...] is processed like any other command. Operators and operands are detected when the command is read, not after expansions are performed. The shell does not do word splitting or pathname generation inside [[...]]. This allows patterns to be specified for string matching purposes. You should use [[...]] instead of [...] and test.
How come [[ $foo == $bar ]] is true and [[ $bar == $foo ]] is false?
The == operator is not symmetrical. It takes a string on the left and a pattern on the right. However, if you double quote the right hand side, which removes the special meaning of pattern match characters, then this becomes a string comparison so that [[ "$foo" == "bar" ]] and [[ "$bar" == "$foo" ]] are equivalent.
Why does ksh93 have print since echo already exists and is widely used?
The behavior of echo varies from system to system. The POSIX standard does not define the behavior of echo when the first argument beings with a - or when any argument contains a  character. This makes echo pretty useless for use in portable scripts.
What is $bar after running 'echo foo | read bar'?
The answer is foo. ksh runs the last component of a pipeline in the current process. Some shells run it as a subshell as if you had invoked it as echo foo | (read bar).
How can I access a substring of a variable?
The syntax ${varname:offset:len} can be used to generate the string of length len starting at the specified offset. String offsets start at 0. If :len is omitted, then the remainder of the string will be used. Both offset and len can be arithmetic expressions. A negative offset is subtracted from the last offset.
What is the difference between ((expr)) and $((expr))?
((expr)) is a command that evaluates an arithmetic expression. The exit status of this command is 0 if the expression evaluates to non-zero and is 1 if it evaluates to 0. 0 is an string expansion that expands to a string representation of the value of this arithmetic expression. It can be used anywhere a variable substitution is permitted.

What is the difference between $((x*y)) and $(($x*$y))?
In the first case the value of x and the value of y are multiplied together, and then their result is converted to a string. In the second case variables $x, *, and $y are concatenated to form an arithmetic expression which is then evaluated. This can yield different results, for example,
x=2+3 y=4+5
print $((x*y)) \$(($x*$y))
45 19
When x and y are numeric the first form is recommended for better
performance.
How do I handle filenames with spaces in them?
To be POSIX conforming, ksh has to do word splitting and pathname expansion the results of substitutions. You can enclose variable substitutions in "..." to prevent both word splitting and pathname expansion. Alternatively, you can disable word splitting by setting IFS='' and pathname generation with set -o noglob.
What are active variables?
By default shell variables are passive. They hold values given to them on assignment, and return values on reference. Active variables allow the assignment and reference (and other actions) be controlled by functions specific to that variable. At the shell level, a 'get', 'set', or 'unset' shell function can be defined for any variable to make them active, so that the function foo.set will be invoked whenever the variable foo is assigned a value. At the C interface level, several functions can be stacked together for an active variable.
What is the difference between function name and name()?
In ksh88 these were the same. However, the POSIX standard choose foo() for functions and defined System V Release 2 semantics to them so that there are no local variables and so that traps are not scoped. ksh93 keeps the ksh88 semantics for functions defined as function name, and has changed the name() semantics to match the POSIX semantics. Clearly, function name is more useful.
What is the naming conventions for files in FPATH and can one file contain more than one function definition?
You can have more than one function defined in each file defined in FPATH and all of them will be added to the list of known functions. Any commands placed in this file outside of function definitions will be invoked first. The name of the file must be that of the first function you invoke. If you have several functions defined in one file, then you should create a link to each of the function names that can potentially be invoked first.
What are name reference variables and how are they used?
Reference variables are variables in which all references and assignments refer to the variable that they reference. For example,
typeset -n name=$1
name=value
is equivalent to
eval \$1='value'
References are most useful for passing arguments such as arrays to functions.
If i=1 and var1=some value, how do I print var$i to get its value?
Either use
eval print var\$i
or
typeset -n x=var$i
print $x
How can I shift the elements of an array?
The shift special builtin-command only works for positional parameters. However, noting that array subscripts start at 0, you can use
typeset -A name "${name[@]:1}"
to shift the array.
Why are the braces required with array references, e.g. ${x[1]}?
It would be nice to do $x[1], but the POSIX shell would expand $x and then search for the file pattern resulting by concatenating [1]. ksh is POSIX compatible.
How do I get the list of subscript names for an associative array?
The prefix operator ! in variable expansions can be used to get names. To get the names of subscripts for an array, associative or indexed, use ${!var[@]}.
How do I do global substitutions on the contents of shell variables?
Use // instead of / for global substitution, ${var//aa/bb} will expand to the value of var with each "aa" replaced by "bb".
How can I convert %XX values to ASCII?
You can convert this to a sequence of ANSI C strings and then eval that string, for example suppose the variable 'foo' contains %XX strings, then
eval print -r -- "\$'${foo//'%'@(??)/'\x\1"'\$'"}'"
will print out the string in ASCII.
I want to use exec to open a file. How do I prevent the script from exiting if the exec fails?
If you run
command exec ... || error ...
then error will be executed if the exec fails, but the script will not terminate. The command builtin will prevent the shell from exiting when special built-ins fail.
How do I execute a builtin inside a function of the same name?
You use the command builtin for this. For example,
function cd
{
	command cd "$@" && title "$PWD"
}
will run the builtin command cd from within the function cd rather than calling the function cd recursively.
How are variables scoped in ksh?
The scoping of variables was not defined for ksh88 but in ksh93 static scoping was specified. For example the output from
function f1
{
	print foo=$foo
}
function f2
{
	typeset foo=local
	f1
}
foo=global
f2
will be "global". To get f2 to cause f1 to print the local value of foo, f2 can run "foo=$foo f1" instead.
Can you write a self reproducing program in KornShell?
Yes, the following program is self reproducing. Any shorter ones?
n="
" q="'" x="cat <<-!" y=! z='n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y'
cat <<-!
n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y
!


redirections

How do I redirect both standard input and standard output to a file?
Add the following redirections to the command. > file 2> &1. This will redirect standard output (file descriptor 1) to "file" and standard error (file descriptor 2) to the same place as file descriptor 1. ksh redirection allows you to redirect any single digit file descriptor by putting the descriptor number in front of the redirection operator with no intervening space.
Is there a way for the shell to pick the file number when I open a file?
Yes, a redirection operator operator can be preceded by {n} without any intervening space where n is the name of a variable. The file descriptor will be placed in variable n.
How do I connect to a socket from a shell script?
exec 3<> /dev/tcp/hostname/portnum will open a tcp connection to portnum on hostname for reading and writing on file descriptor 3. You can then use read and print statements with file descriptor 3, or redirection operators <&3 or >&3 to use these connections.
How do I seek to a given location in a file?
The redirection operators <# and ># allow you to seek to a specified location in a file. The operator can be followed by an arithmetic expression contained in ((...)). The variables CUR and EOF can be used in the arithmetic expression to get relative locations or locations relative to the end of file respectively. Alternatively, <# and ># can be followed by a shell pattern. In this case, the file will be positioned to beginning of the next line containing this pattern.
What is the <<< redirection operator?
It denotes a here-document in which the document is contained the argument that follows <<< and therefore there is no delimiter.
What is the >; redirection operator?
This operator writes the output into a temporary file in the same directory as the file specified after >;. If the command completes successfully, then the file is replaced. Otherwise, the original file is unchanged and the temporary file removed.
What is the <>; redirection operator?
The file is opened for reading and writing as with <>. However, when the file is closed it is truncated to the its current location.


extensions

Is there a shell compiler?
There is a separate command named shcomp that will convert a script into an intermediate machine independent form. The shell will detect this format whenever it runs a script and execute directly from this intermediate format.
What is the advantage of making commands built-in?
The startup time is reduced by a couple of orders of magnitude. In addition, built-in commands can access ksh internals.
What is the disadvantage of making commands built-in?
Errors in these built-ins can cause the shell to crash.
How do I add built-in commands?
There are two ways to do this. One is write a shared library with functions whose names are b_xxxx where xxxx is the name of the builtin. The function b_xxxx takes three arguments. The first two are the same as a mail program. The third parameter is a pointer argument which will point to the current shell context. The second way is to write a shared library with a function named lib_init(). This function will be called with an argument of 0 after the library is loaded. This function can add built-ins with the sh_addbuiltin() API function. In both cases, the library is loaded into the shell with the "builtin" utility.
Can ksh93 be embedded?
Yes, ksh93 can be compiled as a shared or dynamically linked library which can be embedded into applications. There is an API for interfacing to shell variables and to several of the internal shell functions.
Can I write GUI applications with ksh?
There are two extensions to ksh that can be used to write GUI applications as shell script. One is dtksh which was written by Steve Pendergrast at Novell and is included with the Common Desktop Environment, CDE. The other is tksh which was written by Jeff Korn. tksh combines the tk graphics package with ksh93 and reimplements the tcl language as an extension so that both tcl and ksh scripts can run in the same address space. The source for tksh is included in the ast-open package.
show all answers hide all answers


June 19, 2012

ksh-1.0.0-beta.2/docs/ksh/features.html000066400000000000000000000154611415700074400176000ustar00rootroot00000000000000 www/ksh/features.mm mm document

ksh features

KSH-93 is the most recent version of the KornShell Language described in The KornShell Command and Programming Language, by Morris Bolsky and David Korn of AT&T Research. The KornShell is a shell programming language, which is upward compatible with sh (the Bourne Shell), and is intended to conform to the IEEE P1003.2/ISO 9945.2 Shell and Utilities standard. KSH-93 provides an enhanced programming environment in addition to the major command-entry features of the BSD shell csh. With KSH-93, medium-sized programming tasks can be performed at shell-level without a significant loss in performance. In addition, sh scripts can be run on KSH-93 without modification.

The code should conform to the IEEE POSIX 1003.1 standard and to the proposed ANSI C standard so that it should be portable to all such systems. Like the previous version, KSH-88, it is designed to accept eight bit character sets transparently, thereby making it internationally compatible. It can support multi-byte characters sets with some characteristics of the character set given at run time.

KSH-93 provides the following features, many of which were also inherent in KSH-88:

Enhanced Command Re-entry Capability

The KSH-93 history function records commands entered at any shell level and stores them, up to a user-specified limit, even after you log off. This allows you to re-enter long commands with a few keystrokes - even those commands you entered yesterday. The history file allows for eight bit characters in commands and supports essentially unlimited size histories.

In-line Editing

In sh the only way to fix mistyped commands is to backspace or retype the line. KSH-93 allows you to edit a command line using a choice of EMACS-TC or vi functions. You can use the in-line editors to complete filenames as you type them. You may also use this editing feature when entering command lines from your history file. A user can capture keystrokes and rebind keys to customize the editing interface.

Extended I/O Capabilities

KSH-93 provides several I/O capabilities not available in sh, including the ability to:
  • specify a file descriptor for input and output
  • start up and run co-processes
  • produce a prompt at the terminal before a read
  • easily format and interpret responses to a menu
  • echo lines exactly as output without escape processing
  • format output using printf formats.
  • read and echo lines ending in "\e".

Improved performance

KSH-93 executes many scripts faster than the System V Bourne shell. A major reason for this is that many of the standard utilities are built-in. To reduce the time to initiate a command, KSH-93 allows commands to be added as built-ins at run time on systems that support dynamic loading such as System V Release 4.

Arithmetic

KSH-93 allows you to do integer arithmetic in any base from two to sixty-four. You can also do double precision floating point arithmetic. Almost the complete set of C language operators are available with the same syntax and precedence. Arithmetic expressions can be used to as an argument expansion or as a separate command. In addition, there is an arithmetic for command that works like the for statement in C.

Arrays

KSH-93 supports both indexed and associative arrays. The subscript for an indexed array is an arithmetic expression, whereas, the subscript for an associative array is a string.

Functions and Aliases

Two mechanisms - functions and aliases - can be used to assign a user-selected identifier to an existing command or shell script. Functions allow local variables and provide scoping for exception handling. Functions can be searched for and loaded on first reference the way scripts are.

Substring Capabilities

KSH-93 allows you to create a substring of any given string either by specifying the starting offset and length, or by stripping off leading or trailing substrings during parameter substitution. You can also specify attributes, such as upper and lower case, field width, and justification to shell variables.

Enhanced pattern matching capabilities

KSH-93 allows you to specify regular expressions for file and string matches.

Improved debugging

KSH-93 can generate line numbers on execution traces. Also, I/O redirections are now traced. There is a DEBUG trap that gets evaluated after each command so that errors can be localized.

Job Control

On systems that support job control, including System V Release 4, KSH-93 provides a job-control mechanism almost identical to that of the BSD "csh", version 4.1. This feature allows you to stop and restart programs, and to move programs between the foreground and the background.

Added security

KSH-93 can execute scripts which do not have read permission and scripts which have the setuid and/or setgid set when invoked by name, rather than as an argument to the shell. It is possible to log or control the execution of setuid and/or setgid scripts. The noclobber option prevents you from accidentally erasing a file by redirecting to an existing file.

Documentation

Documentation for KSH-93 consists of an Introduction to KSH-93, Compatibility with the Bourne Shell, a manual page and a README file. In addition, the New KornShell Command and Programming Language book is available from Prentice Hall.


March 13, 2012

ksh-1.0.0-beta.2/docs/ksh/functions/000077500000000000000000000000001415700074400170755ustar00rootroot00000000000000ksh-1.0.0-beta.2/docs/ksh/functions/dirs.txt000066400000000000000000000047141415700074400206050ustar00rootroot00000000000000# # DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS # # Uses global parameters _push_max _push_top _push_stack integer _push_max=100 _push_top=100 # Display directory stack -- $HOME displayed as ~ function dirs { typeset dir="${PWD#$HOME/}" case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac print -r - "$dir ${_push_stack[@]}" } # Change directory and put directory on front of stack function pushd { typeset dir= type=0 integer i case $1 in "") # pushd if ((_push_top >= _push_max)) then print pushd: No other directory. return 1 fi type=1 dir=${_push_stack[_push_top]} ;; +[1-9]|+[1-9][0-9]) # pushd +n integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi type=2 dir=${_push_stack[i]} ;; *) if ((_push_top <= 0)) then print pushd: Directory stack overflow. return 1 fi esac case $dir in \~*) dir=$HOME${dir#\~} esac cd "${dir:-$1}" > /dev/null || return 1 dir=${OLDPWD#$HOME/} case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac case $type in 0) # pushd name _push_stack[_push_top=_push_top-1]=$dir ;; 1) # pushd _push_stack[_push_top]=$dir ;; 2) # push +n type=${1#+} i=_push_top-1 set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" shift $type for dir do (((i=i+1) < _push_max)) || break _push_stack[i]=$dir done esac dirs } # Pops the top directory function popd { typeset dir if ((_push_top >= _push_max)) then print popd: Nothing to pop. return 1 fi case $1 in "") dir=${_push_stack[_push_top]} case $dir in \~*) dir=$HOME${dir#\~} esac cd "$dir" || return 1 ;; +[1-9]|+[1-9][0-9]) typeset savedir integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi while ((i > _push_top)) do _push_stack[i]=${_push_stack[i-1]} i=i-1 done ;; *) print pushd: Bad directory. return 1 esac unset '_push_stack[_push_top]' _push_top=_push_top+1 dirs } ksh-1.0.0-beta.2/docs/ksh/functions/emacs_keybind.txt000066400000000000000000000005521415700074400224350ustar00rootroot00000000000000typeset -A Keytable trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD function emacs_keybind { keybind $'\E[A' $'\020' # Up key keybind $'\E[B' $'\016' # Down key keybind $'\E[C' $'\06' # Right key keybind $'\E[D' $'\02' # Left key keybind $'\E[H' $'\01' # Home key keybind $'\E[Y' $'\05' # End key keybind $'\t' $'\E\E' # Tab for command-line completion } ksh-1.0.0-beta.2/docs/ksh/functions/getopt.txt000066400000000000000000000007501415700074400211420ustar00rootroot00000000000000function getopt { typeset c optstring=$1 options= sep= shift while getopts $optstring c do case $c in [:?]) exit 2 ;; *) options="$options$sep-$c" sep=' ' if [[ $optstring == *$c:* ]] then options=" $options $OPTARG" fi #then print -rn -- " -$c" "$OPTARG" #else print -rn -- " -$c" ;; esac done print -rn -- "$options" if [[ ${@:$OPTIND-1} != -- ]] then print -rn -- " --" fi if [[ -n ${@:$OPTIND} ]] then print -r -- " ${@:$OPTIND}" fi } ksh-1.0.0-beta.2/docs/ksh/functions/keybind.txt000066400000000000000000000004321415700074400212620ustar00rootroot00000000000000typeset -A Keytable trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD function keybind # key action { typeset key=$(print -f "%q" "$2") case $# in 2) Keytable[$1]='.sh.edchar=${.sh.edmode}'"$key" ;; 1) unset Keytable[$1] ;; *) print -u2 "Usage: $0 key [action]" ;; esac } ksh-1.0.0-beta.2/docs/ksh/functions/popd.txt000066400000000000000000000047121415700074400206040ustar00rootroot00000000000000# # DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS # # Uses global parameters _push_max _push_top _push_stack integer _push_max=100 _push_top=100 # Display directory stack -- $HOME displayed as ~ function dirs { typeset dir="${PWD#$HOME/}" case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac print -r - "$dir ${_push_stack[@]}" } # Change directory and put directory on front of stack function pushd { typeset dir= type=0 integer i case $1 in "") # pushd if ((_push_top >= _push_max)) then print pushd: No other directory. return 1 fi type=1 dir=${_push_stack[_push_top]} ;; +[1-9]|+[1-9][0-9]) # pushd +n integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi type=2 dir=${_push_stack[i]} ;; *) if ((_push_top <= 0)) then print pushd: Directory stack overflow. return 1 fi esac case $dir in \~*) dir=$HOME${dir#~} esac cd "${dir:-$1}" > /dev/null || return 1 dir=${OLDPWD#$HOME/} case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac case $type in 0) # pushd name _push_stack[_push_top=_push_top-1]=$dir ;; 1) # pushd _push_stack[_push_top]=$dir ;; 2) # push +n type=${1#+} i=_push_top-1 set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" shift $type for dir do (((i=i+1) < _push_max)) || break _push_stack[i]=$dir done esac dirs } # Pops the top directory function popd { typeset dir if ((_push_top >= _push_max)) then print popd: Nothing to pop. return 1 fi case $1 in "") dir=${_push_stack[_push_top]} case $dir in \~*) dir=$HOME${dir#~} esac cd "$dir" || return 1 ;; +[1-9]|+[1-9][0-9]) typeset savedir integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi while ((i > _push_top)) do _push_stack[i]=${_push_stack[i-1]} i=i-1 done ;; *) print pushd: Bad directory. return 1 esac unset '_push_stack[_push_top]' _push_top=_push_top+1 dirs } ksh-1.0.0-beta.2/docs/ksh/functions/pushd.txt000066400000000000000000000047141415700074400207670ustar00rootroot00000000000000# # DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS # # Uses global parameters _push_max _push_top _push_stack integer _push_max=100 _push_top=100 # Display directory stack -- $HOME displayed as ~ function dirs { typeset dir="${PWD#$HOME/}" case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac print -r - "$dir ${_push_stack[@]}" } # Change directory and put directory on front of stack function pushd { typeset dir= type=0 integer i case $1 in "") # pushd if ((_push_top >= _push_max)) then print pushd: No other directory. return 1 fi type=1 dir=${_push_stack[_push_top]} ;; +[1-9]|+[1-9][0-9]) # pushd +n integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi type=2 dir=${_push_stack[i]} ;; *) if ((_push_top <= 0)) then print pushd: Directory stack overflow. return 1 fi esac case $dir in \~*) dir=$HOME${dir#\~} esac cd "${dir:-$1}" > /dev/null || return 1 dir=${OLDPWD#$HOME/} case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac case $type in 0) # pushd name _push_stack[_push_top=_push_top-1]=$dir ;; 1) # pushd _push_stack[_push_top]=$dir ;; 2) # push +n type=${1#+} i=_push_top-1 set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" shift $type for dir do (((i=i+1) < _push_max)) || break _push_stack[i]=$dir done esac dirs } # Pops the top directory function popd { typeset dir if ((_push_top >= _push_max)) then print popd: Nothing to pop. return 1 fi case $1 in "") dir=${_push_stack[_push_top]} case $dir in \~*) dir=$HOME${dir#\~} esac cd "$dir" || return 1 ;; +[1-9]|+[1-9][0-9]) typeset savedir integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi while ((i > _push_top)) do _push_stack[i]=${_push_stack[i-1]} i=i-1 done ;; *) print pushd: Bad directory. return 1 esac unset '_push_stack[_push_top]' _push_top=_push_top+1 dirs } ksh-1.0.0-beta.2/docs/ksh/functions/title.txt000066400000000000000000000015441415700074400207630ustar00rootroot00000000000000# add to (+), delete from (-), print (.), or set ([=]) window title # arguments are eval'd before printing # title text string exported in TITLE_TEXT function title # [+ | - | =] title ... { typeset x t="$TITLE_TEXT" case $1 in +) shift case $# in 0) ;; *) for x do case " $t " in *" $x "*) ;; " ") t=$x ;; *) t="$t $x" ;; esac done case $t in $TITLE_TEXT) return 1 ;; esac ;; esac ;; -) shift case $# in 0) ;; *) for x do case " $t " in *" $x "*) t="${t%?( )$x*}${t##*$x?( )}" ;; esac done case $t in $TITLE_TEXT) return 1 ;; esac ;; esac ;; .) print -r -- "$TITLE_TEXT" return 0 ;; *) t="$*" ;; esac export TITLE_TEXT="$t" eval x=\"$t\" case $TERM in 630*) print -nr -- "[?${#x};0v$x" ;; vt100|xterm*) print -nr -- "]0;$x" ;; *) return 1 ;; esac return 0 } ksh-1.0.0-beta.2/docs/ksh/functions/vi_keybind.txt000066400000000000000000000004071415700074400217620ustar00rootroot00000000000000typeset -A Keytable trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD function vi_keybind { keybind $'\E[A' k # Up key keybind $'\E[B' j # Down key keybind $'\E[C' l # Right key keybind $'\E[D' h # Left key keybind $'\t' '\' # Tab for command-line completion } ksh-1.0.0-beta.2/docs/ksh/index.html000066400000000000000000000003721415700074400170640ustar00rootroot00000000000000 KSH93 Overview
FAQ
Features
Builtins
Examples ksh-1.0.0-beta.2/docs/ksh/ksh.html000066400000000000000000000112641415700074400165440ustar00rootroot00000000000000 www/ksh/ksh.mm mm document

ksh overview

The KornShell language was designed and developed by David G. Korn at AT&T Bell Laboratories and AT&T Research. It is an interactive command language that provides access to the UNIX system and to many other systems, on the many different computers and workstations on which it is implemented. The KornShell language is also a complete, powerful, high-level programming language for writing applications, often more easily and quickly than with other high-level languages. This makes it especially suitable for prototyping. There are two other widely used shells, the Bourne shell developed by Steven Bourne at AT&T Bell Laboratories, and the C shell developed by Bill Joy at the University of California. ksh has the best features of both, plus many new features of its own. Thus ksh can do much to enhance your productivity and the quality of your work, both in interacting with the system, and in programming. ksh programs are easier to write, and are more concise and readable than programs written in a lower level language such as C.

The new version of ksh has the functionality of other scripting languages such as awk, icon, perl, rexx, and tcl. For this and many other reasons, ksh is a much better scripting language than any of the other popular shells. The code size for ksh is larger than the Bourne shell or C shell programs. The revised version is even larger.

In spite of its increased size, ksh provides better performance. You can write programs to run faster with ksh than with either the Bourne shell or the C shell, sometimes an order of magnitude faster. ksh has evolved and matured with extensive user feedback. It has been used by many thousands of people at AT&T since 1982, and at many other companies and universities. A survey conducted at one of the largest AT&T Bell Laboratories computer centers showed that 80% of their customers, both programmers and non-programmers, use ksh. ksh is compatible with the Bourne shell. Virtually all programs written for the Bourne shell run with ksh. If you are familiar with the Bourne shell, you can use ksh immediately, without retraining. The new version of ksh is compatible with earlier versions of ksh. ksh is readily available. It is sold (source and binary) by AT&T and Novell, and by other companies under license from AT&T both in the USA and abroad. It has been purchased by dozens of major corporations, and by many individuals for use on home computers. ksh is extensible.

The KornShell language uses the same syntax for built-in commands as for non built-in commands. Therefore, system developers can add new commands "transparently" to the KornShell language; that is, with minimum effort and with no differences visible to users other than faster execution. On systems with dynamic linking, it is possible to add new built-in commands at run time. Novell has extended the new version of ksh to enable X-windows programming for their desktop ksh product, dtksh. dtksh is a standard part of CDE, the Common Desktop Environment defined by COSE (Common Operating System Environment), supported by most major UNIX system hardware vendors. An extended version of ksh that enables Tk programming, called tksh, is available as well.

ksh is intended to conform to the Shell Language Standard developed by the IEEE POSIX 1003.2 Shell and Utilities Language Committee.


March 13, 2012

ksh-1.0.0-beta.2/docs/ksh/scripts/000077500000000000000000000000001415700074400165545ustar00rootroot00000000000000ksh-1.0.0-beta.2/docs/ksh/scripts/cgi-lib.ksh.txt000066400000000000000000000046671415700074400214240ustar00rootroot00000000000000typeset -A COOKIE HEADER typeset Cgi _CGI_c _CGI_multipart function cgi_header { typeset h for h in "${!HEADER[@]}" do printf '%s: %s\n' "$h" "${HEADER[$h]}" done print } function cgi_url { if [[ $SERVER_PORT != 80 ]] then print "http://$SERVER_NAME:$SERVER_PORT$SCRIPT_NAME" else print "http://$SERVER_NAME$SCRIPT_NAME" fi } function cgi_parse { if [[ $REQUEST_METHOD == POST ]] then if [[ $CONTENT_TYPE == multipart/form-data* ]] then _CGI_multipart=${TMPDIR-/tmp}/cgi-form-$$ trap 'rm -rf "$_CGI_multipart"' EXIT mkdir $_CGI_multipart unset -f Cgi.set typeset -A Cgi.file typeset i b v pax --nosummary --read --edit ",.*/,," --edit ",^,$_CGI_multipart/," for i in $_CGI_multipart/* do b=${i##*/} if [[ $b == +([a-z]) ]] then v=$(<$i) eval Cgi.$b='$v' else Cgi.file[$b]=$i fi done else Cgi=$(<&0) # Read from stdin fi else Cgi="$QUERY_STRING" fi cgi_cookie "$HTTP_COOKIE" HEADER["Content-type"]="text/html" } function cgi_cookie { typeset cookie=$1 name val c IFS=';' set -- $cookie for c do IFS='=' set -- $c name=${1##' '} val=${2##' '} # trim white space name=${name%%' '} val=${val%%' '} COOKIE[$name]=$val done } function cgi_setcookie # name value { HEADER["Set-Cookie"]="$1=$2; path=$SCRIPT_NAME" } ## Cgi variable disciplines function Cgi.set { set -f typeset i j n val IFS='&' set -- ${.sh.value} for i do n=${i%%=*} [[ $n == [[:alpha:]_]*([[:alnum:]_]) ]] || continue val=${i#$n=} val=${val//+/ } val=${val//@([\'\\])/'\'\1} eval j=\${#${.sh.name}.${n}[@]} \ "${.sh.name}.${n}[j]=\$'${val//'%'@(??)/'\x'\1"'\$'"}'" done } function cgi_C_init { integer i for ((i=1; i < 256; i++)) do if (( i!=16#22 && i!=16#27 && i!=16#5C && i!=16#5B && i!=16#5D )) then printf $'_CGI_c[$\'\\\\x%.2X\']=%%%.2X\n' $i $i fi done print } function cgi_encode { typeset v=$1 var=${v//' '/+} cbrace='}' eval var=${var//@([!a-zA-Z0-9_+])/\${_CGI_c[\\\1]$cbrace} print -r -- "$var" } function Cgi.get { typeset i val name vname if [[ ! ${_CGI_c[\\]} ]] then val='"' _CGI_c[""]=%00 _CGI_c[$var]=%22 _CGI_c[\']=%27 _CGI_c[\]]=%5B _CGI_c[\[]=%5D _CGI_c[\\]=%5C eval $(cgi_C_init) unset -f cgi_C_init fi vname=${.sh.name} # .sh.name contains variable name .sh.value= # .sh.value stores value for i in ${!Cgi.@} do name=${i#$vname.} nameref v=${i} val=$(cgi_encode "$v") .sh.value="${.sh.value}${.sh.value:+&}$name=$val" done } ksh-1.0.0-beta.2/docs/ksh/scripts/dump-cgi.ksh.txt000066400000000000000000000003131415700074400216030ustar00rootroot00000000000000#!/bin/ksh . ./cgi-lib.ksh cgi_parse cgi_header print "" print "
"
print -r "Url: $(cgi_url)"
for i in ${!Cgi.*}
do
	nameref val=$i
	print -r "$i = $val"
done
print "
" print "" ksh-1.0.0-beta.2/docs/ksh/scripts/env.txt000066400000000000000000000036151415700074400201120ustar00rootroot00000000000000#! /usr/bin/ksh # shell version of env command case $(getopts '[-]' opt '--???man' 2>&1) in version=[0-9]*) usage=$'[-?@(#)env (AT&T Labs Research) 1999-05-20\n] [-author?David Korn ] [-license?http://www.research.att.com/sw/tools/reuse] [+NAME?env - set environment for command invocation] [+DESCRIPTION?\benv\b modifies the current environment according to the \aname\a\b=\b\avalue\a arguments, and then invokes \acommand\a with the modified environment.] [+?If \acommand\a is not specified, the resulting environment is written to standard output quoted as required for reading by the \bsh\b.] [i:ignore-environment?Invoke \acommand\a with the exact environment specified by the \aname\a\b=\b\avalue\a arguments; inherited environment variables are ignored. As an obsolete feature, \b-\b by itself can be specified instead of \b-i\b.] [u:unset]:[name?Unset the environment variable \aname\a if it was in the environment. This option can be repeated to unset additional variables.] [name=value]... [command ...] [+EXIT STATUS?If \acommand\a is invoked, the exit status of \benv\b will be that of \acommand\a. Otherwise, it will be one of the following:]{ [+0?\benv\b completed successfully.] [+126?\acommand\a was found but could not be invoked.] [+127?\acommand\a could not be found.] } [+SEE ALSO?\bsh\b(1), \bexport\b(1)] ' ;; *) usage='iu:[name] [name=value]... [command ...]' ;; esac clear= while getopts "$usage" var do case $var in i) clear=1;; u) command unset $OPTARG 2> /dev/null;; esac done #[[ $var == "" ]] || exit 1 shift $((OPTIND-1)) if [[ $1 == - ]] # obsolete form then clear=1 shift fi if [[ $clear == 1 ]] then typeset +x $(typeset +x) fi while true do case $1 in *=*) export "$1";; *) break;; esac shift done if (( $# >0 )) then exec "$@" else export exit 0 fi ksh-1.0.0-beta.2/docs/ksh/scripts/line.txt000066400000000000000000000000541415700074400202430ustar00rootroot00000000000000#! /bin/ksh read -r && print -r -- "$REPLY" ksh-1.0.0-beta.2/docs/ksh/scripts/which.txt000066400000000000000000000000331415700074400204130ustar00rootroot00000000000000#! /bin/ksh whence -p "$@" ksh-1.0.0-beta.2/src/000077500000000000000000000000001415700074400141375ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/Mamfile000066400000000000000000000013071415700074400154350ustar00rootroot00000000000000info mam static note * note * This build file is in the Make Abstract Machine (MAM) language. It was note * first generated by nmake, but in the ksh 93u+m distribution we maintain note * it manually because nmake had too many problems to keep using. The note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added note * support for indentation to improve readability. The language is note * documented in Glenn Fowler's paper "A Make Abstract Machine": note * http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html note * note source level :MAKE: equivalent make install make all exec - ${MAMAKE} -r '*/*' ${MAMAKEARGS} done all virtual done install virtual ksh-1.0.0-beta.2/src/cmd/000077500000000000000000000000001415700074400147025ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/cmd/INIT/000077500000000000000000000000001415700074400154455ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/cmd/INIT/C+probe000066400000000000000000000417001415700074400166570ustar00rootroot00000000000000: ### this script contains archaic constructs that work with all sh variants ### # Glenn Fowler # AT&T Research # # @(#)C probe (AT&T Research) 2012-02-29 # # probe [ -d ] c-compiler-path [ attributes ] # # common C probe preamble for the tool specific probes # # NOTE: some cc -E's do syntax analysis! # # probe_* are first eval'd and then attempted from left to right # probe_binding="-dy -dn -Bdynamic -Bstatic '-Wl,-ashared -Wl,+s' -Wl,-aarchive -call_shared -non_shared -dynamic -static -bshared -bstatic '' -static" probe_env="CC_OPTIONS CCOPTS LD_OPTIONS LDOPTS LIBPATH LPATH" probe_include="stdio.h iostream.h complex.h ctype.h plot.h stdarg.h varargs.h ranlib.h hash.h sys/types.h stab.h cmath cstdio iostream string" probe_longlong="long 'long long'" probe_longlong_t="__int64_t _int64_t __int64 _int64 int64" probe_l="l yyreject m sin mopt sin" probe_lxx="C exit ++ exit g++ exit" probe_ppprefix="a n" probe_size="size" probe_src="cxx C cc c" probe_sa=".sa" probe_sd=".dll .lib .dll .x" probe_sdb=".pdb" probe_so=".dylib .so .sl" probe_symprefix="_" probe_verbose="'-v -v' '-# -#' '-d -d' -dryrun '-V -V'" probe_version="--version -V -version -v" # # the following are set by the preamble for the tool specific probe # cc=cc debug= dir=. dll=.dll dynamic= exe=exe executable="test -x" hosted= ifs=${IFS-' '} obj=o ppenv= ppopt= predef= prepred= sa= sd= sdb= so= sov= static= stdlib= stdpp= suffix_command= if test "" != "$TMPDIR" -a -d "$TMPDIR" then tmpdir=$TMPDIR else tmpdir=/tmp fi tmpdir=$tmpdir/probe$$ undef="define defined elif else endif error if ifdef ifndef include line pragma undef __STDC__ __STDPP__ __ARGC__ __BASE__ __BASE_FILE__ __DATE__ __FILE__ __FUNCTION__ __INCLUDE_LEVEL__ __LINE__ __PATH__ __TIME__ __TIMESTAMP__ __VERSION__" version_flags= version_stamp= version_string= # # constrain the environment # DISPLAY= LC_ALL=C export DISPLAY LC_ALL # # now the common probes # while : do case $1 in -d) debug=1 ;; -*) set ''; break ;; *) break ;; esac shift done cc=$1 case $cc in [\\/]*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\*) ;; *) echo "Usage: $0 [ -d ] c-compiler-path [ attributes ]" >&2 exit 1 ;; esac ATTRIBUTES= eval $2 _probe_PATH=$PATH PATH=/usr/bin:/bin:$PATH case $0 in *[\\/]*) dir=`echo $0 | sed -e 's,[\\/][\\/]*[^\\/]*\$,,'` ;; esac $executable . 2>/dev/null || executable='test -r' case $SHELL in [\\/]*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\*) sh=$SHELL ;; *) sh=/bin/sh ;; esac trap 'code=$?; cd ..; rm -rf $tmpdir; exit $code' 0 1 2 3 mkdir $tmpdir cd $tmpdir exec 3>&1 4>&2 /dev/null 2>&1 (ulimit -c 0) >/dev/null 2>&1 && ulimit -c 0 ;; *) PS4='+$LINENO+ ' set -x ;; esac if (xxx=xxx; unset xxx) then UNSET=1 else UNSET= fi eval set x $probe_env while : do shift case $# in 0) break ;; esac eval x='$'$1 case $x in '') continue ;; esac case $1 in *PATH) _probe_export="$_probe_export $1='$x'" ;; esac case $UNSET in '') eval $1= export $1 ;; *) unset $1 ;; esac done if test -f "$dir/probe.ini" then . "$dir/probe.ini" IFS=$ifs fi mkdir suffix cd suffix for src in $probe_src do echo "int main(){return 0;}" > ../test.$src rm -f test* if $cc -c ../test.$src then set test.* if test -f "$1" then o="$*" mv $* .. for i in $o do if $cc -o test.exe ../$i then obj=`echo "$i" | sed -e 's,test.,,'` $executable test.exe || executable="test -r" set test* rm * if $cc -o test ../$i then rm $* set test.* if $executable "$1" then exe=`echo "$1" | sed -e 's,test.,,'` suffix_command=.$exe fi fi break 2 fi done fi fi done cd .. case $src in c) ;; *) echo '// ( int main() { class { public: int i; } j; j.i = 0; int k = j.i + 1; return k; }' > dialect.$src if $cc -c dialect.$src && $cc -o dialect.$exe dialect.$obj && $executable dialect.$exe then mv dialect.$src dialect.c rm -f dialect.$obj dialect.$exe if $cc -c dialect.c && $cc -o dialect.$exe dialect.$obj && $executable dialect.$exe then src=c else set x $cc while : do shift case $# in 0) break ;; esac case $1 in *=*) continue ;; esac case `echo $1 | sed -e 's,.*/,,'` in *CC*|*++*|*[xX][xX]*|*[pP][lL][uU][sS]*) ;; *) src=c ;; esac break done fi else src=c fi ;; esac set x x '(' 1 'int x;' 0 while : do shift shift case $# in [01]) break ;; esac rm -f test.$obj echo "$1" > test.$src $cc -c test.$src r=$? case $r in 0) test -f test.$obj || r=1 ;; *) r=1 ;; esac case $2:$r in 0:0) ;; 0:1) echo "$cc: not a C compiler: failed to compile \`\`$1''" >&4 exit 1 ;; 1:0) echo "$cc: not a C compiler: successfully compiled \`\`$1''" >&4 exit 1 ;; esac done hosttype=`package CC="$cc" || $SHELL -c "package CC='$cc'"` case $hosttype in *[Uu][Ss][Aa][Gg][Ee]:*) hosttype=`PATH=$_probe_PATH; export PATH; package CC="$cc" || $SHELL -c "package CC='$cc'"` ;; esac echo '#include int main(){printf("hello");return 0;}' > dynamic.$src echo 'extern int sfclose() { return 0; }' > fun.$src if $cc -c dynamic.$src && $cc -c fun.$src then eval set x $probe_so while : do shift case $# in 0) break ;; esac for i in foo junk do rm -f dynamic.$exe if $cc -L. -o dynamic.$exe dynamic.$obj -l$i then : "there's really a -l$i"? else rm -f dynamic.$exe cat fun.$obj > lib$i$1 $cc -L. -o dynamic.$exe dynamic.$obj -l$i && $executable dynamic.$exe x=$? rm lib$i$1 case $x in 0) so=$1 rm -f dynamic.$exe > lib$i$1.1 $cc -L. -o dynamic.$exe dynamic.$obj -l$i && $executable dynamic.$exe x=$? rm lib$i$1.1 case $x in 0) sov=1 ;; esac break 2 ;; *) break ;; esac fi done k= for i in "" .1 .2 .3 .4 .5 .6 .7 .8 .9 do rm -f dynamic.$exe > libc$1$i $cc -L. -o dynamic.$exe dynamic.$obj && $executable dynamic.$exe x=$? (cd ..; rm $tmpdir/libc$1$i) case $x in 0) ;; *) k=X$k case $k in XXX) break ;; esac ;; esac done case $k in XXX) so=$1 sov=1 break ;; ?*) so=$1 break ;; esac done rm -f dynamic.$exe if $cc -o dynamic.$exe dynamic.$obj 2>e && $executable dynamic.$exe then e=`wc -l e` maybe= eval set x x $probe_binding while : do shift shift case $# in 0) break ;; esac rm -f dynamic.$exe $cc -o dynamic.$exe $1 dynamic.$obj 2>e && $executable dynamic.$exe || continue case $1 in ?*) case $maybe in "") maybe=$1 ;; *) maybe=-- ;; esac ;; esac case `wc -l e` in $e) ;; *) continue ;; esac d=`ls -s dynamic.$exe` rm -f dynamic.$exe $cc -o dynamic.$exe $2 dynamic.$obj 2>e && $executable dynamic.$exe || continue case `wc -l e` in $e) ;; *) continue ;; esac case `ls -s dynamic.$exe` in $d) ;; *) dynamic=$1 static=$2 maybe= break ;; esac done case $maybe in ""|--) ;; *) rm -f dynamic.$exe if $cc -o dynamic.$exe $maybe dynamic.$obj 2>e && $executable dynamic.$exe then e=`wc -l e` if $cc -o dynamic.$exe $maybe-bogus-bogus-bogus dynamic.$obj 2>e && $executable dynamic.$exe then case `wc -l e` in $e) ;; *) dynamic=$maybe ;; esac else dynamic=$maybe fi fi ;; esac fi fi eval set x $probe_version shift for o in "$@" do if $cc $o > version.out 2>&1 then version_string=`sed -e '/ is /d' -e 's/;/ /g' version.out | sed -e 1q` case $version_string in ''|*[Ee][Rr][Rr][Oo][Rr]*|*[Ff][Aa][Tt][Aa][Ll]*|*[Ww][Aa][Rr][Nn][Ii][Nn][Gg]*|*[Oo][Pp][Tt][Ii][Oo][Nn]*) ;; *) version_flags=$o version_stamp=";VERSION;$o;$version_string;PATH;$cc" break ;; esac fi done case $version_stamp in '') eval set x $probe_version shift echo 'int main() { return 0; }' > version.i for o in "$@" do if $cc -c $o version.i > version.out 2>&1 then version_string=`sed -e '/ is /d' -e 's/;/ /g' version.out | sed -e 1q` case $version_string in ''|*[Ee][Rr][Rr][Oo][Rr]*|*[Ff][Aa][Tt][Aa][Ll]*|*[Ww][Aa][Rr][Nn][Ii][Nn][Gg]*|*[Oo][Pp][Tt][Ii][Oo][Nn]*) ;; *) version_flags=$o break ;; esac fi done ;; esac echo 'int main(){return 0;}' > hosted.$src $cc -o hosted.$exe hosted.$src && ./hosted.$exe && hosted=1 echo '#!'$sh' echo "" $@' > cpp chmod +x cpp case `./cpp -Dprobe` in *-Dprobe*) ;; *) cp /bin/echo cpp chmod u+w cpp ;; esac for prefix in $probe_ppprefix `echo $cc | sed -e '/cc\$/!d' -e 's,cc\$,,' -e 's,.*/,,'` do cp cpp ${prefix}cpp done echo "" > flags.$src echo '#pragma pp:version' > libpp.$src if test `realcppC=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppenv='realcppC=${ppcmd}' elif test `cppC=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppenv='cppC=${ppcmd}' elif test `_CPPNAME=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppenv='_CPPNAME=${ppcmd}' elif test `_CPP=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppenv='_CPP=${ppcmd}' elif test `$cc -Dprobe -E -%p+. flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 && test `$cc -Dprobe -E -%p+. flags.$src | wc -l` -eq 1 then ppopt='-%p+${ppdir}' elif test `$cc -Dprobe -E -Yp,. flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppopt='-Yp,${ppdir}' elif test `$cc -Dprobe -E -Qpath $tmpdir flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppopt='-Qpath ${ppdir}' elif test `$cc -Dprobe -E -tp -B./ flags.$src 2>err.out | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 -a ! -s err.out then ppopt='-tp -B${ppdir}/' elif test `$cc -Dprobe -E -B./ flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppopt='-B${ppdir}/' elif test `$cc -Dprobe -E -tp -h./ -B flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppopt='-tp -h${ppdir}/ -B' elif test `$cc -Dprobe -E -t p,./cpp flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 then ppopt='-t p,${ppcmd}' else { eval set x $probe_verbose shift for o in "$@" do $cc -E $o flags.$src done } 2>&1 | sed -e "s/['\"]//g" > cpp.out fi set x `sed -e 's,[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\\\,/,g' -e 's,\\\\,/,g' cpp.out` def= definclude="-I+C -I-H" stdinclude=$definclude case $hosted in "") usrinclude= ;; esac cmdinclude= while : do case $# in 0|1) break ;; esac shift case $1 in -A) case $2 in *\(*\)) shift prepred="$prepred `echo $1 | sed 's/\(.*\)(\(.*\))/\1 \2/'`" ;; esac ;; -A\(*\)) prepred="$prepred `echo $1 | sed 's/-A\(.*\)(\(.*\))/\1 \2/'`" ;; -[DI][-+][ABCDEFGHIJKLMNOPQRSTUVWXYZ]*) stdpp=1 case $1 in -I?[CH]) case $def in ?*) definclude="$definclude $1" ;; *) stdinclude="$stdinclude $1" ;; esac ;; -I-S*|-YI,*) usrinclude="`echo $1 | sed 's/....//'`" ;; -Y?,*) ;; -Y*) usrinclude="`echo $1 | sed 's/..//'`" ;; esac ;; -D) shift case $1 in [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*=*) predef="$predef `echo $1 | sed -e 's/=.*//'`" ;; [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*) predef="$predef $1" ;; esac ;; -Dprobe);; -D*) case $1 in -D[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*=*) predef="$predef `echo $1 | sed -e 's/^-D//' -e 's/=.*//'`" ;; -D[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*) predef="$predef `echo $1 | sed -e 's/^-D//'`" ;; esac ;; -I) shift case $1 in /*) case $def in ?*) definclude="$definclude $1" ;; *) stdinclude="$stdinclude $1" ;; esac cmdinclude="$cmdinclude $1" ;; esac ;; -I/*) f=`echo X$1 | sed 's/X-I//'` case $def in ?*) definclude="$definclude $f" ;; *) stdinclude="$stdinclude $f" ;; esac cmdinclude="$cmdinclude $f" ;; -U) shift undef="$undef $1" ;; -U*) undef="$undef `echo $1 | sed 's/^-U//'`" ;; flags.$src)def= ;; esac done stdinclude="$stdinclude $definclude" case " $stdinclude " in *\ $usrinclude\ *) case $usrinclude in /usr/include) usrinclude= ;; *) case " $stdinclude " in *\ /usr/include\ *) usrinclude= ;; *) usrinclude=/usr/include ;; esac ;; esac ;; esac tstinclude=`$cc -v -E flags.$src 2>&1 | sed -e '1,/[iI][nN][cC][lL][uU][dD][eE][ ]*<[.][.][.]>/d' -e '/^[eE][nN][dD] [oO][fF] [sS][eE][aA][rR][cC][hH]/,\$d'` j=$tstinclude case $j in */*) ;; *) j=$cmdinclude ;; esac tstinclude= good= nogood= c_hdr="stdio.h ctype.h" C_hdr="libc.h" for i in $j do if test -d "$i" then tstinclude="$tstinclude $i" h= for f in $c_hdr do if test -f "$i/$f" then case $i in */CC) nogood=1 ;; *) good=1 ;; esac else h="$h $f" fi done c_hdr=$h h= for f in $C_hdr do if test -f "$i/$f" then case $i in */CC) nogood=1 ;; *) good=1 ;; esac else h="$h $f" fi done C_hdr=$h fi done case $nogood in 1) good=0 ;; esac case $good in 1) case $c_hdr in ?*) bad=1 usrinclude=/usr/include set '' $tstinclude /usr/include ;; *) set '' $tstinclude ;; esac shift stdinclude=$* echo "#include " > include.$src $cc -E include.$src | sed -e '/# 1 "[\\/]/!d' -e 's,[^"]*",,' -e 's,[\\/][^\\/]*".*,,' -e 's,[\\/]sys,,' > include.out for f in `cat include.out` do if test -d "$f" then g=`echo $f | sed -e 's,[\\/][\\/]*[^\\/]*$,,'` case " $stdinclude " in *\ $f\ *|*\ $g\ *) ;; *) stdinclude="$stdinclude $f" case $f in /usr/include) usrinclude=$f ;; esac bad=1 ;; esac fi done ;; *) case $ppopt$ppenv in ?*) echo '#!'$sh' echo $VIRTUAL_ROOT | sed "s/:.*//"' > cpp chmod +x cpp ppcmd=cpp ppdir=. eval x='`'$ppenv '$'cc -E $ppopt flags.$src'`' case $x in ?*) tstinclude=$x/usr/include ;; esac cp /bin/echo cpp chmod u+w cpp ;; esac eval set x $probe_include while : do shift case $# in 0) break ;; esac echo "#include <$1>" > include.$src $cc -E include.$src done > include.out ccinclude= x=$stdinclude stdinclude= subinclude= for f in $x $tstinclude `sed -e 's,\\\\,/,g' -e 's,///*,/,g' -e 's,"[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:/,"/,g' -e '/^#[line ]*[0123456789][0123456789]*[ ][ ]*"[\\/]/!d' -e 's/^#[line ]*[0123456789][0123456789]*[ ][ ]*"\(.*\)[\\/].*".*/\1/' include.out | sort -u` do case $f in -*) ;; */) f=`echo $f | sed -e 's,//*\$,,'` ;; */.) f=`echo $f | sed -e 's,//*.\$,,'` ;; esac case $f in -I*) ;; */cc) ccinclude=1 ;; */sys) continue ;; */include/*/*) ;; */include/*) subinclude="$subinclude $f" continue ;; esac if test -d "$f" then case " $stdinclude " in *\ $f\ *) ;; *) stdinclude="$stdinclude $f" ;; esac fi done rm include.out case $ccinclude in ?*) eval set x $probe_include while : do shift case $# in 0) break ;; esac echo "#include " > include.$src if $cc -E include.$src > /dev/null then break fi done case $# in 0) ;; *) x=$stdinclude stdinclude= for f in $x do case $f in */cc) ;; *) stdinclude="$stdinclude $f" ;; esac done ;; esac ;; esac case $subinclude in ?*) for i in $subinclude do for j in $stdinclude do case $i in $j/*/*) ;; $j/*) both= eval set x $probe_include while : do shift case $# in 0) for k in $both do echo "#include <$k>" > include.$src $cc -E include.$src > include.out I=`grep -c $i/$k < include.out` J=`grep -c $j/$k < include.out` case $I:$J in 0:*) ;; *:0) stdinclude="$i $stdinclude" break ;; esac done continue 3 ;; esac if test -f $i/$1 then if test ! -f $j/$1 then break 2 fi both="$both $1" fi done ;; $j) continue 2 ;; esac done stdinclude="$i $stdinclude" done ;; esac { for i in $stdinclude do case $i in $usrinclude) ;; *) echo $i $i ;; esac done eval set x $probe_include while : do shift case $# in 0) break ;; esac echo "#include <$1>" > t.c p= for j in `$cc -E t.c | grep "$1" | sed -e 's,\\\\,/,g' -e 's,"[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:/,"/,g' -e '/^#[line ]*1[ ][ ]*"[\\/]/!d' -e 's/^#[line ]*1[ ][ ]*"\(.*\)[\\/].*".*/\1/'` do j=`echo $j | sed -e 's,///*,/,g' -e 's,/$,,'` case $p in ?*) echo $p $j ;; esac p=$j done done case $usrinclude in ?*) echo $usrinclude $usrinclude ;; esac } | tsort > tmp.tmp tstinclude=`cat tmp.tmp` bad= for i in $stdinclude do case " $tstinclude " in *" $i "*) ;; *) bad=1 break ;; esac done ;; esac case $bad in "") x=$stdinclude stdinclude= z= for i in $tstinclude do case " $x " in *" $i "*) stdinclude="$stdinclude $i" z=$i ;; esac done case $usrinclude in '') usrinclude=$z ;; esac ;; esac case $hosted in "") case $usrinclude in /usr/include) usrinclude= ;; esac ;; esac case $usrinclude in ?*) case " $stdinclude " in *\ $usrinclude\ *) x=$stdinclude stdinclude= for f in $x do case $f in $usrinclude) ;; *) stdinclude="$stdinclude $f" ;; esac done ;; esac ;; esac # drop dups -- they creep in somehow x=$stdinclude stdinclude= for f in $x do case " $stdinclude $usrinclude " in *" $f "*) ;; *) stdinclude="$stdinclude $f" ;; esac done ksh-1.0.0-beta.2/src/cmd/INIT/Mamfile000066400000000000000000001113361415700074400167470ustar00rootroot00000000000000info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-06-20 note * note * This build file is in the Make Abstract Machine (MAM) language. It was note * first generated by nmake, but in the ksh 93u+m distribution we maintain note * it manually because nmake had too many problems to keep using. The note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added note * support for indentation to improve readability. The language is note * documented in Glenn Fowler's paper "A Make Abstract Machine": note * http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html note * setv INSTALLROOT ../../.. setv PACKAGEROOT ../../../../.. setv CC cc setv mam_cc_FLAGS setv KSH_RELFLAGS setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} setv COTEMP $$ setv LDFLAGS make install make iffe make iffe.sh done iffe.sh meta iffe %.sh>% iffe.sh iffe prev iffe.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : iffe contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n iffe.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 225 in exec - 0) cp iffe.sh iffe exec - ;; exec - *) { exec - i=`(read x; echo $x) < iffe.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat iffe.sh exec - } > iffe exec - ;; exec - esac exec - ;; exec - *) cat - iffe.sh > iffe <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w iffe -a -x iffe || chmod u+w,+x iffe done iffe generated make mktest make mktest.sh done mktest.sh meta mktest %.sh>% mktest.sh mktest prev mktest.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : mktest contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n mktest.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp mktest.sh mktest exec - ;; exec - *) { exec - i=`(read x; echo $x) < mktest.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat mktest.sh exec - } > mktest exec - ;; exec - esac exec - ;; exec - *) cat - mktest.sh > mktest <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w mktest -a -x mktest || chmod u+w,+x mktest done mktest generated make package make package.sh done package.sh meta package %.sh>% package.sh package prev package.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : package contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n package.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp package.sh package exec - ;; exec - *) { exec - i=`(read x; echo $x) < package.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat package.sh exec - } > package exec - ;; exec - esac exec - ;; exec - *) cat - package.sh > package <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w package -a -x package || chmod u+w,+x package done package generated make regress make regress.sh done regress.sh meta regress %.sh>% regress.sh regress prev regress.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : regress contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n regress.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp regress.sh regress exec - ;; exec - *) { exec - i=`(read x; echo $x) < regress.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat regress.sh exec - } > regress exec - ;; exec - esac exec - ;; exec - *) cat - regress.sh > regress <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w regress -a -x regress || chmod u+w,+x regress done regress generated make rt make rt.sh done rt.sh meta rt %.sh>% rt.sh rt prev rt.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : rt contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n rt.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp rt.sh rt exec - ;; exec - *) { exec - i=`(read x; echo $x) < rt.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat rt.sh exec - } > rt exec - ;; exec - esac exec - ;; exec - *) cat - rt.sh > rt <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w rt -a -x rt || chmod u+w,+x rt done rt generated make crossexec make crossexec.sh done crossexec.sh meta crossexec %.sh>% crossexec.sh crossexec prev crossexec.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : crossexec contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n crossexec.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp crossexec.sh crossexec exec - ;; exec - *) { exec - i=`(read x; echo $x) < crossexec.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat crossexec.sh exec - } > crossexec exec - ;; exec - esac exec - ;; exec - *) cat - crossexec.sh > crossexec <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w crossexec -a -x crossexec || chmod u+w,+x crossexec done crossexec generated make execrate make execrate.sh done execrate.sh meta execrate %.sh>% execrate.sh execrate prev execrate.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : execrate contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n execrate.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp execrate.sh execrate exec - ;; exec - *) { exec - i=`(read x; echo $x) < execrate.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat execrate.sh exec - } > execrate exec - ;; exec - esac exec - ;; exec - *) cat - execrate.sh > execrate <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w execrate -a -x execrate || chmod u+w,+x execrate done execrate generated make filter make filter.sh done filter.sh meta filter %.sh>% filter.sh filter prev filter.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : filter contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n filter.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 184 in exec - 0) cp filter.sh filter exec - ;; exec - *) { exec - i=`(read x; echo $x) < filter.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat filter.sh exec - } > filter exec - ;; exec - esac exec - ;; exec - *) cat - filter.sh > filter <<'!' exec - ${mam_cc_SHELLMAGIC} exec - ! exec - ;; exec - esac exec - test -w filter -a -x filter || chmod u+w,+x filter done filter generated make ignore make ignore.sh done ignore.sh meta ignore %.sh>% ignore.sh ignore prev ignore.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : ignore contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n ignore.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 0 in exec - 0) cp ignore.sh ignore exec - ;; exec - *) { exec - i=`(read x; echo $x) < ignore.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat - ignore.sh <<'!' exec - exec - ! exec - } > ignore exec - ;; exec - esac exec - ;; exec - *) cat - ignore.sh > ignore <<'!' exec - ${mam_cc_SHELLMAGIC} exec - exec - ! exec - ;; exec - esac exec - test -w ignore -a -x ignore || chmod u+w,+x ignore done ignore generated make silent make silent.sh done silent.sh meta silent %.sh>% silent.sh silent prev silent.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : silent contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n silent.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 0 in exec - 0) cp silent.sh silent exec - ;; exec - *) { exec - i=`(read x; echo $x) < silent.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat - silent.sh <<'!' exec - exec - ! exec - } > silent exec - ;; exec - esac exec - ;; exec - *) cat - silent.sh > silent <<'!' exec - ${mam_cc_SHELLMAGIC} exec - exec - ! exec - ;; exec - esac exec - test -w silent -a -x silent || chmod u+w,+x silent done silent generated make mamake make mamake.o make mamake.c make shlib-compat.h implicit done shlib-compat.h dontcare virtual make ast.h implicit done ast.h dontcare virtual done mamake.c meta mamake.o %.c>%.o mamake.c mamake prev mamake.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} -c mamake.c done mamake.o generated exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} ${LDFLAGS} -o mamake mamake.o done mamake generated make proto make proto.o make proto.c done proto.c meta proto.o %.c>%.o proto.c proto prev proto.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} -c proto.c done proto.o generated exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} ${LDFLAGS} -o proto proto.o done proto generated make ratz make ratz.o make ratz.c make unix.h implicit done unix.h dontcare virtual make alloc.h implicit done alloc.h dontcare virtual make unixio.h implicit done unixio.h dontcare virtual make ast_std.h implicit done ast_std.h dontcare virtual make windows.h implicit done windows.h dontcare virtual make io.h implicit done io.h dontcare virtual make direct.h implicit done direct.h dontcare virtual prev ast.h implicit done ratz.c meta ratz.o %.c>%.o ratz.c ratz prev ratz.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} -c ratz.c done ratz.o generated exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} ${LDFLAGS} -o ratz ratz.o done ratz generated make mprobe make mprobe.sh done mprobe.sh meta mprobe %.sh>% mprobe.sh mprobe prev mprobe.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : mprobe contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n mprobe.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 0 in exec - 0) cp mprobe.sh mprobe exec - ;; exec - *) { exec - i=`(read x; echo $x) < mprobe.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat - mprobe.sh <<'!' exec - exec - ! exec - } > mprobe exec - ;; exec - esac exec - ;; exec - *) cat - mprobe.sh > mprobe <<'!' exec - ${mam_cc_SHELLMAGIC} exec - exec - ! exec - ;; exec - esac exec - test -w mprobe -a -x mprobe || chmod u+w,+x mprobe done mprobe generated make probe make probe.sh make C+probe done C+probe make make.probe done make.probe exec - cat C+probe make.probe > probe.sh done probe.sh generated meta probe %.sh>% probe.sh probe prev probe.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : probe contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n probe.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 0 in exec - 0) cp probe.sh probe exec - ;; exec - *) { exec - i=`(read x; echo $x) < probe.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat - probe.sh <<'!' exec - exec - ! exec - } > probe exec - ;; exec - esac exec - ;; exec - *) cat - probe.sh > probe <<'!' exec - ${mam_cc_SHELLMAGIC} exec - exec - ! exec - ;; exec - esac exec - test -w probe -a -x probe || chmod u+w,+x probe done probe generated make ${INSTALLROOT}/bin exec - if test ! -d ${INSTALLROOT}/bin exec - then mkdir -p ${INSTALLROOT}/bin exec - fi done ${INSTALLROOT}/bin generated make ${INSTALLROOT}/bin/iffe prev iffe exec - test '' = 'iffe' || ${STDCMP} 2>/dev/null -s iffe ${INSTALLROOT}/bin/iffe || { ${STDMV} ${INSTALLROOT}/bin/iffe ${INSTALLROOT}/bin/iffe.old 2>/dev/null || true; ${STDCP} iffe ${INSTALLROOT}/bin/iffe ;} done ${INSTALLROOT}/bin/iffe generated make ${INSTALLROOT}/bin/mktest prev mktest exec - test '' = 'mktest' || ${STDCMP} 2>/dev/null -s mktest ${INSTALLROOT}/bin/mktest || { ${STDMV} ${INSTALLROOT}/bin/mktest ${INSTALLROOT}/bin/mktest.old 2>/dev/null || true; ${STDCP} mktest ${INSTALLROOT}/bin/mktest ;} done ${INSTALLROOT}/bin/mktest generated make ${INSTALLROOT}/bin/package prev package exec - test '' = 'package' || ${STDCMP} 2>/dev/null -s package ${INSTALLROOT}/bin/package || { ${STDMV} ${INSTALLROOT}/bin/package ${INSTALLROOT}/bin/package.old 2>/dev/null || true; ${STDCP} package ${INSTALLROOT}/bin/package ;} done ${INSTALLROOT}/bin/package generated make ${INSTALLROOT}/bin/regress prev regress exec - test '' = 'regress' || ${STDCMP} 2>/dev/null -s regress ${INSTALLROOT}/bin/regress || { ${STDMV} ${INSTALLROOT}/bin/regress ${INSTALLROOT}/bin/regress.old 2>/dev/null || true; ${STDCP} regress ${INSTALLROOT}/bin/regress ;} done ${INSTALLROOT}/bin/regress generated make ${INSTALLROOT}/bin/rt prev rt exec - test '' = 'rt' || ${STDCMP} 2>/dev/null -s rt ${INSTALLROOT}/bin/rt || { ${STDMV} ${INSTALLROOT}/bin/rt ${INSTALLROOT}/bin/rt.old 2>/dev/null || true; ${STDCP} rt ${INSTALLROOT}/bin/rt ;} done ${INSTALLROOT}/bin/rt generated make ${PACKAGEROOT}/bin exec - if test ! -d ${PACKAGEROOT}/bin exec - then mkdir -p ${PACKAGEROOT}/bin exec - fi done ${PACKAGEROOT}/bin generated make ${PACKAGEROOT}/bin/execrate prev ${PACKAGEROOT}/bin prev execrate exec - test '' = 'execrate' || ${STDCMP} 2>/dev/null -s execrate ${PACKAGEROOT}/bin/execrate || { ${STDMV} ${PACKAGEROOT}/bin/execrate ${PACKAGEROOT}/bin/execrate.old 2>/dev/null || true; ${STDCP} execrate ${PACKAGEROOT}/bin/execrate ;} done ${PACKAGEROOT}/bin/execrate generated make ${PACKAGEROOT}/bin/ignore prev ignore exec - test '' = 'ignore' || ${STDCMP} 2>/dev/null -s ignore ${PACKAGEROOT}/bin/ignore || { ${STDMV} ${PACKAGEROOT}/bin/ignore ${PACKAGEROOT}/bin/ignore.old 2>/dev/null || true; ${STDCP} ignore ${PACKAGEROOT}/bin/ignore ;} done ${PACKAGEROOT}/bin/ignore generated make ${PACKAGEROOT}/bin/mamprobe make mamprobe meta mamprobe %.sh>% mamprobe.sh mamprobe make mamprobe.sh done mamprobe.sh exec - case static,port:$OPTIND:$RANDOM in exec - ?*:*:*|*::*|*:*:$RANDOM) exec - ;; exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null exec - then if grep '### .*archaic.* ###' >/dev/null exec - then : mamprobe contains archaic constructs : exec - else ENV= LC_ALL=C $SHELL -n mamprobe.sh exec - fi exec - fi exec - ;; exec - esac exec - case '${mam_cc_SHELLMAGIC}' in exec - "") case 0 in exec - 0) cp mamprobe.sh mamprobe exec - ;; exec - *) { exec - i=`(read x; echo $x) < mamprobe.sh` exec - case $i in exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;; exec - esac exec - cat - mamprobe.sh <<'!' exec - exec - ! exec - } > mamprobe exec - ;; exec - esac exec - ;; exec - *) cat - mamprobe.sh > mamprobe <<'!' exec - ${mam_cc_SHELLMAGIC} exec - exec - ! exec - ;; exec - esac exec - test -w mamprobe -a -x mamprobe || chmod u+w,+x mamprobe done mamprobe generated exec - test '' = 'mamprobe' || ${STDCMP} 2>/dev/null -s mamprobe ${PACKAGEROOT}/bin/mamprobe || { ${STDMV} ${PACKAGEROOT}/bin/mamprobe ${PACKAGEROOT}/bin/mamprobe.old 2>/dev/null || true; ${STDCP} mamprobe ${PACKAGEROOT}/bin/mamprobe ;} done ${PACKAGEROOT}/bin/mamprobe generated make ${PACKAGEROOT}/bin/package prev package exec - test '' = 'package' || ${STDCMP} 2>/dev/null -s package ${PACKAGEROOT}/bin/package || { ${STDMV} ${PACKAGEROOT}/bin/package ${PACKAGEROOT}/bin/package.old 2>/dev/null || true; ${STDCP} package ${PACKAGEROOT}/bin/package ;} done ${PACKAGEROOT}/bin/package generated make ${PACKAGEROOT}/bin/silent prev silent exec - test '' = 'silent' || ${STDCMP} 2>/dev/null -s silent ${PACKAGEROOT}/bin/silent || { ${STDMV} ${PACKAGEROOT}/bin/silent ${PACKAGEROOT}/bin/silent.old 2>/dev/null || true; ${STDCP} silent ${PACKAGEROOT}/bin/silent ;} done ${PACKAGEROOT}/bin/silent generated make ${INSTALLROOT}/bin/crossexec prev crossexec exec - test '' = 'crossexec' || ${STDCMP} 2>/dev/null -s crossexec ${INSTALLROOT}/bin/crossexec || { ${STDMV} ${INSTALLROOT}/bin/crossexec ${INSTALLROOT}/bin/crossexec.old 2>/dev/null || true; ${STDCP} crossexec ${INSTALLROOT}/bin/crossexec ;} done ${INSTALLROOT}/bin/crossexec generated make ${INSTALLROOT}/bin/filter prev filter exec - test '' = 'filter' || ${STDCMP} 2>/dev/null -s filter ${INSTALLROOT}/bin/filter || { ${STDMV} ${INSTALLROOT}/bin/filter ${INSTALLROOT}/bin/filter.old 2>/dev/null || true; ${STDCP} filter ${INSTALLROOT}/bin/filter ;} done ${INSTALLROOT}/bin/filter generated make ${PACKAGEROOT}/lib/package exec - if test ! -d ${PACKAGEROOT}/lib/package exec - then mkdir -p ${PACKAGEROOT}/lib/package exec - fi done ${PACKAGEROOT}/lib/package generated make ${INSTALLROOT}/bin/mamake prev mamake exec - test '' = 'mamake' || ${STDCMP} 2>/dev/null -s mamake ${INSTALLROOT}/bin/mamake || { ${STDMV} ${INSTALLROOT}/bin/mamake ${INSTALLROOT}/bin/mamake.old 2>/dev/null || true; ${STDCP} mamake ${INSTALLROOT}/bin/mamake ;} done ${INSTALLROOT}/bin/mamake generated make ${INSTALLROOT}/bin/proto prev proto exec - test '' = 'proto' || ${STDCMP} 2>/dev/null -s proto ${INSTALLROOT}/bin/proto || { ${STDMV} ${INSTALLROOT}/bin/proto ${INSTALLROOT}/bin/proto.old 2>/dev/null || true; ${STDCP} proto ${INSTALLROOT}/bin/proto ;} done ${INSTALLROOT}/bin/proto generated make ${INSTALLROOT}/bin/ratz prev ratz exec - test '' = 'ratz' || ${STDCMP} 2>/dev/null -s ratz ${INSTALLROOT}/bin/ratz || { ${STDMV} ${INSTALLROOT}/bin/ratz ${INSTALLROOT}/bin/ratz.old 2>/dev/null || true; ${STDCP} ratz ${INSTALLROOT}/bin/ratz ;} done ${INSTALLROOT}/bin/ratz generated make ${INSTALLROOT}/bin/mkdir make mkdir.sh done mkdir.sh exec - if test ! -x ${INSTALLROOT}/bin/mkdir -a -x /bin/mkdir exec - then mkdir -p 2>/dev/null || : exec - if test -d ./-p exec - then rmdir ./-p exec - cp mkdir.sh ${INSTALLROOT}/bin/mkdir exec - chmod +x ${INSTALLROOT}/bin/mkdir exec - fi exec - fi done ${INSTALLROOT}/bin/mkdir generated make ${INSTALLROOT}/bin/.paths exec - if test ! -f ${INSTALLROOT}/bin/.paths -o -w ${INSTALLROOT}/bin/.paths exec - then N=' exec - ' exec - H=${mam_cc_HOSTTYPE} exec - P="" exec - b= f= h= l= n= p= u= B= L= exec - set : $P exec - while : exec - do while : exec - do case $1 in exec - '') break 2 ;; exec - :) shift; break ;; exec - esac exec - shift exec - done exec - case $# in exec - 0|1) break ;; exec - esac exec - case $L in exec - ?*) L="$L|" ;; exec - esac exec - L="$L$2=*" exec - B=$1 exec - done exec - if test -f ${INSTALLROOT}/bin/.paths exec - then while read x exec - do case $x in exec - *\$\(\"*) break exec - ;; exec - '#'?*) case $h in exec - '') h=$x ;; exec - esac exec - ;; exec - $L) l=$x exec - ;; exec - *BUILTIN_LIB=*) b=$x exec - ;; exec - *FPATH=*) f=$x exec - ;; exec - *PLUGIN_LIB=*) p=$x exec - ;; exec - *) case $u in exec - ?*) u=$u$N ;; exec - esac exec - u=$u$x exec - ;; exec - esac exec - done < ${INSTALLROOT}/bin/.paths exec - fi exec - ifs=$IFS exec - m= exec - case $p in exec - ?*) b= exec - ;; exec - esac exec - case $b in exec - ?*) IFS='=' exec - set $b exec - IFS=$ifs exec - shift exec - p="PLUGIN_LIB=$*" exec - case $b in exec - [Nn][Oo]*) p=no$p ;; exec - esac exec - m=1 exec - ;; exec - esac exec - case $f in exec - '') f="FPATH=../fun" exec - m=1 exec - ;; exec - esac exec - case $h in exec - '') h='# use { no NO } prefix to permanently disable #' ;; exec - esac exec - case $l in exec - '') set x x : $P exec - l= exec - while : exec - do while : exec - do case $# in exec - 0) break ;; exec - esac exec - x=$1 exec - shift exec - case $x in exec - :) break ;; exec - esac exec - done exec - case $# in exec - 0|1) break exec - ;; exec - 2) l=$2 exec - ;; exec - *) case "$H" in exec - $3) l=$2; break ;; exec - esac exec - ;; exec - esac exec - done exec - case $l in exec - '') if test -x /lib/dld.sl exec - then l=SHLIB_PATH exec - elif test -x /usr/lib/dyld exec - then l=DYLD_LIBRARY_PATH exec - else case "$H" in exec - ibm.*|mvs.*) exec - l=LIBPATH exec - ;; exec - sgi.mips3) exec - l=LD_LIBRARYN32_PATH exec - ;; exec - sgi.mips4) exec - l=LD_LIBRARYN64_PATH exec - ;; exec - *) l=LD_LIBRARY_PATH exec - ;; exec - esac exec - fi exec - ;; exec - esac exec - case $l in exec - ?*) case $B in exec - '') B=lib ;; exec - esac exec - l="$l=../$B" exec - m=1 exec - ;; exec - esac exec - ;; exec - esac exec - case $p in exec - '') p="PLUGIN_LIB=cmd" exec - case '' in exec - '') p=no$p ;; exec - esac exec - m=1 exec - ;; exec - esac exec - case $m in exec - 1) case $u in exec - ?*) u=$N$u ;; exec - esac exec - echo "$h$N$p$N$f$N$l$u" > ${INSTALLROOT}/bin/.paths exec - ;; exec - esac exec - fi done ${INSTALLROOT}/bin/.paths generated make ${INSTALLROOT}/lib/probe/C exec - if test ! -d ${INSTALLROOT}/lib/probe/C exec - then mkdir -p ${INSTALLROOT}/lib/probe/C exec - fi done ${INSTALLROOT}/lib/probe/C generated make ${INSTALLROOT}/lib/probe/C/probe prev ${INSTALLROOT}/lib/probe/C prev C+probe exec - test '' = 'C+probe' || ${STDCMP} 2>/dev/null -s C+probe ${INSTALLROOT}/lib/probe/C/probe || { ${STDMV} ${INSTALLROOT}/lib/probe/C/probe ${INSTALLROOT}/lib/probe/C/probe.old 2>/dev/null || true; ${STDCP} C+probe ${INSTALLROOT}/lib/probe/C/probe ;} done ${INSTALLROOT}/lib/probe/C/probe generated make ${INSTALLROOT}/lib/probe/C/make exec - if test ! -d ${INSTALLROOT}/lib/probe/C/make exec - then mkdir -p ${INSTALLROOT}/lib/probe/C/make exec - fi done ${INSTALLROOT}/lib/probe/C/make generated prev ${INSTALLROOT}/lib/probe/C/make make ${INSTALLROOT}/lib/probe/C/pp exec - if test ! -d ${INSTALLROOT}/lib/probe/C/pp exec - then mkdir -p ${INSTALLROOT}/lib/probe/C/pp exec - fi done ${INSTALLROOT}/lib/probe/C/pp generated prev ${INSTALLROOT}/lib/probe/C/pp make ${INSTALLROOT}/lib/probe/C/mam exec - if test ! -d ${INSTALLROOT}/lib/probe/C/mam exec - then mkdir -p ${INSTALLROOT}/lib/probe/C/mam exec - fi done ${INSTALLROOT}/lib/probe/C/mam generated make ${INSTALLROOT}/lib/probe/C/mam/probe prev ${INSTALLROOT}/lib/probe/C/mam prev mprobe exec - test '' = 'mprobe' || ${STDCMP} 2>/dev/null -s mprobe ${INSTALLROOT}/lib/probe/C/mam/probe || { ${STDMV} ${INSTALLROOT}/lib/probe/C/mam/probe ${INSTALLROOT}/lib/probe/C/mam/probe.old 2>/dev/null || true; ${STDCP} mprobe ${INSTALLROOT}/lib/probe/C/mam/probe ;} done ${INSTALLROOT}/lib/probe/C/mam/probe generated make ${INSTALLROOT}/lib/probe/C/mam/mprobe prev mprobe exec - test '' = 'mprobe' || ${STDCMP} 2>/dev/null -s mprobe ${INSTALLROOT}/lib/probe/C/mam/mprobe || { ${STDMV} ${INSTALLROOT}/lib/probe/C/mam/mprobe ${INSTALLROOT}/lib/probe/C/mam/mprobe.old 2>/dev/null || true; ${STDCP} mprobe ${INSTALLROOT}/lib/probe/C/mam/mprobe ;} done ${INSTALLROOT}/lib/probe/C/mam/mprobe generated make ${INSTALLROOT}/lib/probe/C/make/probe prev probe exec - test '' = 'probe' || ${STDCMP} 2>/dev/null -s probe ${INSTALLROOT}/lib/probe/C/make/probe || { ${STDMV} ${INSTALLROOT}/lib/probe/C/make/probe ${INSTALLROOT}/lib/probe/C/make/probe.old 2>/dev/null || true; ${STDCP} probe ${INSTALLROOT}/lib/probe/C/make/probe ;} done ${INSTALLROOT}/lib/probe/C/make/probe generated make ${INSTALLROOT}/lib/probe/C/make/probe.ini make probe.ini make probe.win32 done probe.win32 exec - t=${mam_cc_HOSTTYPE} exec - ifs=$IFS exec - IFS=. exec - set x $t exec - IFS=$ifs exec - t=$2 exec - set x probe.win32 exec - while : exec - do shift exec - case $# in exec - 0) break ;; exec - esac exec - case $1 in exec - *probe.$t) exec - break exec - esac exec - done exec - case $1 in exec - ?*) cmp -s $1 probe.ini || cp $1 probe.ini ;; exec - *) : > probe.ini exec - esac done probe.ini generated exec - test '' = 'probe.ini' || ${STDCMP} 2>/dev/null -s probe.ini ${INSTALLROOT}/lib/probe/C/make/probe.ini || { ${STDMV} ${INSTALLROOT}/lib/probe/C/make/probe.ini ${INSTALLROOT}/lib/probe/C/make/probe.ini.old 2>/dev/null || true; ${STDCP} probe.ini ${INSTALLROOT}/lib/probe/C/make/probe.ini ;} done ${INSTALLROOT}/lib/probe/C/make/probe.ini generated make ${INSTALLROOT}/include/ast exec - if test ! -d ${INSTALLROOT}/include/ast exec - then mkdir -p ${INSTALLROOT}/include/ast exec - fi done ${INSTALLROOT}/include/ast generated make ${INSTALLROOT}/include/ast/prototyped.h prev ${INSTALLROOT}/include/ast make prototyped.h prev ${INSTALLROOT}/bin/proto exec - proto -f /dev/null > h.${COTEMP}.h exec - if cmp 2>/dev/null -s h.${COTEMP}.h prototyped.h exec - then rm -f h.${COTEMP}.h exec - else mv h.${COTEMP}.h prototyped.h exec - fi done prototyped.h generated exec - test '' = 'prototyped.h' || ${STDCMP} 2>/dev/null -s prototyped.h ${INSTALLROOT}/include/ast/prototyped.h || { ${STDMV} ${INSTALLROOT}/include/ast/prototyped.h ${INSTALLROOT}/include/ast/prototyped.h.old 2>/dev/null || true; ${STDCP} prototyped.h ${INSTALLROOT}/include/ast/prototyped.h ;} done ${INSTALLROOT}/include/ast/prototyped.h generated make ${INSTALLROOT}/lib/lib exec - if test ! -d ${INSTALLROOT}/lib/lib exec - then mkdir -p ${INSTALLROOT}/lib/lib exec - fi done ${INSTALLROOT}/lib/lib generated make ${INSTALLROOT}/lib/lib/dl prev ${INSTALLROOT}/lib/lib make dl.req make dl.c done dl.c exec - set - exec - r='-' exec - for i in dl.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in dl - exec - do case $p in exec - -) if ${CC} -o dl.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o dl.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > dl.req exec - rm -f dl.exe dl done dl.req generated exec - test '' = 'dl.req' || ${STDCMP} 2>/dev/null -s dl.req ${INSTALLROOT}/lib/lib/dl || { ${STDMV} ${INSTALLROOT}/lib/lib/dl ${INSTALLROOT}/lib/lib/dl.old 2>/dev/null || true; ${STDCP} dl.req ${INSTALLROOT}/lib/lib/dl ;} done ${INSTALLROOT}/lib/lib/dl generated make ${INSTALLROOT}/lib/lib/iconv make iconv.req make iconv.c done iconv.c exec - set - exec - r='-' exec - for i in iconv.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in iconv - exec - do case $p in exec - -) if ${CC} -o iconv.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o iconv.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > iconv.req exec - rm -f iconv.exe iconv done iconv.req generated exec - test '' = 'iconv.req' || ${STDCMP} 2>/dev/null -s iconv.req ${INSTALLROOT}/lib/lib/iconv || { ${STDMV} ${INSTALLROOT}/lib/lib/iconv ${INSTALLROOT}/lib/lib/iconv.old 2>/dev/null || true; ${STDCP} iconv.req ${INSTALLROOT}/lib/lib/iconv ;} done ${INSTALLROOT}/lib/lib/iconv generated make ${INSTALLROOT}/lib/lib/w make w.req make w.c done w.c make w2.c done w2.c exec - set - exec - r='-' exec - for i in w.c w2.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in w - exec - do case $p in exec - -) if ${CC} -o w.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o w.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > w.req exec - rm -f w.exe w w2 done w.req generated exec - test '' = 'w.req' || ${STDCMP} 2>/dev/null -s w.req ${INSTALLROOT}/lib/lib/w || { ${STDMV} ${INSTALLROOT}/lib/lib/w ${INSTALLROOT}/lib/lib/w.old 2>/dev/null || true; ${STDCP} w.req ${INSTALLROOT}/lib/lib/w ;} done ${INSTALLROOT}/lib/lib/w generated make ${INSTALLROOT}/lib/lib/intl make intl.req make intl.c done intl.c exec - set - exec - r='-' exec - for i in intl.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in intl - exec - do case $p in exec - -) if ${CC} -o intl.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o intl.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > intl.req exec - rm -f intl.exe intl done intl.req generated exec - test '' = 'intl.req' || ${STDCMP} 2>/dev/null -s intl.req ${INSTALLROOT}/lib/lib/intl || { ${STDMV} ${INSTALLROOT}/lib/lib/intl ${INSTALLROOT}/lib/lib/intl.old 2>/dev/null || true; ${STDCP} intl.req ${INSTALLROOT}/lib/lib/intl ;} done ${INSTALLROOT}/lib/lib/intl generated make ${INSTALLROOT}/lib/lib/m make m.req make m.c done m.c make m2.c done m2.c make m3.c done m3.c make m4.c done m4.c make m5.c done m5.c make m6.c done m6.c exec - set - exec - r='-' exec - for i in m.c m2.c m3.c m4.c m5.c m6.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in m - exec - do case $p in exec - -) if ${CC} -o m.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o m.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > m.req exec - rm -f m.exe m m2 m3 m4 m5 m6 done m.req generated exec - test '' = 'm.req' || ${STDCMP} 2>/dev/null -s m.req ${INSTALLROOT}/lib/lib/m || { ${STDMV} ${INSTALLROOT}/lib/lib/m ${INSTALLROOT}/lib/lib/m.old 2>/dev/null || true; ${STDCP} m.req ${INSTALLROOT}/lib/lib/m ;} done ${INSTALLROOT}/lib/lib/m generated make ${INSTALLROOT}/lib/lib/nsl make nsl.req make nsl.c done nsl.c exec - set - exec - r='-' exec - for i in nsl.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in nsl - exec - do case $p in exec - -) if ${CC} -o nsl.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o nsl.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > nsl.req exec - rm -f nsl.exe nsl done nsl.req generated exec - test '' = 'nsl.req' || ${STDCMP} 2>/dev/null -s nsl.req ${INSTALLROOT}/lib/lib/nsl || { ${STDMV} ${INSTALLROOT}/lib/lib/nsl ${INSTALLROOT}/lib/lib/nsl.old 2>/dev/null || true; ${STDCP} nsl.req ${INSTALLROOT}/lib/lib/nsl ;} done ${INSTALLROOT}/lib/lib/nsl generated make ${INSTALLROOT}/lib/lib/socket make socket.req make socket.c done socket.c prev nsl.c exec - set - exec - r='-' exec - for i in socket.c nsl.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in socket - exec - do case $p in exec - -) if ${CC} -o socket.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o socket.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > socket.req exec - rm -f socket.exe socket nsl done socket.req generated exec - test '' = 'socket.req' || ${STDCMP} 2>/dev/null -s socket.req ${INSTALLROOT}/lib/lib/socket || { ${STDMV} ${INSTALLROOT}/lib/lib/socket ${INSTALLROOT}/lib/lib/socket.old 2>/dev/null || true; ${STDCP} socket.req ${INSTALLROOT}/lib/lib/socket ;} done ${INSTALLROOT}/lib/lib/socket generated make ${INSTALLROOT}/lib/lib/dbm make dbm.req make db.c done db.c make gdbm.c done gdbm.c make gdbm1.c make gdbm-ndbm.h implicit done gdbm-ndbm.h dontcare virtual done gdbm1.c make gdbm2.c make ndbm.h implicit done ndbm.h dontcare virtual done gdbm2.c exec - set - exec - r='-' exec - for i in db.c gdbm.c gdbm1.c gdbm2.c exec - do if ${CC} -c $i > /dev/null exec - then g= exec - for p in db - gdbm_compat - gdbm - ndbm - dbm - exec - do case $p in exec - -) if ${CC} -o dbm.exe $i $g > /dev/null 2>&1 exec - then ${CC} -o dbm.exe $i > /dev/null 2>&1 || { exec - r="$g" exec - break 2 exec - } exec - fi exec - g= exec - ;; exec - *) g="$g -l$p" exec - ;; exec - esac exec - done exec - fi exec - done 2>/dev/null exec - echo " $r" > dbm.req exec - rm -f dbm.exe db gdbm gdbm1 gdbm2 done dbm.req generated exec - test '' = 'dbm.req' || ${STDCMP} 2>/dev/null -s dbm.req ${INSTALLROOT}/lib/lib/dbm || { ${STDMV} ${INSTALLROOT}/lib/lib/dbm ${INSTALLROOT}/lib/lib/dbm.old 2>/dev/null || true; ${STDCP} dbm.req ${INSTALLROOT}/lib/lib/dbm ;} done ${INSTALLROOT}/lib/lib/dbm generated done install virtual make test make test.iffe prev iffe make iffe.tst done iffe.tst exec - regress iffe.tst iffe done test.iffe virtual make test.mamake prev mamake make mamake.tst meta mamake.tst %.rt>%.tst mamake.rt mamake make mamake.rt done mamake.rt exec - if [[ "1" || "mamake.rt" -nt "mamake.tst" ]] exec - then mktest --style=regress mamake.rt > mamake.tst exec - fi done mamake.tst generated exec - regress mamake.tst mamake done test.mamake virtual done test dontcare virtual ksh-1.0.0-beta.2/src/cmd/INIT/RELEASE000066400000000000000000001451711415700074400164610ustar00rootroot0000000000000012-07-17 iffe.sh: add C code NOTE("...") to amend --verbose output 12-06-26 iffe.sh: fix "npt foo" to handle function-like macro foo() 12-06-20 package.sh: use $KSH for rt in "results test" 12-06-15 Makefile: add PLUGIN_LIB to $INSTALLROOT/bin/.paths and BUILTIN_LIB => PLUGIN_LIB 12-06-15 package.sh: add PLUGIN_LIB to $INSTALLROOT/bin/.paths and BUILTIN_LIB => PLUGIN_LIB 12-06-13 package.sh: handle admin.db column output 12-06-08 iffe.sh: fix 12-06-06 typo 12-06-06 iffe.sh: check for -l* in reverse and accumulative order (e.g., for -last & -lm) 12-06-04 package.sh: always check $INSTALLROOT/lib/package/profile 12-05-31 Makefile: ID=ast; $(INSTALLROOT)/prototyped.h => $(INSTALLROOT)/$(ID)/prototyped.h 12-05-28 iffe.sh: API foo YYYYMMDD => FOOAPI(rel) test macro 12-05-24 package.sh: change admin.db comment => owner attributes 12-04-25 ratz.c: add sear -k option to keep installation tmp dir on exit 12-04-17 package.sh: skip sh version logic for ``use'' 12-04-17 cc.ibm.risc*: _LARGEFILE64_SOURCE => _LARGE_FILE_API moved to libast/features 12-04-09 cc.ibm.risc*: speak aixese for _LARGEFILE64_SOURCE 12-02-29 cc.darwin.i386*: handle default cc vs kernel bittedness 12-02-29 C+probe: add __TIMESTAMP__ to the nopredefined list 12-02-29 package.sh: don't assume grep -q or /usr/local/lib in LD_LIBRARY_PATH 12-02-29 package.sh: fix ksh vs -lcmd compatibility checks 12-02-23 iffe.sh: checkcc() before checkread() for sensible diagnostics 12-02-14 package.mk: { --clobber --compare --link=lib*.a* } for --mam=static 12-02-14 package.mk: export LICENSEFILEDEFAULT instead of LICENSEFILE 12-02-14 package.sh: handle @(cc|ld).${HOSTTYPE}* intercepts 12-02-07 package.sh: add { clean clobber } actions 12-02-02 regress.sh: fix ulimit -c defaults for --nokeep 12-01-18 regress.sh: add INPUT|OUTPUT|ERROR -e 'filter' to filter before comparison 12-01-21 package.sh: fix `admin make' bug that created unused $INSTALLROOT/lib 12-01-21 Makefile: :PACKAGE: license=ast -- oops 12-01-20 cc.darwin,cc.mvs.390: tmp=/tmp/cc.${USER:-$LOGNAME}.$$.err 12-01-12 package.sh: add admin make share closure to handle alternate HOSTTYPEs 11-12-13 iffe.sh: add /**/ test code comment to disable default #include 11-11-11 C+probe: test for .so before .sl 11-10-26 package.sh: don't forget about *.pkg for admin update 11-10-18 cc.*-icc: update and add more 11-10-11 package.sh: handle package make|view when no source installed 11-09-11 package.sh: count admin '*** termination code' errors 11-08-31 mamake.c: add -e, ignore use recursive prereq timestamps 11-08-29 iffe.sh: add ``set stdio try1.h - try2.h ...'' 11-08-29 iffe.sh: trap EXIT => trap 0 for ancient sh 11-08-11 iffe.sh: handle ancient sort that doesn't have -k 11-06-01 make.probe: add more /lib64 logic 11-05-01 package.sh: fix admin ditto to sync LICENSES too 11-03-25 package.sh: initialize { $SED $TR } before first use! 11-03-21 package.sh: fix vpath probes 11-03-17 iffe.sh: fix cleanup to rm $tmp* instead of $tmp*.* 11-02-24 package.sh: change curl usage to "curl -L ..." 11-02-11 package.sh,C+probe,make.probe,mamprobe.sh: add ###.*archaic.*### 11-02-02 Makefile: add :MAPLIB: check for ancient -lw 11-02-02 make.probe: handle -print-multi-directory => 64 => /usr/lib64 /lib64 11-02-02 package.sh: HOSTTYPE=*,*cc*[,-*,...] sets CC [ and CCFLAGS ] 11-02-02 make.probe: handle gcc $ORIGIN link but exec failure -- gee thanks 11-01-25 cc.hp.ia64: bundled cc is a pile of shaving cream 11-01-07 iffe.sh: check debug==3 for is_hdr() failure 10-11-22 ditto.sh: fix timing problem between |& and exec &p 10-11-10 package.sh: fix cc cross compile check to use checkcc absolute path 10-10-10 package.sh: list main env vars at start of make action 10-10-10 ratz.c: tweak windows delays 10-09-10 ratz.c: add _SEAR_ARGS for _SEAR_EXEC 10-09-01 package.sh: fix ratz from source logic 10-08-25 package.mk: consolidate license file search in .package.licenses. 10-08-22 ratz.c: run sear bootstrap command detached 10-08-20 C+probe: version_stamp only if version_flags works 10-08-17 package.sh: unset makerules *DIR variables in env 10-08-15 package.sh: "make" action now lists some env values 10-08-11 mktest.sh: add "DO command ..." 10-07-27 rt.sh: handle "rt X=Y ..." 10-06-29 ratz.c: non-option sear args passed to sear_exec() 10-06-25 iffe.sh: "api" op changed to not do "map-libc" type mappings 10-06-25 package.sh: "force admin ditto" => no ditto --update option 10-06-22 C+probe: handle cc that require .[ci] input for version info 10-06-21 ditto.sh: change default remote access to ssh (about time) 10-06-12 regress.sh: DIAGNOSTICS [ 1 | 0 | pattern ] and fix EXIT for all 10-06-09 package.sh: add AT&T to usable nmake check 10-06-06 iffe.sh,iffe.tst: add { api ver } ops 10-04-22 package.sh: update "html binary|source" NAME/PASSWORD info 10-04-15 iffe.sh: don't forget candidate headers for hdr|sys! 10-04-11 WWW.mk: disable man page metarule -- now done by admin-man(1) 10-02-14 package.sh: $CC verification needs $INSTALLROOT/bin in PATH 10-02-11 package.sh: fix package admin make report error count 10-02-02 package.sh: fix write binary bug that did scp on local fs 10-02-02 package.mk: up to date binary targets must still be in PACKAGE.*.lst 10-01-01 package.sh: fix premature $INSTALLROOT/bin during cross compile check 10-01-01 make.probe: handle ['"] in CC.VERSION.STRING 09-12-04 iffe.sh: add "opt name" to check for name in $PACKAGE_OPTIONS 09-11-30 mktest.sh: change RESET to STATE.RESET to make it global 09-11-14 make.probe: use gcc { -print-multi-directory -print-search-dirs } 09-11-11 package.sh: re-order and combine cc checks 09-10-27 C+probe,make.probe,probe.win32: add CC.SUFFIX.DEBUG 09-10-21 iffe.sh,Makefile: test -e is not in ksh88! 09-10-06 iffe.sh: handle cc -E #error with 0 exit status (sgi) 09-10-06 package.sh: stub in ar intercept checks -- not used yet 09-10-06 ar.ibm.risc: add ar intercept because some AIX require -Xfoo first!! 09-09-24 regress.sh: fix UMASK logic to create test support files before umask 09-08-28 release.c: change docs to mention stdin if no file operands 09-08-24 package.sh: fix isascii() bug that failed on od(1) trailing space 09-08-20 make.probe: add CC.SHARED.NAME 09-08-20 regress.sh: add { JOB CONTINUE EXITED KILL FIFO } 09-08-11 package.sh: filter lines containing : for package results 09-07-31 make.probe: add CC.AR.ARFLAGS (for AIX ar -xany) 09-07-31 package.sh,cc.*: fix -dumpmachine to handle 32/64/* bit options 09-06-24 package.sh: fix admin.db output formatting 09-05-05 package.sh: export dll hackery environment vars 09-05-05 package.sh: handle non-identifier hostnames 09-05-05 mamake.c: pass undefined ${...} identifiers to the shell 09-05-05 mamake.rt: add macro expansion regression tests 09-05-01 iffe.sh: fix output initialization *again* 09-04-28 package.sh: handle admin.db contact field $9 09-04-15 iffe.sh: add implicit "ini" op to initialize io for subsequent ops 09-03-31 regress.sh: EXPORT before test => global ENVIRON[] 09-03-26 package.sh: test fail pattern is 'fail[es]' 09-03-26 UNIT - ... appends (options) to command line 09-03-19 TEST.mk: x.tst => x only if x is command target 09-03-15 regress.sh: add ${MAIN} for base name of main unit 09-03-10 TEST.mk: add .SOURCE:tests if tests is a dir 09-03-03 regress.sh: allow command line unit to override UNIT 09-03-03 mktest.sh: handle IO == $'\n' 09-02-02 package.sh: delay $INSTALLROOT/bin/.paths generation until mamprobe runs 09-01-30 cc.mvs.390: c89 balks at [ ()] in -Dname="..."! 09-01-27 package.sh: add isascii() to use ratz instead of tar 09-01-20 hurl.sh: add --size=bytes option 09-01-08 TEST.mk: add test.* prereqs, multiple arg lists with :T=*: binding 09-01-03 regress.sh: fix UNIT to allow command line override 09-01-03 mktest.sh: handle TWD 08-12-24 package.sh: fix cross-compile HOSTTYPE logic 08-12-15 package.sh,hurl.sh: handle http codes { 301 302 303 } 08-10-16 make.probe '-fno-stack-protector -fno-stack-protector-all' to cop out!! 08-09-30 rt.sh: fix ksh93 regression test signal count 08-09-26 regress.sh: ignore SIGPIPE for SET pipe-input 08-09-24 package.sh: package only test foo => make --recurse=only recurse tests foo 08-09-20 make.probe: handle another /usr/bin/file shared lib description 08-09-20 regress.sh: add --pipefail for SET pipe-input ... 08-09-17 Makefile: add gdbm1.c for 08-09-10 make.probe: add CC.NOPROTECT 08-08-08 mktest.sh: add --width=width 08-08-05 dbm.req: favor sleepycat ndbm compatibility 08-08-04 C+probe: fix stdlib initialization logic 08-06-24 package.sh: fix $INSTALLROOT/bin/cc intercept time stamp file typo 08-06-20 TEST.mk: make the localyunit before *.rt => *.tst -- doh 08-06-20 mktest.sh: prepend $PWD onto PATH for local units -- doh^2 08-06-11 regress.sh: fix bug that skipped the last test 08-05-20 regress.sh: add --local to put *.tmp dir in local fs 08-05-05 regress.sh: add IF command ... ELIF command ... ELSE ... FI 08-05-01 package.sh: package test => ulimit -c 0 08-04-28 regress.sh: fix EXPORT quoting 08-04-28 regress.sh: fix UNIT set check args too 08-04-24 rt.sh: exit code > 256 => signal termination 08-04-10 C+probe: change probe_so order to check .so last (Mac OS X ld workaround) 08-04-01 package.sh: handle multiple admin HOSTTYPEs per HOST 08-03-28 C+probe: add C++ #include (no extension) dir probes 08-03-17 regress.sh: fix trap on EXIT, add terminated note to final tally 08-02-28 make.probe: fix probe_warn to include ld! 08-02-02 make.probe: add CC.RUNPATH to match default -L order 08-01-31 package.sh: check lib64 for LD_LIBRARY_PATH 08-01-31 iffe.sh: tweak ancient /bin/sh workarounds 08-01-28 make.probe: Darwin ld export dynamic is -force_flat_namespace 08-01-28 C+probe: handle SGI cc error message but exit 0 botch(es) 08-01-23 package.sh: fix checksum doc typo 08-01-09 C+probe: add __FUNCTION__ to the undef (don't check) list 07-12-14 iffe.sh: add set nooptimize 07-12-03 package.sh: add LC_ALL=C 07-11-27 package.sh: fix overaggressive *.md5 cleanup 07-11-20 iffe.sh: treat exit status >= 250 as normal error with no signal 07-11-05 package.sh: fix write op error count pattern 07-11-05 package.mk: fix $(~req) .ver binding 07-08-11 probe.win32: add cl.exe setuid workaround, CC.VERSION[.STRING] 07-08-01 package.sh: handle 'package read lcl|tgz' 07-05-08 regress.sh: execute basename instead of absolute path for short $0 07-04-27 cc.sgi.mips[34]: for #error to exit non-zero -- a no brainer 07-04-20 mktest.sh: defer to systems without 'grep -q' -- sigh 07-04-11 mamprobe.sh: handle $(CC.*) => ${mam_cc_*}, $(...) => ${...} 07-04-11 make.probe: fix CC.PICBIG probe, default { CC.PIC CC.DLL } to BIG 07-04-04 iffe.sh: prepend ${tst}${ext} to each .c probe 07-03-28 package.sh: fix binary tgz architecture type duplication 07-03-28 package.mk: add binary write PACKAGE.$HOSTTYPE.lst 07-03-28 iffe.sh: add -F header to mac test 07-03-23 make.probe: handle file(1) that returns 'archive' for .so 07-03-22 mamprobe.sh: fix STDED probe for implementations that ignore EOF 07-03-11 package.sh: add nocopyright and tst => nocopyright 07-03-11 package.mk: add copyright=0 07-03-08 C+probe: restore IFS after probe.ini 07-02-26 mamake.c: expand first of ${mam_lib*} for ${AR} 07-01-05 package.sh: fix "admin write binary" logic 07-01-01 iffe.sh: add "cmd" --verbose trace 07-01-01 iffe.sh: sort => LC_ALL=C sort 07-01-01 C+probe: LC_ALL=C 06-12-22 make.probe: lean on gcc -v for stdlib, but preserve /usr/local! 06-11-23 package.sh: *.md5 are not tarballs -- doh 06-11-23 iffe.sh: add -F, --features=feature-test-header 06-11-11 make.probe: favor lib64 over lib for hosttype==*64 06-10-31 make.probe: add "-ignore-source-dir -iquote" test 06-10-31 iffe.sh: add status{...} code block 06-10-11 regress.sh: fix DO to handle {...} (time for regress.tst?) 06-10-11 package.sh: handle already gunzip'd *.tgz 06-10-06 iffe.sh: add reference for header content tests 06-09-27 regress.sh: fix UMASK to do DO too (duh) 06-09-22 iffe.sh: drop -O for npt tests (for msvc intrinsics) 06-09-14 cc.darwin: drop -O until gcc 4.* gets its act together 06-09-11 package.sh: { cc ld ldd } intercepts check ${HOSTTYPE%.*} too 06-09-08 regress.sh: add PIPE INPUT|OUTPUT for pipe io 06-09-05 C+probe: add { probe_version version_stamp version_string } 06-09-05 make.probe: add version stamp comment, CC.VERSION[.STRING] 06-08-27 regress.sh,mktest.sh: add UMASK 06-08-25 regress.sh: add -b,--ignore-space,IGNORESPACE 06-08-25 mktest.sh: add IGNORESPACE 06-08-24 mktest.sh: handle \000 in data 06-08-24 regress.sh: handle -f* for INPUT|OUTPUT|ERROR 06-08-16 package.sh: fix 'install flat' logic 06-08-11 rt.sh: handle style=shell %K date format 06-07-17 ratz.c: fix __MVS__ FAR definition 06-07-17 iffe.sh: "header x.h" -- deprecate "include x.h" for .SCAN.iffe 06-07-17 package.sh: differentiate urls vs. assignments 06-06-27 rt.sh: add --failed, --heading 06-06-27 C+probe,TEST.mk,make.probe,mktest.sh,regress.sh: 'ulimit -c 0' 06-06-26 cc.darwin.ppc: handle -lcc_dynamic disappearance 06-06-25 mktest.sh: implement PROG 06-06-11 Makefile: add -ldbm :MAPLIB:, provide public MAPLIB.mk 06-05-06 package.sh: add PACKAGE_admin_tail_timeout 06-05-22 ratz.c: upgrade to zlib-1.2.3 06-05-09 package.sh: fix admin.db docs 06-03-11 package.sh: fix `package use - command ...' 06-03-05 make.probe: work around pedantic bash 3.1 mismatched " in `.` 06-02-14 package.sh: "results failed test" == "results test failed" cc.sgi.*: add _AST_cc_OPTIONS parameterization, -OPT:Olimit=0 cc.linux.ia64-icc: add for Intel cc 06-02-02 package.sh: FreeBSD stuck with OS version for all arch 06-02-01 package.mk: fix locale logic (tw -d requires dir arg) 06-01-31 package.sh: require $CC only for make|test 06-01-30 package.sh,hurl.sh: use the backwards-compatible --http-passwd package.sh: add more pdksh => /bin/sh checks 06-01-26 package.sh: wget --http-pass => --http-password package.sh: fix wget error logic hurl.sh: wget --http-pass => --http-password 06-01-11 package.mk: pass package.license.class to make --mam too package.mk: variants=pattern => --variants=pattern package.sh: Darwin rel<=7 => darwin7.ppc package.sh: FreeBSD rel<=4 => freebsd4 package.sh: FreeBSD rel<=5 => freebsd5 05-12-07 iffe.sh: don't emit if | (XXX) 05-12-05 make.probe: disable readonly.exe core dump via ulimit -c 0 05-09-22 mktest.sh: add EXEC [ ++NOOUTPUT ++NOERROR ++NOEXIT ] 05-09-21 mktest.sh: fix --style=shell compare to ignore \r 05-09-12 TEST.mk: all --force to force %.rt regeneration 05-09-05 TEST.mk: regenerate from %.rt only if newer, :SAVE: %.tst 05-08-25 mktest.sh: add TEST.mk: add %.rt=>%.tst for mktest 05-08-18 package.sh: 'package host cpu' now checks $NPROC first 05-07-17 iffe.sh: add { define extern include print } ops iffe.sh: accept output{...}end output on success only -- doh 05-07-01 package.sh: add TARPROBE for tar B flag probe 05-06-24 package.sh: fix binary read chmod via *.sum 05-06-06 package.sh: fix KEEP_HOSTTYPE logic to handle synthesized types 05-06-01 make.probe: verify that cc_pic works for hosted cc cc.lynxos.ppc: make -mshared the default package.sh: note $INSTALLROOT/bin/@(cc|ld|ldd) installation 05-05-25 make.probe: add CC.INCLUDE.LOCAL instead of -I- in CC.DIALECT 05-05-24 iffe.sh: really fix grouping logic -- with tests this time package.sh: pipe/socket configuration mismatches => use /bin/sh 05-04-28 TEST.mk: add $(TESTS) 05-04-19 package.sh: package results test uses rt if possible iffe.sh: fix 'op var - ... - ...' grouping logic 05-04-15 rt.sh: handle autom4ate style 05-04-11 regress.sh: fix unit name when command line unit also specified rt.sh: handle all AST package test output formats package.sh: fix make docs for options passed to underlying make 05-04-08 package.sh: cp -p makerules.mo to $OK to preserve mtime regress.sh: add "TITLE name" to change TEST output title 05-04-01 rt.sh: add pretty make test + regress.sh wrapper 05-03-29 package.sh: test -e path => test -f path -o -d path 05-03-24 make.probe: fix CC.PICBIG probe to prefer -fPIC over -fpic -- doh 05-03-19 mamake.c: command line name=var also defines name.FORCE=var 05-03-11 regress.sh: unset LC_ALL when LC_* EXPORT'd package.sh: old make.out saved in circular make.out.[1-9] mamake.c: sync with nmake :W=O: 05-03-01 package.sh: fix flat hierarchy initialization package.sh: admin action now properly resets sibling remote logs package.mk: relax unknown/unwritten package messages to warnings package.sh: handle space in command line name=value make.probe: add MVS -Wc,dll,exportall,longname,rent to CC.DLL probe 05-02-24 package.sh: hosttype *.powerpc => *.ppc cc.lynxos.ppc,ldd.lynxos.ppc: add 05-02-22 mamake.c: fix { -G --debug-symbols -S --strip-symbols } MAMAKEFLAGS bug 05-02-20 probe.win32: handle /platformsdk mount 05-02-19 package.sh,package.mk: add write tst for tgz in tst subdir 05-02-18 package.sh: accept cc -dumpmachine with 0 or 1 - 05-02-14 package.sh: handle multiple architectures per host in admin.db Makefile,package.sh: honor $INSTALLROOT/bin/.paths overrides package.sh: normalize trailing [-_]bits in host type iffe.sh: some ksh-compatible shells don't do *(pattern) 05-02-11 iffe.sh: back out 05-01-11 child process stdin hijack cc.lynxos.i386: -dynamic instead of -static default 05-02-10 package.sh: cyg usr/doc => usr/share/doc 05-02-08 package.sh: drop -m with pax -- delta bug fixed 2005-02-08 iffe.sh: work around old bash 0<... redirection bug 05-02-06 package.mk: source.tgz: update generated files only when they change 05-02-02 *.sh,*probe: IFS may be unset and { ash bsh } don't on startup -- wow 05-01-11 package.sh: update setup docs to include authorize+password package.mk: fix .source.cyg final directory edit package.mk: notice=1 for conspicuous empty NOTICE file WWW.mk: fix *-index.html installation filter.sh: retain input file suffix in tmp copy mamexec.c: fix non-contiguous "exec" bug that skipped lines iffe.sh: fix candidate lib test to try grouping subsequent libs iffe.sh: fix child process stdin hijack that skipped input lines iffe.sh: --shell=osh to force read -r compatibility command iffe.sh: chop iffe input leading space before # for KnR compatibility 05-01-05 package.sh: add ${TAR} ${TARFLAGS} and tar B flag for pipes mamake.c: fix makefile scan to ignore lib*.[hH] iffe.sh: immunize function/symbol tests from aggressive -O 04-12-28 WWW.mk: add :WWWPAGE: faq.*.mm index generator 04-12-21 ratz.c: make sure tmp dir is writable -- doh 04-12-08 iffe.sh: fix dat test for aggressive -O 04-12-01 iffe.sh: add `include file' to pull in #define's for `exp' 04-11-11 package.sh: default MAKESKIP is "*[-.]*" 04-10-22 ratz.c: change docs to note zlib license mamake.c: handle --debug-symbols and --strip-symbols package.sh: make (debug|strip)=1 => --(debug|strip)-symbols package.mk: add :LICENSE: => package.license.class mamake.c: fix recursive order logic 04-10-18 package.mk: add :LICENSE:, :OMIT: to omit package subdirs 04-10-11 package.sh: add 'authorize name' and 'password password' 04-10-01 iffe.sh: double check $static link with ! $static Makefile: add BUILTIN_LIB to $INSTALLROOT/bin/.paths make.probe: add CC.DIALECT EXPORT={ALL,REF,EXT,DLL} package.sh: add BUILTIN_LIB to $INSTALLROOT/bin/.paths 04-09-21 package.mk: $(init)$(name) is now an implicit prereq 04-09-09 package.sh: copy makerules.mo to $INSTALLROOT/bin/ok 04-09-01 package.mk,package.sh: rename *.txt => *.README package.mk: add the runtime package type (no *.[ah]) iffe.sh: fix key test reports 04-08-26 Makefile: { add m2.c m3.c } -lm tests for { frexp[l] ldexp[l] } 04-08-11 package.mk: handle HOSTTYPE for Solaris > 9 package.sh: add `checkaout proto' for { make view } package.sh: check for { md5sum md5 } iffe.sh: add {if|elif|else|endif} test ... iffe.sh: add 'exp - expression' and '( expression )' iffe.sh: add 'name = test ...' user defined macros iffe.sh: add '! test ...' negation TEST.mk: add implied { .c .sh } generated prereq cc.darwin.ppc: handle 10.3 -dylib mess 04-08-01 package.mk: let include handle nested requirements -- duh 04-07-31 package.sh: attempt a second ping before admin assumes host down 04-07-26 package.sh: fix hp.ia64 HOSTTYPE 04-07-23 probe.win32: generalize #include dir order search 04-07-17 regress.sh: add INPUT -x for chmod +x 04-07-01 regress.sh: TMP => TWD 04-06-29 regress.sh: put COMMAND in $TWD too 04-06-21 regress.sh: mkdir -p INPUT and OUTPUT intermediate dirs TEST.mk: add :TEST: -- to disable .c .sh search 04-06-18 TEST.mk: add .SCAN.tst 04-06-17 regress.sh: TEST returns true if active, false otherwise regress.sh: add CD to change test pwd from $TWD 04-06-16 regress.sh: add TWD for ./unit.tmp override regress.sh: DO now flushes previous test regress.sh: INPUT and OUTPUT handle -f for printf instead of print 04-06-11 package.sh: make sure $INSTALLROOT/bin is in front of $PATH package.sh: skip nmake if older than 2000-10-31 04-05-20 package.sh: fix arg vs. package parse with - or '' to disambiguate 04-05-11 package.sh: package verbose update lists closure for package setup package.sh: add src/lib/libardir to nmake proto bootstrap regress.sh: probe for rm -u vs. chmod -R u+rwx 04-05-01 package.sh: $CC must be C, not C++; allow release command on $PATH 04-04-15 make.probe: check probe_libdir false positives package.sh: add lib/package/*.lic src package subdirs package.mk: add mamfile=0 to inhibit Mamfile generation iffe.sh: config name_DECLARED => HAVE_name_DECL iffe.sh: fix mac to handle default value 04-04-11 iffe.sh: normalize sed [\\\\/] quoting 04-04-04 package.mk: only checksum generated tarballs mamprobe.sh: add STDCHMOD 04-04-01 C+probe: set export LANG=C for uniform error messages make.probe: another CC.STDLIB tweak package.sh: fix regress core dump pattern, expand [a-z] match ranges 04-03-31 Makefile: add intl :MAPLIB: test make.probe: fix CC.STDLIB search; drop CC.* path duplicates 04-03-28 iffe.sh: drop unused exec $stdin<&0 dup 04-03-25 Makefile: add iconv :MAPLIB: package.sh: use ${PING:-ping -c 1 -w 4}, allowing admin.db override 04-03-24 package.mk: add *.md5 checksum for each *.(c|exe|tgz) package.sh: update base change on md5 sum instead of size iffe.sh: adjust case label \ and keyword quoting for ancient /bin/sh 04-03-22 probe.win32: ncc => nld 04-03-19 CONVERT.mk: change the instructions and old source dir default package.mk: fix recurse=list check package.mk: add *.md5 checksum for each *.(c|exe|tgz) package.sh: fix update base/delta/sync existence check 04-03-18 iffe.sh: -d2 does not remove core dumps on exit 04-03-17 package.sh: fix make recurse arg/action order 04-02-29 package.sh: add regress action to compare current and previous tests package.sh: fix sgi.mips[23] HOSTTYPE test for old IRIX cc package.sh: add `export variable ...' package.sh: admin action now handles host name with non-id chars package.sh: non-numeric M T W in admin.db disables that action package.sh: fix admin write binary local vs. shared clash cc.hp.pa: add _AST_CC_hp_pa_DEFAULT=+DAportable cc.hp.pa64: sync with cc.hp.pa cc.ibm.risc: -bnolibpath => -blibpath:/usr/lib:/lib probe.win32: sync with make.probe make.probe: fix last chance dynamic test make.probe: add hp.pa CC.EXPORT.DYNAMIC -Wl,-E make.probe: add ibm.risc CC.EXPORT.DYNAMIC -bexpall make.probe: move probe_dll_def to the end of probe_dll package.mk: capture subcomponent mamfile recursion 04-02-24 make.probe: strip "..." from cc/ld traces iffe.sh: add ``set [no]define'' to disable macro #define/#undef 04-02-23 make.probe: rework CC.LD search 04-02-14 make.probe: add CC.EXPORT.DYNAMIC for main dynamic sym export make.probe: resurrect CC.PIC with separate semantics from CC.DLL make.probe: add CC.SHARED.LD for CC.SHARED linker C+probe: clear DISPLAY to stifle interactive windows 04-02-11 iffe.sh: handle ``siz void*'', add cross{ ... }end make.probe: add { CC.AR CC.SIZE }, fix cross command search cc.darwin.ppc: change $cc => $CC for old ksh + libast conf bug 04-02-09 make.probe: drop -nostartfiles from CC.SHARED for C++ 04-02-04 package.sh: fix cross compilation bug that mixed binary formats 04-02-02 package.sh: package admin now ditto's bin/package too 04-01-30 cc.sgi.mips3: drop warning 3421 04-01-11 regress.sh: output label#count for tests in loops 04-01-05 regress.sh: fix bug that ignored the first SAME 04-01-04 crossexec.sh: fix typo that did not recognize rcp 03-12-19 mamake.c: add `foolib:foo:libfoo' to recurse() 03-10-11 regress.sh: add EXPORT, export COLUMNS=80 for message consistency 03-09-23 ratz.c: fix tar header number parse bug that skipped to next number regress.sh: rm cleanup now handles files matching -* 03-09-11 iffe.sh: add unnamed { ... } blocks regress.sh: add COPY from to, like MOVE but comparison still done regress.sh: rm -rfu to handle test dirs w/o u+rwx 03-08-14 Makefile: add hello.c to the manifest 03-08-11 package.sh: fix `html binary' generation 03-06-21 package.sh: fix INITROOT initialization bug package.sh: make sure admin logs exists before tail'ing 03-06-11 probe.win32: fix $(BINDIR) typo that expanded in sh instead of make cc.mvs.390: return code 4 yields exit code 3 but it's *really* ok package.sh: fix onpath function global var conflict make.probe: add CC.DIALECT { GNU -dD } package.mk: add Mamfile to lcl manifest 03-06-10 package.sh: fix setup action typo that only checked the INIT package package.sh: *.s390x => *.s390-64 03-06-09 package.mk: add cyg :POSTINSTALL: 03-06-08 make.probe: fix CC.STDLIB logic hurl.sh: add User-Agent identification package.sh: tweak source and binary installation instructions cc.hp.pa,ld.hp.pa: +-Wl,+cdp,${INSTALLROOT}/lib/: drops abs lib paths ldd.hp.pa: add 03-06-06 package.sh: fix $INSTALLROOT/bin/ldd check make.probe: add CC.STDLIB verification 03-06-04 make.probe: add +forceread +noforceread 03-05-11 hurl.sh: handle http://host:port/path 03-05-06 package.sh: fix setup action PACKAGEROOT and INIT logic 03-05-05 package.mk: fix Cygwin tarball names 03-04-30 package.sh: move (cc|ld|ldd).$HOSTTYPE updates from Makefile 03-04-27 make.probe: fix MVS CC.PREFIX.SHARED "lib" => "" make.probe: add CC.DLL.DIR = $(BINDIR) or $(LIBDIR) make.probe: add { CC.LD.LAZY CC.LD.NOLAZY CC.LD.RECORD CC.LD.NORECORD } probe.win32: sync with latest CC.* 03-04-25 mamprobe.sh: add args to `. $makeprobe' for ancient sh 03-04-23 package.mk: fix dup "covered by" licenses 03-04-22 probe.win32: CC.DIALECT += "LIBPP -I-" for all cc's package.sh: fix admin write binary tarball snarf 03-04-21 package.mk: package covered *.@(pkg|lic) too 03-04-15 package.mk: don't generate incremental archives for lcl package.mk: add incremental=[source:1 binary:0] archive control package.sh: generate $INSTALLROOT/bin/cc wrapper for CC != cc package.sh: admin must ditto lib/package/*.@(pkg|lic) too mamake.c: ignore time of ignore prereqs mamake.c: -D2 lists propagated times 03-04-11 package.mk: tidy up cyg tarballs package.sh: fix old shell clash between get() and $get 03-04-05 package.mk: restore *.inx generation somehow lost during cyg additions package.sh: add pthread_num_processors_np() last resort for CPU count package.sh: use `make believe' to accept mamake generated files package.sh: handle `make [make-flags] [target ...]' mamake.c: ignore -e 03-03-21 package.mk: fix cyg old make typo package.sh: switch to `package setup' instructions 03-03-19 package.sh: add registry checks for `host cpu' package.sh: `results failed' now lists core dump messages 03-03-17 package.sh: on Cygwin verify 'ntsec binmode' in $CYGWIN or die Makefile: install gcc wrapper if no cc package.mk: add :DETAILS: { :README: :EXPORT: :INSTALL: :TEST: } ops 03-03-12 package.mk: add :DETAILS: for style-specific details 03-03-11 package.sh: add beta setup/update support TEST.mk: add (TESTCC) prereq for .sh tests 03-03-07 hurl.sh: add 03-03-06 iffe.sh: fix lib Win32 test Cygwin vs native incompatibility iffe.sh: change internal stdio.h guard to handle C++ inline vs. macro 03-03-03 package.sh: check for curl or wget for update package.sh: add setup action == update read make package.sh: fix packageroot() typo that showed up in non ~user shells mamake.c: treat name+=value args like name=value mamake.c: add ${var?*|value?match?no-match?} mamake.c: fix archive vs. dynamic bind logic 03-02-28 package.sh: add the "cyg" (Cygwin) package type package.mk: add "cyg" stubs, :CATEGORY: for category name(s) 03-02-25 mamake.c: add -D4 system(3) debug trace 03-02-24 package.mk: change --mismatch to --corrupt=accept 03-02-14 ratz.c: add _WIN32 setmode([01],O_BINARY) and fopen "rb"/"wb" 03-02-12 Makefile: handle getconf LIBPATH with host pattern 03-01-31 package.mk: fix .lic search 03-01-30 package.sh: handle { INIT ksh nmake } already installed elsewhere package.sh: admin handles command outside of $PACKAGEROOT/bin Makefile: install $(INSTALLROOT)/lib/make/package.mk 03-01-28 package.sh: admin remote commands on one line to please syslog 03-01-23 probe.win32: borland and mingw32 tweaks 03-01-22 package.sh: fix $CC test to ignore set -x trace -- duh 03-01-16 ditto.sh: tw --chop on by default 03-01-14 package.sh: use /bin/cp to copy previous binaries to bin/ok/ package.sh: admin now initiates remote exec and copy from local host 03-01-12 package.sh: handle admin "xxx:" default root 03-01-03 probe.win32: add /usr/include/borland path truncation workaround 02-12-10 iffe.sh: add <&$nullin >&$nullout to checkread() $cc 02-12-06 probe.win32: fix inlcude => include typo, add lcc lib probe.win32: CC.MAKE.OPTIONS = nativepp=0 02-12-04 mamake.c: fix ${foo-bar} to expand foo if defined 02-11-28 probe.win32: add C++ and -I- CC.DIALECT checks 02-11-26 package.sh: package release now checks for second level files 02-11-22 package.sh: update action now uses HTTP/1.0 02-11-21 probe.win32: update the vc include dir test 02-11-20 make.probe: fix CC.LD.ORIGIN typo that expanded make var 02-11-13 packahe.mk: fix list.install => list.installed typo 02-11-12 make.probe: add CC.LD.ORIGIN for a.out origin dir relative dll search make.probe: add CC.LD.STRIP for link time a.out strip package.sh: fix package_use vs. PACKAGE_USE check 02-10-24 WWW.mk: fix bug that required a :WWWBIN: assertion to post 02-10-23 mamake.c: fix uninitialized time in make() ratz.c: fix meter buffer overflow 02-10-20 package.sh: fix lib/probe/C/make/probe update test 02-10-18 probe.win32: update for mingw make.probe: add bash workaround to SHELLMAGIC test package.sh: work around yet another Cygwin hassle 02-10-17 iffe.sh: short circuit id check for *[-+/\\]* 02-10-08 regress.sh: unset FIGNORE to avoid rm . errors package.sh: unset FIGNORE to avoid rm . errors package.sh: $CC must at least compile and executable hello world 02-10-04 package.sh: $INSTALLROOT/lib/package/tgz=>$PACKAGEROOT/lib/package/tgz package.mk: $(ED) => $(STDED), $(EDFLAGS) => $(STDEDFLAGS) iffe.sh: add identifier checks for tests that (implicitly) require them iffe.sh: disambiguate a few --config macros 02-10-02 iffe.sh: fix shell=bsh `hdr a/b' 02-09-30 package.sh: handle chmod of -* files package.sh: verify that $SHELL is Bourne compatible package.sh: tighten PACKAGE_USE logic PATH,LIBPATH,etc. validation iffe.sh: fix bug that didn't define mac variable on success 02-09-22 package.sh: handle admin_action=ditto iffe.sh: --config sizeof(foo) macro is SIZEOF_foo iffe.sh: fix long.long test so it doesn't defeat UWIN "typ long.long" mamprobe.sh: convert $("foo") nmake string constants 02-09-21 mamprobe.sh: "-" info-path writes probe info to stdout 02-09-11 make.probe: move from nmake src to be part of mamprobe.sh mamprobe: generate from mamprobe.beg C.probe make.probe mamprobe.end mamake.c: pass cc absolute path to mamprobe package.sh: generate mamprobe -- yuk (at least it's confined to INIT) iffe.sh: lcl,nxt: drop default sys/ check ditto.sh: tw --logical by default; add --physical 02-09-10 package.sh: SHELLMAGIC creeps into package too -- duh and fooey 02-09-09 ditto.sh: test that remote .profile exists before sourcing 02-09-06 package.sh: don't ditto nfs junk ditto.sh: --show now lists directory ops instead of enumerating all 02-09-05 ditto.sh: add --remote={rsh|ssh} package.sh: add admin [[{rsh|ssh|-}]:]directory 02-09-02 iffe.sh: change 'print -r --' to 'print -r -' for ksh86 compatibility 02-09-01 cc.unix.mc68k: add for ancient 3b1 02-08-22 package.sh: fix component() to test for components -- duh Makefile: add LICENSE:.DONTCARE to workaround mam 02-08-11 iffe.sh: provide defaults for LD_* additions 02-08-07 ratz.c: change -m to use * instead of non-portable inverse video 02-07-17 mamprobe.sh: close tmp file in trap before rm for Cygwin package.sh: fix "type" to handle i1586 (P4) package.sh: add the view action 02-06-28 package.sh: handle multiple packages for release action 02-06-27 package.sh: catch sol*.sparc=>sol*.sun4 when CC=gcc 02-06-14 package.sh: fix admin_action to not include qualifiers package.sh: fix help/html doc typo 02-06-11 package.sh: fix ditto update doc to `PACKAGEROOT field matching *:*' 02-06-07 WWW.mk: change substitute $("\n") to \n 02-06-06 package.sh: clarify output streams for help/html 02-05-22 mamake.c: fix executable file check to use (S_IXUSR|S_IXGRP|S_IXOTH) 02-04-04 package.sh: fix update to differentiate *.sun4 and sun4 02-03-27 package.sh: yacc/bison warning only if both missing 02-03-24 mamake.c: all shell actions wrapped with -c to avoid #! problems 02-03-23 package.sh: recover $PACKAGEROOT/bin/package if not in INIT package package.sh: precheck $CC, not `cc' package.sh: fix install to use pax -ps to preserve set-uid/gid package.sh: fix install to use list.installed for existing files only 02-03-17 package.sh: fix PAX initialization that was sometimes omitted for read package.sh: fix update delta sync fetch 02-02-14 iffe.sh: fix macro{ }end docs to include " iffe.sh: add dfn to extract #define from headers iffe.sh: handle nxt #include ok but no line sync iffe.sh: drop local header clash logic iffe.sh: add -X, --exclude=dir to exclude -I dirs iffe.sh: lcl,nxt now generate <...> headers instead of "..." package.sh: admin.db root dir matching -* disables host package.mk: fix package.src.pat typo -- too many ) package.mk: add { :COVERS: :DESCRIPTION: :REQUIRES: } package.sh: handle { :COVERS: :DESCRIPTION: :REQUIRES: } Makefile: move proto.c generation to the proto component dir 02-02-02 execrate.sh: add for .exe challenged Win32 systems/commands mamprobe.sh: add STD* commands/flags mamake.c: update mamprobe info when older than mamprobe executable package.sh: move ed/ex workaround to mamprobe.sh package.sh: fix `host type' bug that incorrectly assumed sun4 for sol package.sh: add execrate(1) hooks for challenged systems package.sh: add check for { cc ar nm yacc/bison } before make ratz.c: fix "rb" vs. "r" macro tests iffe.sh: add nxt, similar to lcl but defines _nxt_foo for #include iffe.sh,package.sh: remove variable from sccs,cvs ident strings -- duh 02-01-24 C+probe: check CC.DYNAMIC to handle cc that accept but ignore -B* iffe.sh: handle 'mem struct.a.b' 02-01-22 iffe.sh: cache (internal) `foo vs. struct foo' test results package.sh: uts.370 => uts.390 02-01-18 package.sh: fix uts hosttype 02-01-17 package.sh: add 'results failed ...' to list failures only package.sh: change ARCH internal var to all_types to avoid env conflict iffe.sh: fix hdr/lib precheck that missed some -- ouch iffe.sh: fix noexecute test that forgot to check compile first! 02-01-15 ratz.c: fix path[] type typo 02-01-01 package.mk: tighten license search 02-01-08 package.sh: `pwd` => ${PWD:-`pwd`} package.mk: expand license file pattern match 02-01-04 iffe.sh: fix `exp name "value"' bug that duped "value" iffe.sh: fix initial check to honor --config 01-12-25 iffe.sh: fix bug where -o file restored old file 01-12-23 package.mk: uniq the closure lists 01-12-07 ratz.c: fix --meter to retain paths containing " -- " 01-11-30 ratz.c: use sear_system() to execute; should work on all windows 01-11-28 ratz.c: fix sear_rm_r() to check SetCurrentDirectory() status 01-11-26 ditto.sh: drop n+=v for ksh compatibility 01-11-21 ditto.sh: add rsync script replacement [hey, it works!] package.sh: add [ditto]:directory notation to admin.db 01-10-31 package.sh: handle *.sum paths with embedded space package.sh: change executable() to onpath() package.sh: executable([!] foo) replaces test [!] -x foo (.exe hack) package.sh: add os2 fix to `host type' mamake.c: add .exe hack iffe.sh: fix intrinsic function lib test mamprobe.sh: update pic probe to match make.probe for linux.ia64 01-10-30 package.sh: make action skeleton view now checks subdirs 01-10-20 package.sh: don't recurse into leaf dirs matching $MAKESKIP package.mk: tarball package.notice replaces `license accepted' prompt package.sh: eliminate `license accepted' prompt package.sh: add update to download latest from a url package.sh: use builtin arithmetic when we know it's ksh iffe.sh: unkown -> unknown 01-10-18 package.sh: convert to YYYY-MM-DD delta releases instead of NNNN package.mk: convert to YYYY-MM-DD delta releases instead of NNNN ratz.c: fix -m for paths containing \f\n\r\v 01-10-16 ratz.c: _SEA_* => SEAR_* ratz.c: preserve stdin for sear_exec() ratz.c: add recursive sear_rm_r() to sear_exec() tmp dir cleanup 01-10-10 mamprobe.sh: add mam_cc_SHELLMAGIC package.sh: add nfs wakeup call to admin to avoid stale file handles 01-10-04 cc.darwin.ppc: -flat_namespace is not longer the default (huh) 01-10-01 package make: prepend $INSTALLROOT/bin/ok to PATH package read: save cpy of bin/package when reading the INIT package mamprobe.sh: allow cc path with optional arguments 01-09-24 Makefile,package.sh: add $INSTALLROOT/bin/.paths initialization 01-09-19 package.mk: add recurse to list.package.* package.sh: bootstrap build nmake with _BLD_STATIC for _WIN32 01-09-11 ratz.c: add _SEA_SKIP & _SEA_COMMAND for self extracting archives 01-09-07 package.mk: fix output capture to not generate files names with spaces 01-09-07 package.mk: fix delta release number search 01-08-11 package.mk: handle single gz executable packages (e.g., for ksh) package.sh: fix package install to require nmake only if no *.sum iffe.sh: drop ancient menu and prompt actions; check ./hdr.h clash 01-07-17 package: fix use cross compile test to generate files in /tmp 01-06-27 ratz: handle hard and soft links if possible 01-06-07 Makefile: fix :MAPLIB: for sco 01-05-31 crossexec.sh: add iffe.sh: add -x crosstype to run crossexec iffe.sh: exp test now handles pass{}end fail{}end yes{}end no{}end package.sh: add package host canon external-host-type-name package.sh: fix `use USER' lookup for shells that support ~USER cc.*: add -dumpmachine to dump target HOSTTYPE 01-05-18 iffe.sh: drop $HOME/tmp/t.sh debug trace -- oops 01-05-01 mamake.c: scan() now handles :PACKAGE: foo:command 01-04-26 *.sh: expand [a-z][A-Z][0-9] for non-contiguous character codes iffe.sh: fix run *.sh for shells that don't $* across . command cc.mvs.390: recode for /bin/sh 01-04-25 package.mk: include non cc-g variants by default package.sh: *[._]* => *?[_.]* for mvs.390 /bin/sh 01-04-24 TEST.mk: no tests for VARIANT=="DLL" 01-04-22 package.mk,package.sh: tarball text members are ASCII encoded 01-04-18 package.mk: allow package name to be the same as one of its components cc.mvs.390: handle .C .cpp .cxx cc.mvs.390: compensate for -o that does not overwrite 01-04-01 regress: fix SAME that just skipped it -- we should regress regress! iffe: fix bug that didn't emit _hdr_foo for internal hdr tests iffe: fix lcl bug for cc -E that doesn't emit line syncs ratz: add ASCII=>EBCDIC conversion for text archive members mamake: fix buffer overlap bug that clobbered the probe file path 01-03-17 iffe: handle : separator as first arg 01-03-15 mamake.c,ratz.c,release.c: add and 01-02-26 iffe.sh: fix bug that omitted runtime #define for `mac' op 01-02-22 cc.ibm.risc: handle SF_CLOSE clash in 01-02-14 cc.sgi.mips3,cc.sgi.mips4: handle -mips2 -mips3 -mips4 for cross cc C+probe: quote "$cc" when it's an argument! mamake: execute actions with $SHELL, ignored signals back to default package.sh: nmake check error output to /dev/null package.sh: fix INIT a.out updates for knr cc package.sh: package list now handles large tgz dirs package.sh: *-ok executables moved to ok/* for *.dll systems iffe.sh: change "exec >&-" to "exec >/dev/null" else Linux mkdir fails! mamake: handle `bind -lx [dontcare]' 01-02-12 ratz.c: fix _PACKAGE_ast includes package.sh: $HOSTTYPE env overrides if $PACKAGEROOT/arch/$HOSTTYPE/ package.sh: $CC ^HOSTTYPE=[A-Za-z_0-9.]*$ overrides HOSTTYPE iffe.sh: fix dat code that used previous $tmp.exe iffe.sh: fix dat code for _DLL imports 01-02-09 iffe.sh: add copy() for shells with the disappearing here doc bug 01-02-08 Makefile: guard against null $(CC.HOSTTYPE) 01-02-06 Makefile: separate out cc,ld,ldd workarounds (so they will be packaged) 01-02-02 package.sh: fix package use for $INSTALLROOT != */$HOSTTYPE package.sh: create intermediate recursion makefiles when needed package.sh: add $SECONDS to the DEBUG trace prompt 01-01-01 ratz.c: #ifdef for UWIN ncc iffe.sh,package.sh: check PACKAGE_PATH for local installations package.sh: add psrinfo for osf.alpha host cpu package.sh: change pax --meter probe; some hang on /dev/tty package.sh: fix `install flat ARCH' mamake: eliminate loops from scan order C+probe: add probe_verbose -V for AIX cc=xlc cc.ibm.risc,ldd.ibm.risc: add package.mk: list refs to top-level licenses only package.mk: add local link table to change log html 00-12-25 package.sh: `no package archives' is a hard error, duh package.sh: reorder host type logic for lame shells mamake.c: getcwd => getwd for NeXT -- how about posix==default guys iffe.sh: really gross workaround for NeXT -lposix stdout null's iffe.sh: handle cc -E that insists on compiling 00-12-15 iffe.sh: ancient sh function call blows $*; call only when $# == 0 *.sh: `getopts 2>/dev/null` => `(getopts)2>/dev/null` for ancient sh package.sh: fix LD_LIBRARY*_PATH initialization cc.next.m68k: add for _POSIX_SOURCE and linker multiply defined syms 00-12-12 ratz: add --meter package.sh: a few VPATH fixes Makefile: don't override *.mips* cc if -version not accepted 00-12-11 package.mk: *.inx now contains name=value 00-12-07 package.sh: handle PC netscape . => _ pathname mangle WWW.mk: .tar.gz => .tgz 00-11-27 package.sh: add checklicense() to do license checks at read time package.mk: change component list from preformat to table 00-10-31 package.mk: *.pkg must assert closure package.mk: add cc- variants to list.package.binary package.sh: omit dups from package list package.sh: invalid arg gives one line Usage package.sh: relax checkaout checks for non-owners package.sh: package use sets NPROC if not already set or [01] proto.c: add $(INSTALLROOT)/include/ast hack 00-10-26 WWW.mk: add .SOURCE rhs to :WWWPAGE: 00-10-25 package: fix install package.mk: add list.install 00-10-22 regress: fix VIEW to skip empty dirs 00-10-19 package.mk: $(PACKAGEROOT)/bin/nmake => $(PACKAGEROOT)/bin/manmake iffe: validate #define identifiers 00-10-18 C+probe: Mac OS X additions package: add DYLD_LIBRARY_PATH initialization add ldd.$(CC.HOSTTYPE) 00-10-01 iffe: handle -I* -L* options 00-09-21 mamake: add libxxx and xxx to makefile ordered prereqs 00-09-19 C+probe: add probe_longlong 00-09-11 package: drop manmake and $PACKAGEROOT/bin/nmake 00-09-08 iffe: verify that $cc is a C compiler 00-06-14 mamprobe: fix win32.* probe mamake: fix bug that used lower view path for generation package: don't clobber $PACKAGEROOT/bin/nmake 00-06-01 C+probe: fix stdinclude *again* package: fix write delta source to use default pax format package: add disambiguating bias for sgi.mips3 over sgi.mips4 package.mk: fix for directory content packages lib ast-locale 00-05-01 iffe: fix invalid _LIB_ macro identifier 00-04-11 C+probe: uniq stdinclude and stdlib, fix usrinclude 00-04-01 regress: fix explicit OUTPUT bug that didn't compare with expected 00-03-17 package: all archives are .tgz for binary download package: $(PACKAGEROOT)/LICENSES/* in source and binary archives package: implement install and verify actions iffe: add exp, pth file dir ..., fix lib - -lfoo, fix lib - - -la -lb iffe: -L* must affect LD_LIBRARY* hacks for .exe tests -- yuk package.mk: add *.pkg :INDEX: 00-03-07 package: add admin action 00-03-06 makefile: install optional make probe override script C+make+probe.lcl 00-02-14 --- release 1.0 --- ratz: treat "foo/" as a dir, not a regular file package: clarify source and binary installation instructions package: fix so binary packages can install without cc package: "ratz" now a non-archive package (the only one) for bootstrap package: handle VPATH=a:b arg package.mk: "ratz" package adjustments Makefile: use :PACKAGE_INIT: to support binary INIT packages WWW.mk: add :WWWALL: C.probe: fix .so check that let .dll slip through iffe: fix config sh var assignment for HAVE_member_IN_struct iffe: fix config sh var assignment for symbol_DECLARED package: delay PATH export until dll hack exports complete package: don't forget binary package $(INSTALLROOT)/lib(32|64) package: add delta change log for source packages 00-02-10 mamprobe: add mam_cc_DLLBIG package: fix spelling typos package: add html help output package.mk: beef up source and binary help => html 00-02-08 package: mkdir man/man[138] in the new arch to cover MAM bug 00-01-28 package,release: add -rcount to release package: fix Linux "host cpu" and "host rating" package: copy *.lic to $PACKAGEBIN for "make" and "write binary" package: fix 'release change log' case match 00-01-24 package: add copyright action mamprobe: add -D_BLD_DLL to mam_cc_DLL 00-01-11 package: tsort for package write package: early verification that $CC works package: add non-interactive command arg for use action proto: fix -C intermediate mkdir() mamprobe: unixware.i386 ksh workaround C.probe: move hosttype to C.probe (with unixware.i386 workaround) WWW.mk: fix mm2html option quoting WWW.mk: add .SCAN.mm WWW.mk: don't force static=1; grab dll's instead *.sh: fix getopts test to handle botched implementations like osf.alpha iffe.sh: fix read -r test 99-12-25 iffe: tweak verbose messages iffe: hand code non-optget getopts parse iffe: fix bash quoting bug again iffe: do test -w . after option parse package: fix PACKAGEROOT search 99-11-19 --- release 0.2 --- 99-11-19 first working package & friends 99-10-31 change from lib0ast to INIT; add MAM and package bootstrap hostinfo: gobbled by package 99-10-01 iffe: add --config, yes{...}end no{...}end, fix read -r workaround 99-09-27 iffe: add --all --verbose, --* set options 99-09-22 regress: -v disables long line truncation 99-09-11 WWW.mk: WWWDIR and MM2HTMLINFO are now lists searched in $(HOME) 99-08-11 hostinfo: fix type sgi.mips4 99-06-24 WWW.mk: add 99-06-08 hostinfo.sh: ${TMPDIR:-/tmp} 99-06-07 TEST.mk: add 99-06-01 iffe: add `siz type' for _siz_type == sizeof(type) 99-05-11 hostinfo,iffe,regress,use: long options 99-05-01 C.probe: fix over aggressive stdinclude, e.g., /usr/include/machine 99-04-01 hostinfo: sgi.mips? -o32 and -n32 checks iffe: check that . is writable 99-03-17 hostinfo: fix for cc not found dl.c,hello.c,m.c: headers in conditionals to force .DONTCARE C.probe: extra check for include dirs pulled in by 99-03-03 regress: add `UNIT - ...' for extra args Makefile: add (_hosttype_) prereq for cc 99-01-23 hostinfo: tweak rating, use /proc/cpuinfo if there 99-01-11 C.probe: shlib before lib, /usr before / 98-12-25 iffe: work around win32.alpha intrinsic clash with -O 98-11-11 regress: fix UNIT PATH lookup 98-11-01 regress: add PROG 98-10-01 hostinfo: add unixware.* use: export PACKAGE_* 98-08-11 C.probe: add /usr/include check (for sco CC) hostinfo: handle UWIN uname update 98-05-01 regress: fix bug sometimes didn't list last test 98-04-01 hostinfo: add cc path arg hostinfo: now works with /bin/sh Makefile: strengthen -lm probe 98-01-23 Makefile: check for -ldl -lm C.probe: handle gcc -v -E phony include dirs iffe: fix lcl by dropping sort -u -- we need the real first iffe: `mem x' to test if x is a non-opaque struct 98-01-11 $(INSTALLROOT)/lib32 for sgi.mips3 $(INSTALLROOT)/lib64 for sgi.mips4 add cc.hp.pa 98-01-01 cc.sgi.mips*: turn off ld library multiply defined 97-10-11 regress: add VIEW function for locating data 97-10-01 Makefile: -ldl test moved to libdll Makefile 97-08-11 regress: add MOVE regress: add SAME regress: use getopts regress: `EXEC' repeats previous test 97-07-17 use: tweak PATH and LIBPATH bootstrap order iffe: fix lcl bug that botched pathnames with embedded spaces 97-06-12 iffe: add npt `needs prototype' test 97-05-09 hostinfo: mvs.* => mvs.390 Makefile: cc.$(_hosttype_) workaround installed here iffe: fix nolink{ ... }end iffe: add [no]static{ ... }end for static link test C.probe: _probe_PATH => _probe_export which must be eval'd 97-04-01 use: _RLD_ROOT set too 97-03-17 mm2html: changed inner loop mm2html: handle .if|.ie|.el, .so mm2html: handle different man styles mm2html: differentiate mm/man in some non-obvious cases hostinfo: r5000 is not mips4 97-02-14 hostinfo: validate type with cc 96-12-25 C.probe: UWIN tweaks iffe: use `...` instead of $(...) for alpha /bin/sh iffe: fix `typ' divide by 0 iffe: `lcl' now drops X: prefix iffe: +l* -> -l* iffe: eval around ${...#%...} for BSD /bin/sh use: add sgi.mips LD_LIBRARY_PATH variants use: add -e to list exports iffe: lcl leaves leading [a-zA-Z]: for DOS iffe: fix no{link|output|execute} logic C.probe: don't automatically add /usr/include for non-hosted compilers C.probe: don't automatically place /usr/include last C.probe: check gcc style -v -E for stdinclude usrinclude 96-11-28 iffe: check BASH_VERSION for IFS botch iffe: typ long.xxx only if sizeof(long xxx) != sizeof(xxx) hostinfo: fix sgi.mips[234] tests hostinfo: fix ncr.i386 tests 96-10-31 iffe: work around old bsh here doc bug by running separate sh 96-10-11 iffe: *.iffe and *.iff for iffe src files hostinfo: tighten sgi.mips CPU type check 96-10-01 C.probe: add probe_libdir to catch alpha /usr/shlib 96-09-17 iffe: fix typ bug that failed for single id types! 96-08-31 hostinfo: handle recent SGI hinv CPU changes 96-07-17 make sure sizeof(long xxx)>sizeof(xxx) for typ long.xxx 96-05-09 C.probe: drop multiple / in stdinclude 96-02-29 use: package root must have bin and lib subdir mm2html: add C.probe: probe_members += -whole-archive for gcc iffe: add + fix the blasted `...'...\\...'...` 96-01-31 use: add pkg dir hostinfo: add tandem 96-01-01 hostinfo: windows_nt|windows[0-9][0-9] -> win32 95-11-24 hostinfo: linux-aout.* for non-ELF Linux 95-11-11 use: add AIX LIBPATH 95-10-11 hostinfo: no args prints type 95-08-11 use: add 95-05-09 save original PATH in _probe_PATH beef up library dir probe 95-04-01 use c source suffix if it still preserves the dialect add hostinfo add lib/hostinfo/typemap user type map add sol.sun4 CPU count fix C.probe to properly handle C/C++ combined compiler drivers add NeXT to hostinfo bummer: mach has /usr/bin/hostinfo 95-03-19 fix dialect executable test 95-03-19 --- release 0.0 --- ksh-1.0.0-beta.2/src/cmd/INIT/ar.freebsd12.amd64000077500000000000000000000001411415700074400204570ustar00rootroot00000000000000: freebsd12.amd64 ar wrapper case $1 in *x*) /usr/bin/ar "$@" ;; *) /usr/bin/ar U"$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/ar.ibm.risc000077500000000000000000000002461415700074400175040ustar00rootroot00000000000000: stupid stupid stupid to require a non-standard option for ar to work : 2009-10-06 : op=$1 shift case $op in -*) ;; *) op=-$op ;; esac /usr/bin/ar -Xany "$op" "$@" ksh-1.0.0-beta.2/src/cmd/INIT/ar.linux.i386-64000077500000000000000000000001371415700074400200530ustar00rootroot00000000000000: linux.i386-64 ar wrapper case $1 in *x*) /usr/bin/ar "$@" ;; *) /usr/bin/ar U"$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.freebsd000077500000000000000000000002121415700074400173640ustar00rootroot00000000000000: FreeBSD cc wrapper HOSTTYPE=freebsd.generic case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac exec /usr/bin/cc -P "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.hp.ia64000077500000000000000000000005521415700074400171320ustar00rootroot00000000000000: hp.ia64 cc wrapper for reasonable ANSI C defaults : 2011-01-25 : [ /usr/bin/cc -ef /usr/ccs/bin/cc ] || exit 1 : bundled cc -- really, in the face of gcc you ship a subpar /usr/bin/cc? : HOSTTYPE=hp.ia64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /usr/bin/cc -D_HPUX_SOURCE -D_INCLUDE__STDC_A1_SOURCE -D_INCLUDE_XOPEN_SOURCE_500 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.hp.pa000077500000000000000000000005301415700074400167630ustar00rootroot00000000000000: hp.pa cc wrapper for reasonable ANSI C defaults : 2004-02-29 : HOSTTYPE=hp.pa case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac _AST_CC_hp_pa_DEFAULT=${_AST_CC_hp_pa_DEFAULT-"+DAportable"} /opt/ansic/bin/cc -Ae +e -Wl,+s $_AST_CC_hp_pa_DEFAULT \ ${INSTALLROOT:+-Wl,+cdp,${INSTALLROOT}/lib/:} \ -Wl,+vnocompatwarnings "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.hp.pa64000077500000000000000000000004161415700074400171400ustar00rootroot00000000000000: hp.pa64 cc wrapper for reasonable ANSI C defaults : 2001-02-11 : HOSTTYPE=hp.pa64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /opt/ansic/bin/cc +D2.0W -Ae +e -Wl,+s \ ${INSTALLROOT:+-Wl,+cdp,${INSTALLROOT}/lib/:} \ -Wl,+vnocompatwarnings "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.ibm.risc000077500000000000000000000017141415700074400174700ustar00rootroot00000000000000: cc wrapper for AIX RISC xlc : 2012-04-17 : hosttype=ibm.risc case $HOSTTYPE in $hosttype-64) case " $* " in *" -q64 "*) ;; *) set -- -q64 "$@" ;; esac ;; *) case " $* " in *" -q64 "*) HOSTTYPE=$hosttype-64 ;; *) HOSTTYPE=$hosttype ;; esac ;; esac case " $* " in *" -dumpmachine "*) echo $HOSTTYPE exit ;; esac bin=/usr/vac/bin cc=$bin/xlc ccflags="-brtl -qhalt=e -qsuppress=1506-224:1506-507" case " $@ " in *" -G "*) ccflags="$ccflags -berok" ;; esac if test -x $bin/c99 then # the xlc optimizer vintage that supports c99 is flawed and causes the AST build to fail # case " $* " in *" -O "*) set '' "$@" '' shift while : do a=$1 shift case $a in '') break ;; -O) ;; *) set '' "$@" $a ;; esac shift done ;; esac $cc $ccflags "$@" code=$? else export PATH=/bin:$PATH LIBPATH=/usr/lib:/lib ccflags="$ccflags -blibpath:$LIBPATH" fi $cc $ccflags "$@" code=$? case $code in 127|255) code=1 ;; esac exit $code ksh-1.0.0-beta.2/src/cmd/INIT/cc.ibm.risc.gcc000077500000000000000000000007541415700074400202260ustar00rootroot00000000000000: cc wrapper for AIX RISC gcc : 2012-04-17 : hosttype=ibm.risc case $HOSTTYPE in $hosttype-64) case " $* " in *" -maix64 "*) ;; *) set -- -maix64 "$@" ;; esac ;; *) case " $* " in *" -maix64 "*) HOSTTYPE=$hosttype-64 ;; *) HOSTTYPE=$hosttype ;; esac ;; esac case " $* " in *" -dumpmachine "*) echo $HOSTTYPE exit ;; esac cc=gcc ccflags= case " $@ " in *" -shared "*) ccflags="$ccflags -shared -Wl,-G -Wl,-berok" ;; *) ccflags="-Wl,-brtl" ;; esac $cc $ccflags "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux000077500000000000000000000002531415700074400171160ustar00rootroot00000000000000: linux cc wrapper : 2021-04-08 : HOSTTYPE=linux.generic case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac exec /usr/bin/cc -P -D_LARGEFILE64_SOURCE "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux.aarch64000077500000000000000000000002301415700074400203400ustar00rootroot00000000000000: linux.aarch64 cc wrapper : 2006-02-14 : HOSTTYPE=linux.aarch64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /usr/bin/cc -P "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux.i386-64000077500000000000000000000002301415700074400200300ustar00rootroot00000000000000: linux.i386-64 cc wrapper : 2006-02-14 : HOSTTYPE=linux.i386-64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /usr/bin/cc -P "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux.i386-64-icc000077500000000000000000000005541415700074400205750ustar00rootroot00000000000000: linux.i386-64 icc wrapper : 2011-10-18 : HOSTTYPE=linux.i386-64-icc case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac icc=$(which icc 2>/dev/null) case $icc in "") if test -f /etc/profile.d/icc.sh then . /etc/profile.d/icc.sh fi icc=$(which icc 2>/dev/null) case $icc in "") echo icc: not found >&2 exit 127 ;; esac ;; esac $icc "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux.i386-icc000077500000000000000000000006031415700074400203410ustar00rootroot00000000000000: linux.i386 icc wrapper : 2021-01-31 : HOSTTYPE=linux.ia64-icc case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac icc=$(which icc 2>/dev/null) case $icc in "") if test -f /etc/profile.d/icc.sh then . /etc/profile.d/icc.sh fi icc=$(which icc 2>/dev/null) case $icc in "") echo icc: not found >&2 exit 127 ;; esac ;; esac exec "$icc" -D_LARGEFILE64_SOURCE "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.linux.ia64-icc000077500000000000000000000005461415700074400204210ustar00rootroot00000000000000: linux.ia64 icc wrapper : 2011-10-18 : HOSTTYPE=linux.ia64-icc case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac icc=$(which icc 2>/dev/null) case $icc in "") if test -f /etc/profile.d/icc.sh then . /etc/profile.d/icc.sh fi icc=$(which icc 2>/dev/null) case $icc in "") echo icc: not found >&2 exit 127 ;; esac ;; esac $icc "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.lynxos.i386000077500000000000000000000022531415700074400200050ustar00rootroot00000000000000: lynxos.i386 cc wrapper with -dynamic default : 2005-02-14 : HOSTTYPE=lynxos.i386 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=gcc link=1 static=0 set . "$@" /../ while : do shift case $1 in /../) break ;; esac case $1 in *.[cChHiI]|*.[cChHiI][pPxX][pPxX]) set . -D__NO_INCLUDE_WARN__ -I/sys/include/kernel -I/sys/include/family/x86 "$@" shift break ;; -o) case $2 in /../) ;; *) x=$1 shift set . "$@" "$x" shift ;; esac ;; -static)static=1 ;; -l*) case $static in 0) static=n set . -L/lib/shlib "$@" shift ;; esac ;; -[cE]) link=0 ;; esac x=$1 shift set . "$@" "$x" done while : do case $1 in /../) shift break ;; -l*) case $static in 0) static=n set . -L/lib/shlib "$@" shift ;; esac ;; -[cE]) link=0 ;; esac x=$1 shift set . "$@" "$x" shift done case $link:$static in 1:0) static=n ;; esac case $static in n) specs=/tmp/cc$$.specs trap 'status=$?; rm -f $specs; exit $status' 0 1 2 echo '*link: %{shared:-shared} %{static:-static} %{mshared|shared: %{static: %eerror: -shared and -static may not be combined. }}' > $specs $cc -specs=$specs "$@" ;; *) $cc "$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.lynxos.ppc000077500000000000000000000023301415700074400200720ustar00rootroot00000000000000: lynxos.ppc cc wrapper with -mshared default : 2005-06-01 : HOSTTYPE=lynxos.ppc case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=gcc link=1 static=0 set . "$@" /../ while : do shift case $1 in /../) break ;; esac case $1 in *.[cChHiI]|*.[cChHiI][pPxX][pPxX]) set . -D__NO_INCLUDE_WARN__ -I/sys/include/kernel -I/sys/include/family/ppc "$@" shift break ;; -o) case $2 in /../) ;; *) x=$1 shift set . "$@" "$x" shift ;; esac ;; -static)static=1 ;; -mshared) static=n continue ;; -l*) case $static in 0) static=n set . -L/lib/shlib "$@" shift ;; esac ;; -[cE]) link=0 ;; esac x=$1 shift set . "$@" "$x" done while : do case $1 in /../) shift break ;; -l*) case $static in 0) static=n set . -L/lib/shlib "$@" shift ;; esac ;; -[cE]) link=0 ;; esac x=$1 shift set . "$@" "$x" shift done case $link:$static in 1:0) static=n ;; esac case $static in n) specs=/tmp/cc$$.specs trap 'status=$?; rm -f $specs; exit $status' 0 1 2 echo '*link: %{shared:-shared} %{static:-static} %{mshared|shared: %{static: %eerror: -shared and -static may not be combined. }}' > $specs $cc -specs=$specs -mshared "$@" ;; *) $cc "$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.mvs.390000077500000000000000000000115541415700074400171040ustar00rootroot00000000000000: mvs.390 cc wrapper for Unix message and exit code semantics : 2012-01-20 : HOSTTYPE=mvs.390 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac ar=ar cc=/bin/c89 CC=/bin/c++ ccflags="-D_ALL_SOURCE -Wc,dll" objmax=60 tmpfiles= unbotch= # -n as *first* arg shows but does not do # -Wc,exportall => -Wl,dll # -Bdynamic => .c,.o dynamic # -Bstatic => .c,.o static # *.C => cc=$CC # *.cpp => cc=$CC # *.cxx => cc=$CC # no optimization until the optimizer is fixed: # -O dropped (no optimization) # -0 dropped (no optimization) # -1 -O (default level 1 optimization) # -2 -2 (maximal level 2 optimization) let argc=0 cmp=0 dll=0 libc=0 dynamic=1 dynamic_objc=0 static_objc=0 relc=0 botched=0 case $1 in -n) exec=print shift ;; *) exec= ;; esac export _CC_ACCEPTABLE_RC=1 export _C89_ACCEPTABLE_RC=$_CC_ACCEPTABLE_RC export _CXX_ACCEPTABLE_RC=$_CC_ACCEPTABLE_RC case " $* " in *.C" "*)let dll=2 cc=$CC export _CXXSUFFIX=C ;; *.cpp" "*)let dll=2 cc=$CC export _CXXSUFFIX=cpp ;; *.cxx" "*)let dll=2 cc=$CC export _CXXSUFFIX=cxx ;; esac exe= xxx= while : do case $# in 0) break ;; esac arg=$1 case $arg in -1) arg=-O ;; -Bdynamic) let dynamic=1 ;; -Bstatic) let dynamic=0 ;; -c) let cmp=1 ;; -D_ALL_SOURCE|-D_ALL_SOURCE=*) arg= ;; -D*[\ \(\)]*) arg=${arg#-D} botch_macro[botched]=${arg%%=*} botch_value[botched]=${arg#*=} let botched=botched+1 arg= ;; -o) argv[argc]=$arg let argc=argc+1 shift arg=$1 exe=$arg rm -f "$exe" ;; -[O0]) arg= ;; -Wc,dll)arg= ;; -Wc,exportall) let dll=1 ;; -Wl,dll)arg= let dll=1 ;; *.c) if [[ $botched != 0 ]] then src=$arg arg=${arg##*/} unbotch="$unbotch ${arg%.c}.o" arg=__$arg tmpfiles="$tmpfiles $arg" { while [[ $botched != 0 ]] do let botched=botched-1 print -r -- "#define ${botch_macro[botched]} ${botch_value[botched]}" done cat $src } > $arg fi ;; *.o) if test 0 != $dynamic then let dynamic_objc=dynamic_objc+1 else let static_objc=static_objc+1 fi ;; *.x) a=${arg%.x}.a if test -f $a then argv[argc]=$a let argc=argc+1 xxx=-Wl,dll case $a in ast.a|*/ast.a) cc="$CC -u_ast_init" ;; esac fi ;; esac case $arg in ?*) argv[argc]=$arg let argc=argc+1 ;; esac shift done tmp=/tmp/cc.${USER:-$LOGNAME}.$$.err tmpfiles="$tmp $tmpfiles" # if any dll .o's are in .a then a .x gets generated # but the native cc doesn't jcl for the .x # -Wl,dll does that, so we nuke the .x and keep the exe test 0 != $dll && xxx= case $xxx in ?*) case $exe in ?*) a=${exe##*/} a=${a%.*} case $exe in */*) tmpfiles="$tmpfiles ${exe%/*}/${a}.x" ;; *) tmpfiles="$tmpfiles ${a}.x" ;; esac ;; esac ;; esac if test 0 != $dll then if test 0 != $cmp then xxx="-D_SHARE_EXT_VARS $xxx" else xxx="-Wl,dll $xxx" fi fi set -- $xxx "${argv[@]}" # can't handle more than objmax .o's # -r into intermediates doesn't work, but the cat trick does # also, the runtime dll file must be executable but cc -Wl,dll forgets if test 0 != $dll -a \( $dynamic_objc -ge $objmax -o 0 != $static_objc \) then unset argv argc=0 libc=0 dynamic=1 dynamic_objc=0 static_objc=0 endc=0 while : do case $# in 0) break ;; esac case $1 in -Bdynamic) let dynamic=1 ;; -Bstatic) let dynamic=0 ;; *.o) if test 0 != $dynamic then dynamic_objv[dynamic_objc]=$1 let dynamic_objc=dynamic_objc+1 else static_objv[static_objc]=$1 let static_objc=static_objc+1 fi ;; -l*) libv[libc]=$1 let libc=libc+1 ;; -o) argv[argc]=$1 let argc=argc+1 shift argv[argc]=$1 let argc=argc+1 exe=$1 ;; *) argv[argc]=$1 let argc=argc+1 ;; esac shift done if test 0 != $static_objc then case $exe in ?*) $exec $ar cr ${exe%.*}.a "${static_objv[@]}" ;; esac fi if test 0 != $dynamic_objc then cat=0.0.o tmpfiles="$tmpfiles $cat" cat "${dynamic_objv[@]}" > $cat || exit else cat= fi set -- "${argv[@]}" $cat "${libv[@]}" fi # grep through the warning/error messages to get the true exit code # some annoying messages are dropped while we're at it trap 'rm -f $tmpfiles' 0 1 2 15 $exec $cc $ccflags "$@" 2> $tmp code=$? for i in $unbotch do test -f __$i && mv __$i $i done typeset -l lc while : do if read line then lc=$line case $lc in *'#include file'*'not found'*) code=1 ;; *'#pragma ignored'*) continue ;; *'definition side file is not defined'*) continue ;; *'step ended with return code 4'*) code=0 continue ;; *'step ended with return code'*) code=1 continue ;; *'try again'*) code=1 continue ;; *'unknown preprocessing directive'*) code=1 case $lc in 'warning '*) set -- $line shift line=$* ;; esac ;; *'unresolved writable static references are detected'*) test 0 != $dll && continue ;; esac else case $code:$exe in 0:?*) $exec chmod +x $exe ;; esac exit $code fi echo "$line" >&2 done < $tmp ksh-1.0.0-beta.2/src/cmd/INIT/cc.next.i386000077500000000000000000000055621415700074400174350ustar00rootroot00000000000000: next.i386 cc wrapper for Unix message and exit code semantics : 1995-05-09 : HOSTTYPE=next.i386 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # 1995-05-09 -lposix termios.o waitpid.o setpgid.o *do* work # 1994-11-04 -posix has old redirection hole bug # -D_POSIX_SOURCE requires manual fixes # libexpr/exeval.c bombs -O, no -O ok command=cc cc="/bin/cc -D_POSIX_SOURCE" nooptimize="exeval" # first check $INSTALLROOT/botch case $INSTALLROOT in "") echo "$command: INSTALLROOT: must be defined and exported" >&2; exit 1 ;; esac if test ! -d $INSTALLROOT/botch -a -dryrun != "$1" then if mkdir $INSTALLROOT/botch then : ok to initialize else echo "$command: $INSTALLROOT/botch must be initialized by the owner of $INSTALLROOT" 2>&1 exit 1 fi ( cd $INSTALLROOT/botch dir=. for i in lib . include sys do case $i in .) dir=. ;; *) case $i in /*) dir=$i ;; *) dir=$dir/$i ;; esac test -d $dir || mkdir $dir ;; esac done if test ! -f include/sys/dirent.h then echo "#include " > tmp.c header=`$cc -E tmp.c | sed -e '/^#[ ]*1[ ].*\/sys\/dirent\.h"/!d' -e 's/.*"\(.*\)".*/\1/'` sed -e 's/[ ]off_t[ ][ ]*d_off[ ]*;//' $header > include/sys/dirent.h fi if test ! -f lib/libbotch.a then lipo /usr/lib/libposix.a -thin i386 -output tmp.a ar x tmp.a termios.o waitpid.o setpgid.o ar cr lib/libbotch.a *.o ranlib lib/libbotch.a fi rm -f *.[aco] ) fi # now slip in our args case $nooptimize in "") nooptimize=. ;; *) optimize= for arg in $nooptimize do case $optimize in ?*) optimize="$optimize|" ;; esac optimize="$optimize$arg.[ci]|*/$arg.[ci]" done nooptimize=$optimize ;; esac set . "$@" . noexec= library= local= optimize= verbose= while : do shift arg=$1 shift case $arg in .) break ;; -[cES]) library=1 ;; -O) optimize=1 ;; -v) verbose=1 ;; -dryrun)noexec=1 verbose=1 ;; -I-) case $local in "") local=1 set . "$@" -I$INSTALLROOT/botch/include -I- -I$INSTALLROOT/botch/include ;; *) set . "$@" -I- -I$INSTALLROOT/botch/include ;; esac continue ;; -I*|*.[cChHiI]|*.[cChHiI][pPxX][pPxX]) case $optimize in 1) eval " case \$arg in $nooptimize) optimize=0 ;; esac " ;; esac case $local in "") local=1 set . "$@" -I$INSTALLROOT/botch/include "$arg" continue ;; esac ;; -last|*/libast.a) case $library in "") library=1 set . "$@" $INSTALLROOT/botch/lib/libbotch.a "$arg" $INSTALLROOT/botch/lib/libbotch.a continue ;; esac ;; esac set . "$@" "$arg" done case $library in "") set . "$@" $INSTALLROOT/botch/lib/libbotch.a shift ;; esac case $optimize in 0) set . "$@" . while : do shift arg=$1 shift case $arg in .) break ;; -O) set . "$@" ;; *) set . "$@" "$arg" ;; esac done ;; esac case $verbose in ?*) echo $cc "$@" ;; esac case $noexec in "") $cc "$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.next.m68k000077500000000000000000000002571415700074400175250ustar00rootroot00000000000000: next.m68k cc wrapper that enables POSIX : 2000-12-15 : HOSTTYPE=next.m68k case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /bin/cc -posix -Xlinker -m "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.openbsd000077500000000000000000000002121415700074400174040ustar00rootroot00000000000000: OpenBSD cc wrapper HOSTTYPE=openbsd.generic case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac exec /usr/bin/cc -P "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.osf.alpha000077500000000000000000000003371415700074400176350ustar00rootroot00000000000000: osf.alpha cc wrapper with reasonable namespace defaults : 1998-02-04 : HOSTTYPE=osf.alpha case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /usr/bin/cc -std -Dnoshare=_noshare_ -Dreadonly=_readonly_ "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.pentium4000077500000000000000000000006371415700074400175320ustar00rootroot00000000000000: linux.pentium4 gcc wrapper : 2005-10-24 : HOSTTYPE=linux.pentium4 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac case " $* " in *" -O "*) set -A argv -- "$@" set -A nargv integer i j for ((i = j = 0; i < ${#argv[@]}; i++)) do if [[ ${argv[i]} == -O ]] then nargv[j++]=-O3 nargv[j++]=-march=pentium4 else nargv[j++]=${argv[i]} fi done gcc "${nargv[@]}" exit ;; esac gcc "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sco.i386000077500000000000000000000002741415700074400172360ustar00rootroot00000000000000: sco.i386 cc wrapper with reasonable binary and namespace : 1998-02-04 : HOSTTYPE=sco.i386 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /bin/cc -b elf -D_SVID3 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sgi.mips2000077500000000000000000000020251415700074400175710ustar00rootroot00000000000000: sgi.mips2 cc wrapper that generates MIPS II binaries : 2006-02-14 : HOSTTYPE=sgi.mips2 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=/usr/bin/cc debug= dynamic=-G0 flags=-OPT:Olimit=0 ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433 ldignore=15,84,85,13 optimize= case $_AST_cc_OPTIONS in ?*) eval $_AST_cc_OPTIONS ;; esac case $ignore in ?*) ignore="-woff $ignore" ;; esac case $ldignore in ?*) ifs=$IFS IFS=, v=$ldignore ldignore= for i in $v do ldignore="$ldignore -Wl,-woff,$i" done IFS=$ifs ;; esac case $debug in ?*) integer n=0 for i do case $i in -g*) case $debug in -) continue ;; esac i=$debug ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $optimize in ?*) integer n=0 for i do case $i in -O*) case $optimize in -) continue ;; esac i=$optimize ;; esac a[n++]=$i done set -- ${a[@]} ;; esac if test -d /usr/lib32 then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@" else $cc -mips2 $flags $ignore "$@" fi ksh-1.0.0-beta.2/src/cmd/INIT/cc.sgi.mips3000077500000000000000000000040171415700074400175750ustar00rootroot00000000000000: sgi.mips3 cc wrapper that generates MIPS III binaries : 2007-04-27 : HOSTTYPE=sgi.mips3 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # ld: # 15 # 84 # 85 # 134 # cc: # 1685 (first!!) Invalid error number: X. # 1035 cpp #error -- 0 exit status by default - botch botch botch # 1048 # 1155 # 1171 The indicated expression has no effect. # 1184 "=" is used where where "==" may have been intended. # 1209 The controlling expression is constant. # 1343 # 3169 X not marked as intrinsic because it is not yet declared # 3170 X not marked as intrinsic because it is not yet declared # 3421 expecting function name #pragma intrinsic (X) # 3433 X not marked as intrinsic because it is not yet declared # 3434 X not marked as intrinsic because it is not yet declared cc=/usr/bin/cc debug= dynamic=-G0 flags=-OPT:Olimit=0 fatal=1035 ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3421,3433,3434 ldignore=15,84,85,13 optimize= case $_AST_cc_OPTIONS in ?*) eval $_AST_cc_OPTIONS ;; esac case $fatal in ?*) fatal="-diag_error $fatal" ;; esac case $ignore in ?*) ignore="-woff $ignore" ;; esac case $ldignore in ?*) ifs=$IFS IFS=, v=$ldignore ldignore= for i in $v do ldignore="$ldignore -Wl,-woff,$i" done IFS=$ifs ;; esac case $debug in ?*) integer n=0 for i do case $i in -g*) case $debug in -) continue ;; esac i=$debug ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $optimize in ?*) integer n=0 for i do case $i in -O*) case $optimize in -) continue ;; esac i=$optimize ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $1 in -mips2) if test -d /usr/lib32 then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@" else $cc -mips2 $flags $ignore "$@" fi ;; -mips4) case " $* " in *" -ldl "*) integer n=0 for i do case $i in -ldl) ;; *) a[n++]=$i ;; esac done set -- ${a[@]} esac $cc -64 -mips4 $flags $dynamic $fatal $ldignore $ignore "$@" ;; *) $cc -n32 -mips3 $flags $dynamic $fatal $ldignore $ignore "$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.sgi.mips3-o32000077500000000000000000000016721415700074400202020ustar00rootroot00000000000000: sgi.mips3-o32 cc wrapper that generates MIPS III O32 binaries : 2006-02-14 : HOSTTYPE=sgi.mips3-o32 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=/usr/bin/cc debug= dynamic=-G0 flags= ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433 ldignore=15,84,85,13 optimize= case $_AST_cc_OPTIONS in ?*) eval $_AST_cc_OPTIONS ;; esac case $ignore in ?*) ignore="-woff $ignore" ;; esac case $ldignore in ?*) ifs=$IFS IFS=, v=$ldignore ldignore= for i in $v do ldignore="$ldignore -Wl,-woff,$i" done IFS=$ifs ;; esac case $debug in ?*) integer n=0 for i do case $i in -g*) case $debug in -) continue ;; esac i=$debug ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $optimize in ?*) integer n=0 for i do case $i in -O*) case $optimize in -) continue ;; esac i=$optimize ;; esac a[n++]=$i done set -- ${a[@]} ;; esac $cc -o32 -mips3 $flags $dynamic $ldignore $ignore "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sgi.mips4000077500000000000000000000026131415700074400175760ustar00rootroot00000000000000: sgi.mips4 cc wrapper that generates MIPS IV binaries : 2007-04-27 : HOSTTYPE=sgi.mips4 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=/usr/bin/cc debug= dynamic=-G0 flags=-OPT:Olimit=0 fatal=1035 ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433 ldignore=15,84,85,13 optimize= case $_AST_cc_OPTIONS in ?*) eval $_AST_cc_OPTIONS ;; esac case $fatal in ?*) fatal="-diag_error $fatal" ;; esac case $ignore in ?*) ignore="-woff $ignore" ;; esac case $ldignore in ?*) ifs=$IFS IFS=, v=$ldignore ldignore= for i in $v do ldignore="$ldignore -Wl,-woff,$i" done IFS=$ifs ;; esac case $debug in ?*) integer n=0 for i do case $i in -g*) case $debug in -) continue ;; esac i=$debug ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $optimize in ?*) integer n=0 for i do case $i in -O*) case $optimize in -) continue ;; esac i=$optimize ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $1 in -mips2) if test -d /usr/lib32 then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@" else $cc -mips2 $flags $ignore "$@" fi ;; -mips3) $cc -n32 -mips3 $flags $dynamic $fatal $ldignore $ignore "$@" ;; *) case " $* " in *" -ldl "*) integer n=0 for i do case $i in -ldl) ;; *) a[n++]=$i ;; esac done set -- ${a[@]} esac $cc -64 -mips4 $flags $dynamic $fatal $ldignore $ignore "$@" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/cc.sgi.mips4-n32000077500000000000000000000016711415700074400202010ustar00rootroot00000000000000: sgi.mips4-n32 cc wrapper that generates MIPS IV N32 binaries : 2006-02-14 : HOSTTYPE=sgi.mips4-n32 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=/usr/bin/cc debug= dynamic=-G0 flags= ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433 ldignore=15,84,85,13 optimize= case $_AST_cc_OPTIONS in ?*) eval $_AST_cc_OPTIONS ;; esac case $ignore in ?*) ignore="-woff $ignore" ;; esac case $ldignore in ?*) ifs=$IFS IFS=, v=$ldignore ldignore= for i in $v do ldignore="$ldignore -Wl,-woff,$i" done IFS=$ifs ;; esac case $debug in ?*) integer n=0 for i do case $i in -g*) case $debug in -) continue ;; esac i=$debug ;; esac a[n++]=$i done set -- ${a[@]} ;; esac case $optimize in ?*) integer n=0 for i do case $i in -O*) case $optimize in -) continue ;; esac i=$optimize ;; esac a[n++]=$i done set -- ${a[@]} ;; esac $cc -n32 -mips4 $flags $dynamic $ldignore $ignore "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sol11.i386000077500000000000000000000007041415700074400174070ustar00rootroot00000000000000: solaris.i386 cc wrapper for 32 bit : 2021-05-12 : HOSTTYPE=sol11.i386 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # Solaris build scripts set $CC_EXPLICIT. If not set, function without it. case ${CC_EXPLICIT:=$CC} in '' | cc) PATH=`/usr/bin/getconf PATH` # avoid infinite recursion executing 'cc' CC_EXPLICIT=cc esac # Note: the _XPG6 macro is now defined in src/lib/libast/features/common $CC_EXPLICIT -m32 -std=c11 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sol11.i386-64000077500000000000000000000007121415700074400176350ustar00rootroot00000000000000: solaris.i386-64 cc wrapper for 64 bit : 2021-05-12 : HOSTTYPE=sol11.i386-64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # Solaris build scripts set $CC_EXPLICIT. If not set, function without it. case ${CC_EXPLICIT:=$CC} in '' | cc) PATH=`/usr/bin/getconf PATH` # avoid infinite recursion executing 'cc' CC_EXPLICIT=cc esac # Note: the _XPG6 macro is now defined in src/lib/libast/features/common $CC_EXPLICIT -m64 -std=c11 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sol11.sparc000077500000000000000000000007061415700074400200300ustar00rootroot00000000000000: solaris.sparc cc wrapper for 32 bit : 2021-05-12 : HOSTTYPE=sol11.sparc case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # Solaris build scripts set $CC_EXPLICIT. If not set, function without it. case ${CC_EXPLICIT:=$CC} in '' | cc) PATH=`/usr/bin/getconf PATH` # avoid infinite recursion executing 'cc' CC_EXPLICIT=cc esac # Note: the _XPG6 macro is now defined in src/lib/libast/features/common $CC_EXPLICIT -m32 -std=c11 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.sol11.sparc-64000077500000000000000000000007141415700074400202560ustar00rootroot00000000000000: solaris.sparc-64 cc wrapper for 64 bit : 2021-05-12 : HOSTTYPE=sol11.sparc-64 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # Solaris build scripts set $CC_EXPLICIT. If not set, function without it. case ${CC_EXPLICIT:=$CC} in '' | cc) PATH=`/usr/bin/getconf PATH` # avoid infinite recursion executing 'cc' CC_EXPLICIT=cc esac # Note: the _XPG6 macro is now defined in src/lib/libast/features/common $CC_EXPLICIT -m64 -std=c11 "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.specialize000077500000000000000000000007741415700074400201170ustar00rootroot00000000000000: -O* specialization cc wrapper : 2011-11-11 : case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac cc=cc CCREPLACE='' # these (possibly empty) options replace -O* CCALWAYS='' # these (possibly empty) options always set case $CCREPLACE in '') ;; *) case " $* " in *" -O"*) set '' "$@" '' shift while : do a=$1 shift case $a in '') break ;; -O*) set '' "$@" $CCREPLACE ;; *) set '' "$@" "$a" ;; esac shift done ;; esac ;; esac $cc $CCALWAYS "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.unix.mc68k000077500000000000000000000026171415700074400176770ustar00rootroot00000000000000: 3B1/PC7300 unix.mc68k cc wrapper for ANSI C : 2002-09-01 : HOSTTYPE=unix.mc68k case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac # /bin/cc predates ANSI C; use gcc # some headers depend on SYSTEM5 or mc68k being defined # headers for Ethernet software are under /usr/ethernet/include # both /usr/lib/libnet.a and /usr/lib/libcurses.a define select() # -lcurses uses a version of select for napms(), but that # implementation always returns an error if given file # descriptors to watch # the one in -lnet must be used if fds (instead of or in addition to # a timeout) are of interest therefore, -lnet should be # specified before -lcurses # rename(old, new) in /usr/lib/libnet.a fails if new exists # (permitted by ANSI/ISO C-1990 7.9.4.2) # gcc -fpic doesn't work as there's no _GLOBAL_OFFSET_TABLE symbol cc="gcc" exec= show=: inc=0 lib=0 set '' -DSYSTEM5 -Dmc68k "$@" '' shift while : do a=$1 shift case $a in '') break ;; -lcurses|libcurses.a|*/libcurses.a) lib=1 set '' "$@" -lnet shift ;; -lnet|libnet.a|*/libnet.a) lib=1 ;; -o) a=$1 shift set '' "$@" -o shift ;; -fpic) continue ;; -n) exec=: continue ;; -v) show=echo continue ;; -*) ;; *) case $inc in 0) inc=1 set '' "$@" -I/usr/ethernet/include shift ;; esac ;; esac set '' "$@" "$a" shift done case $lib in 0) set '' "$@" -lnet shift ;; esac $show $cc "$@" $exec $cc "$@" ksh-1.0.0-beta.2/src/cmd/INIT/cc.unixware.i386000077500000000000000000000002511415700074400203070ustar00rootroot00000000000000: unixware.i386 cc wrapper HOSTTYPE=unixware.i386 case " $* " in *" -dumpmachine "*) echo $HOSTTYPE; exit ;; esac /bin/cc -D_XOPEN_UNIX -D_XOPEN_SOURCE_EXTENDED "$@" ksh-1.0.0-beta.2/src/cmd/INIT/crossexec.sh000066400000000000000000000107061415700074400200030ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : cross compiler a.out execution (command set -o posix) 2>/dev/null && set -o posix command=crossexec tmp=/tmp/cross$$ case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) ARGV0="-a $command" USAGE=$' [-? @(#)$Id: crossexec (AT&T Labs Research) 2004-01-04 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 1994-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?crossexec - cross compiler a.out execution] [+DESCRIPTION?\bcrossexec\b runs a cross-compiled \acommand\a in an environment that supports a cross-compilation architecture different from the current host. The cross environment is determined by \acrosstype\a, usually a host type name produced by \bpackage\b(1). \acrosstype\a is used to find an entry in \b$HOME/.crossexec\b that specifies the cross compiler host and access details.] [+?The exit status of \bcrossexec\b is the exit status of \acommand\a.] [+CROSS ENVIRONMENT FILE?\b$HOME/.crossexec\b contains one line for each supported \acrosstype\a. Each line contains 5 tab separated fields. Field default values are specified as \b-\b. The fields are:]{ [+crosstype?The host type produced by \bpackage\b(1).] [+host?The host name.] [+user?The user name on \ahost\a. The default is the current user.] [+dir?The directory to copy \acommand\a and execute it. The default is the \auser\a \b$HOME\b on \ahost\a.] [+shell?The command used to get shell access to \ahost\a. Currently only \brsh\b and \bssh\b are supported.] [+copy?The command used to copy \acommand\a to \ahost\a. Currently only \brcp\b and \bscp\b are supported.] } [n:show?Show the underlying commands but do not execute.] crosstype command [ option ... ] [ file ... ] [+SEE ALSO?\brcp\b(1), \brsh\b(1), \bscp\b(1), \bssh\b(1)] ' ;; *) ARGV0="" USAGE="crosstype command [ option ... ] [ file ... ]" ;; esac usage() { OPTIND=0 getopts $ARGV0 "$USAGE" OPT '-?' exit 2 } exec= # get the options and operands while getopts $ARGV0 "$USAGE" OPT do case $OPT in n) exec=echo ;; *) usage ;; esac done shift $OPTIND-1 case $# in [01]) usage ;; esac type=$1 shift cmd=$1 shift # get the host info info=$HOME/.$command if test ! -r $info then echo "$command: $info: not found" >&2 exit 1 fi ifs=${IFS-' '} while : do IFS=' ' read hosttype hostname usr dir sh cp code=$? IFS=$ifs case $code in 0) ;; *) echo "$command: $type: unknown cross compiler host type" >&2 exit 1 ;; esac case $hosttype in $type) break ;; esac done < $info # fill in the defaults case $usr in -) cpu= shu= ;; *) cpu=${usr}@ shu="-l $usr" ;; esac case $dir in -) dir= ;; esac case $sh in ''|-) sh=ssh ;; esac case $cp in ''|-) cp=scp ;; scp) cp="$cp -q" ;; esac trap "rm -f $tmp" 0 1 2 3 15 $exec $cp $cmd $cpu$hostname:$dir /dev/null; code=\$?; rm -f $cmd; echo $command: exit \$code >&2" $tmp exit `sed -e '/^'$command': exit [0-9][0-9]*$/!d' -e 's/.* //' $tmp` ksh-1.0.0-beta.2/src/cmd/INIT/db.c000066400000000000000000000031531415700074400162000ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for sleepycat dbm compatibility */ #define DB_DBM_HSEARCH 1 #if DB_DBM_HSEARCH #include #endif int main() { DBM* dbm = 0; dbm_close(dbm); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/dl.c000066400000000000000000000030561415700074400162140ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -ldl */ #ifndef dlopen #include #endif int main() { dlopen("libdl.so",0); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/execrate.sh000066400000000000000000000107551415700074400176110ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : wrapper for .exe challenged Win32 systems/commands (command set -o posix) 2>/dev/null && set -o posix command=execrate bins=` ( userPATH=$PATH PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH getconf PATH 2>/dev/null && echo "$userPATH" || echo /bin:/usr/bin:/sbin:/usr/sbin:"$userPATH" ) | sed 's/:/ /g' ` || exit case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) ARGV0="-a $command" USAGE=$' [-? @(#)$Id: execrate (AT&T Labs Research) 2002-02-02 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 2002-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?execrate - wrapper for .exe challenged commands] [+DESCRIPTION?\bexecrate\b runs \acommand\a after checking the \afile\a operands for standard semantics with respect to \bWin32\b \b.exe\b suffix conventions. This command is only needed on \bWin32\b systems that inconsistently handle \b.exe\b across library and command interfaces. \acommand\a may be one of \bcat\b(1), \bchmod\b(1), \bcmp\b(1), \bcp\b(1), \bln\b(1), \bmv\b(1), or \brm\b(1). Only the 2 argument forms of \bcp\b, \bln\b and \bmv\b are handled. Unsupported commands and commands requiring no change are silently executed.] [+?With no arguments \bexecrate\b exits with status 0 if the current system is \b.exe\b challenged, 1 if the current system is normal.] [n:show?Show the underlying commands but do not execute.] command [ option ... ] file ... [+SEE ALSO?\bwebster\b(1)] ' usage() { OPTIND=0 getopts $ARGV0 "$USAGE" OPT '-?' exit 2 } exec=1 while getopts $ARGV0 "$USAGE" OPT do case $OPT in n) exec=0 ;; *) usage ;; esac done shift `expr $OPTIND - 1` ;; *) usage() { echo "Usage: execrate [ -n ] [ command [ option ... ] file ... ]" >&2 exit 2 } exec=1 while : do case $1 in -n) exec=0 ;; -*) usage ;; *) break ;; esac shift done ;; esac case $# in 0) if test ! -x /bin/cat.exe then exit 1 # normal fi if /bin/cat /bin/cat >/dev/null 2>&1 then exit 1 # normal fi exit 0 # challenged ;; 1) usage ;; esac case $1 in *cat|*rm) NUM=0 ;; *chgrp|*chmod) NUM=1 ;; *cmp|*cp|*ln|*mv) NUM=2 ;; *) case $exec in 0) echo "$@" ;; *) "$@" ;; esac exit ;; esac CMD=$1 shift case $CMD in */*) ;; *) for d in $bins do if test -x $d/$1 -o -x $d/$1.exe then CMD=$d/$1 break fi done ;; esac while : do case $1 in -*) CMD="$CMD $1" ;; *) break ;; esac shift done case $exec in 0) CMD="echo $CMD" ;; esac case $NUM:$# in *:0) ;; 1:*) CMD="$CMD $1" NUM=0 shift ;; esac case $NUM:$# in 0:*) status=0 for f do if test "$f" -ef "$f".exe then f=$f.exe fi $CMD "$f" case $? in 0) ;; *) status=$? ;; esac done exit $status ;; 2:2) f=$1 case $f in *.exe) ;; *) if test "$f" -ef "$f".exe then f=$f.exe fi ;; esac case $f in *.exe) if test -d "$2" then t=$2/$f else t=$2 fi case $t in */*) b=`basename "$t"` ;; *) b=$t ;; esac case $b in *.*) $CMD "$f" "$t"; exit ;; *) $CMD "$f" "$t".exe; exit ;; esac ;; esac ;; esac $CMD "$@" ksh-1.0.0-beta.2/src/cmd/INIT/filter.sh000066400000000000000000000061751415700074400172770ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : convert command that operates on file args to pipeline filter (command set -o posix) 2>/dev/null && set -o posix command=filter TMPDIR=${TMPDIR:-/tmp} export TMPDIR tmp=$TMPDIR/$command$$ suf= case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) ARGV0="-a $command" USAGE=$' [-? @(#)$Id: filter (AT&T Labs Research) 2001-05-31 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 1994-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?filter - run a command in stdin/stdout mode] [+DESCRIPTION?\bfilter\b runs \acommand\a in a mode that takes input from the \afile\a operands, or from the standard input if no \afile\a operands are specified, and writes the results to the standard output. It can be used to run commands like \bsplit\b(1), that normally modify \afile\a operands in-place, in pipelines. The \afile\a operands are not modified; \acommand\a is run on copies in \b/tmp\b.] command [ option ... ] [ file ... ] [+SEE ALSO?\bstrip\b(1)] ' ;; *) ARGV0="" USAGE="command [ option ... ] [ file ... ]" ;; esac usage() { OPTIND=0 getopts $ARGV0 "$USAGE" OPT '-?' exit 2 } while getopts $ARGV0 "$USAGE" OPT do case $OPT in *) usage ;; esac done shift `expr $OPTIND - 1` case $# in 0) usage ;; esac cmd=$1 while : do shift case $# in 0) break ;; esac case $1 in -*) cmd="$cmd $1" ;; *) break ;; esac done trap 'rm -f $tmp$suf' 0 1 2 3 15 case $# in 0) cat > $tmp $cmd $tmp ;; *) for file do suf=${file##*/} case $suf in *.*) suf=.${suf#*.} ;; *) suf= ;; esac cp $file $tmp$suf || exit 1 chmod u+rwx $tmp$suf || exit 1 $cmd $tmp$suf || exit 1 cat $tmp$suf rm -f $tmp$suf done ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/gdbm.c000066400000000000000000000031351415700074400165240ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -lgdbm */ #define _hdr_gdbm_ndbm 1 #if _hdr_gdbm_ndbm #include #endif int main() { DBM* dbm = 0; dbm_close(dbm); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/gdbm1.c000066400000000000000000000031351415700074400166050ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -lgdbm */ #define _hdr_gdbm_ndbm 1 #if _hdr_gdbm_ndbm #include #endif int main() { DBM* dbm = 0; dbm_close(dbm); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/gdbm2.c000066400000000000000000000031151415700074400166040ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -lgdbm */ #define _hdr_ndbm 1 #if _hdr_ndbm #include #endif int main() { DBM* dbm = 0; dbm_close(dbm); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/hello.c000066400000000000000000000030351415700074400167150ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #ifndef printf #include #endif int main() { int new = 0; printf("hello world\n"); return new;} ksh-1.0.0-beta.2/src/cmd/INIT/hosttype.tst000066400000000000000000000006161415700074400200630ustar00rootroot00000000000000hp.pa hostname 9000/730 hp9000s700 HP-UX hostname A.09.01 A linux-aout.i386 hostname i586 i386 linux hostname 1.1.59 #1 sgi.mips2 hostname.domain IP22 mips IRIX hostname 5.2 02282016 osf.alpha hostname.domain alpha alpha OSF1 hostname.domain V3.2 62 sun4 hostname.domain sun4 sparc SunOS hostname.domain 4.1.1 1 sun4c sol.sun4 hostname.domain sun4 sparc SunOS hostname.domain 5.4 Generic_101945-13 ksh-1.0.0-beta.2/src/cmd/INIT/iconv.c000066400000000000000000000030161415700074400167270ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #ifndef iconv #include #endif int main() { iconv(0, 0, 0, 0, 0); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/iffe.sh000066400000000000000000003211731415700074400167210ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2012 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## # Glenn Fowler & Phong Vo # AT&T Research # # test if feature exists # this script is written to make it through all sh variants # # NOTE: .exe a.out suffix and [\\/] in path patterns for DOS/NT (command set -o posix) 2>/dev/null && set -o posix case `uname -s` in AIX) unset LIBPATH ;; esac command=iffe version=2021-12-06 compile() # $cc ... { "$@" 2>$tmp.err _compile_status=$? if test -s $tmp.err then cat $tmp.err >&2 case $_compile_status in [1-9]|[1-9][0-9]|1[01][0-9]|12[0-7]) if egrep -i -c 'terminated with signal|core dump|segmentation fault' $tmp.err >&$nullout then _compile_status=139 fi ;; esac fi case $_compile_status in ?|??|1[01]?|12[0-8]|25?) ;; *) echo "$command: $@" >&$stderr cat $tmp.err >&$stderr echo "$command: $1: core dump or fatal interruption -- results inconclusive" >&$stderr exit $_compile_status ;; esac return $_compile_status } is_hdr() # [ - ] [ file.c ] hdr { case $1 in -) _is_hdr_flag=-; shift ;; *) _is_hdr_flag= ;; esac case $1 in *.c) _is_hdr_file=$1; shift ;; *) _is_hdr_file=$tmp.c ;; esac is hdr $1 compile $cc -c $_is_hdr_file <&$nullin >&$nullout 2>$tmp.e _is_hdr_status=$? case $_is_hdr_status in 0) if test -s $tmp.e then case `grep '#.*error' $tmp.e` in ?*) _is_hdr_status=1 ;; esac fi ;; esac case $_is_hdr_status in 0) success $_is_hdr_flag ;; *) case $debug in 3) cat $tmp.e >&$stderr ;; esac failure $_is_hdr_flag ;; esac return $_is_hdr_status } pkg() # package { case $1 in '') # Determine default system path, store in $pth. pth=` PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH exec getconf PATH 2>/dev/null ` case $pth in '' | [!/]* | *:[!/]* | *: ) pth="/bin /usr/bin /sbin /usr/sbin" ;; *:*) pth=`echo "$pth" | sed 's/:/ /g'` ;; esac # Fix for NixOS. Not all POSIX standard utilities come with the default system, # e.g. 'bc', 'file', 'vi'. The command that NixOS recommends to get missing # utilities, e.g. 'nix-env -iA nixos.bc', installs them in a default profile # directory that is not in $(getconf PATH). So add this path to the standard path. # See: https://github.com/NixOS/nixpkgs/issues/65512 if test -e /etc/NIXOS && nix_profile_dir=/nix/var/nix/profiles/default/bin && test -d "$nix_profile_dir" then case " $pth " in *" $nix_profile_dir "* ) # nothing to do ;; * ) # insert the default profile directory as the second entry pth=` set $pth one=$1 shift echo "$one $nix_profile_dir${1+ }$@" ` ;; esac fi # Fix for AIX. At least as of version 7.1, the system default 'find', 'diff -u' and 'patch' utilities # are broken and/or non-compliant in ways that make them incompatible with POSIX 2018. However, GNU # utilities are commonly installed in /opt/freeware/bin, and under standard names (no g- prefix). if test -d /opt/freeware/bin then case `uname` in AIX ) pth="/opt/freeware/bin $pth" ;; esac fi return ;; '<') shift ;; *) return ;; esac case $1 in X|X11*) i="openwin" case $1 in X) set X11 ;; esac case $1 in X11) case $# in 1) set $1 6 5 4 ;; esac ;; esac ;; *) i= ;; esac pth="{ usr . - . contrib local $i - . share - . lib - $1" i=$1 while : do shift case $# in 0) break ;; esac case $1 in '>') shift; break ;; esac pth="$pth ${i}R$1 ${i}.$1" done pth="$pth . } $*" } is() # op name { case $verbose in 1) case $complete in 1) failure ;; esac oo=$1 shift case $1 in ?*) yy=is ii=$1 complete=1 case $oo in cmd) mm="a command" ;; dat) mm="a library data symbol" ;; dfn) mm="a macro with extractable value" ;; exp) mm="true" ;; hdr) mm="a header" ;; id) mm="an identifier" ;; lcl) mm="a native header" ;; key) mm="a reserved keyword" ;; lib) mm="a library function" ;; LIB) case $2 in "") mm="a library" ;; *) ii=$*; mm="a library group" ;; esac ;; mac) mm="a macro" ;; mem) mm="a member of $2" ;; mth) mm="a math library symbol" ;; nos) mm="a non-opaque struct" ;; npt) mm="a symbol that needs a prototype" ;; num) mm="a numeric constant or enum" ;; nxt) mm="an include path for the native header" ;; opt) mm="set in \$PACKAGE_OPTIONS" ;; pth) mm="a file" ;; run) yy="capture output of" mm= ;; siz) mm="a type with known size" ;; sym) mm="a typed variable" ;; sys) mm="a system header" ;; typ) mm="a type or typedef" ;; val) yy="determine" mm="value" ;; *) yy= mm= ;; esac case $ii in [abcdefghijklmnopqrstuvwxyz]*[abcdefghijklmnopqrstuvwxyz]'{') ii="$ii ... }end" ;; esac $show "$command: test:" $yy $ii $mm "...$SHOW" >&$stderr complete=1 ;; esac ;; esac } success() { case $1 in -) shift ;; *) case $result in UNKNOWN) result=SUCCESS ;; esac case $1 in +) return ;; esac ;; esac case $complete:$verbose in 1:1) case $suspended in 1) suspended=0 $show "$command: test:" $yy $ii $mm "...$SHOW" >&$stderr ;; esac complete=0 case $# in 0) mm="yes" ;; *) mm="'$*'" ;; esac case $debug in 0) echo " $mm" >&$stderr ;; *) echo "$command: ... $mm" >&$stderr ;; esac ;; esac } failure() { case $1 in -) shift ;; *) result=FAILURE case $1 in +) return ;; esac ;; esac case $complete:$verbose in 1:1) case $suspended in 1) suspended=0 $show "$command: test:" $yy $ii $mm "...$SHOW" >&$stderr ;; esac complete=0 case $group in '') case $# in 0) mm="no" ;; *) mm=$* ;; esac ;; *) mm= ;; esac case $debug in 0) echo " $mm" >&$stderr ;; *) echo "$command: ... $mm" >&$stderr ;; esac ;; esac } # report # # - ignore global status # -0 normal sense # -1 inverted sense if ! def # status test status 0:success *:failure # success success comment # failure failure comment # default default setting comment # # globals # # $not invert test sense # $M test variable # $m test macro # $v default macro report() # [-] [-0] [-1] status value success failure default { case $1 in -) _report_ignore=$1 shift ;; *) _report_ignore= ;; esac _report_not=$not case $1 in -0) shift ;; -1) shift case $def in ''|-) case $_report_not in 1) _report_not= ;; *) _report_not=1 ;; esac ;; esac ;; esac _report_status=$1 case $_report_ignore:$_report_status in -:*) ;; *:0) success $_report_ignore ;; *) failure $_report_ignore case $group in ?*) return ;; esac ;; esac _report_value=$2 case $_report_not in 1) case $_report_status in 0) _report_status=1 ;; *) _report_status=0 ;; esac _report_success=$4 _report_failure=$3 ;; *) _report_success=$3 _report_failure=$4 ;; esac _report_default=$5 case $_report_status in 0) case $M in *-*) ;; *) usr="$usr$nl#define $m $_report_value" case $_report_success in ''|-) ;; *) case $define in 1) echo "#define $m $_report_value /* $_report_success */" ;; n) echo "$m=$_report_value" esac ;; esac eval $m=\'$_report_value\' ;; esac ;; *) case $M in *-*) ;; *) case $_report_failure in ''|-) ;; *) case $define$all$config$undef in 1?1?|1??1)echo "#undef $m /* $_report_failure */" ;; 11??) echo "#define $m 0 /* $_report_failure */" ;; n1?1) echo "$m=" ;; n1??) echo "$m=0" ;; esac ;; esac case $_report_default in ''|-) ;; *) case $define$set in 1?*) echo "#define $v $set /* $_report_default */" ;; n?*) echo "$v=$set" ;; esac ;; esac eval $m=0 ;; esac ;; esac } noisy() { case $complete:$verbose in 1:1) suspended=1 echo >&$stderr ;; esac } here_broken=0 literal() # line that echo might process { if cat <&$stderr ;; esac sh -c "cat <&$stderr ;; esac sh -c "cat < "$1" ;; *) if cat > "$1" <&$stderr ;; esac sh -c "cat > \"$1\" < $tmp.c if compile $cc -c $tmp.c <&$nullin >&$nullout then echo "(;" > $tmp.c if compile $cc -c $tmp.c <&$nullin >&$nullout then cctest="should not compile '(;'" fi else cctest="should compile 'int i = 1;'" fi case $cctest in "") cctest=0 ;; *) echo "$command: $cc: not a C compiler: $cctest" >&$stderr exit 1 ;; esac } checkread() { case $cctest in "") checkcc ;; esac case $posix_read in -no) ;; *) posix_read=`(read -r _checkread_line; echo $_checkread_line) 2>/dev/null <= 0) { if (c == ' ' || c == '\\t') { if (k < sizeof(s)) s[k++] = c; continue; } if (k > 1 && c != '#' && c != '\\n' && c != '\\r') write(1, s + 1, k - 1); k = -1; } if (c == '\\r') { r = c; if (read(0, &c, 1) == 1 && c != '\\n') write(1, &r, 1); } write(1, &c, 1); if (c == '\\n') return 0; } return 1; }" if compile $cc -o ${tmp}r.exe ${tmp}r.c >&$nullout then posix_read=${tmp}r.exe else echo "$command: cannot compile read -r workaround" >&$stderr exit 1 fi ;; esac } execute() { case $verbose in 0) noteout=$nullout ;; *) noteout=$stderr ;; esac if test "" != "$cross" then crossexec $cross "$@" 9>&$noteout _execute_=$? elif test -d /NextDeveloper then "$@" <&$nullin >&$nullout 9>&$noteout _execute_=$? "$@" <&$nullin | cat else "$@" 9>&$noteout _execute_=$? fi return $_execute_ } exclude() { case $excludes in '') return 0 ;; esac for _exclude_var do eval _exclude_old=\$$_exclude_var case $_exclude_old in *" -I"*);; *) continue ;; esac _exclude_new= _exclude_sep= for _exclude_arg in $_exclude_old do _exclude_skip= for _exclude_dir in $excludes do case $_exclude_arg in -I$_exclude_dir|-I*/$_exclude_dir) _exclude_skip=1 break; ;; esac done case $_exclude_skip in '') _exclude_new="$_exclude_new$_exclude_sep$_exclude_arg" _exclude_sep=" " ;; esac done eval $_exclude_var=\$_exclude_new case $debug in 0) ;; *) echo $command: exclude $_exclude_var: "$_exclude_old => $_exclude_new" >&$stderr ;; esac done } all=0 apis= binding="-dy -dn -Bdynamic -Bstatic -Wl,-ashared -Wl,-aarchive -call_shared -non_shared '' -static" complete=0 config=0 defhdr= define=1 explicit=0 iff= usr= cross= debug=0 deflib= dir=FEATURE excludes= executable="test -x" exists="test -e" gothdr= gotlib= idno= idyes= ifs=${IFS-' '} in= includes= intrinsic= libpaths="DYLD_LIBRARY_PATH LD_LIBRARY_PATH LD_LIBRARYN32_PATH LD_LIBRARY64_PATH LIBPATH SHLIB_PATH" DYLD_LIBRARY_PATH_default=:/lib:/usr/lib LD_LIBRARY_PATH_default=:/lib:/usr/lib LD_LIBRARYN32_PATH_default=:/lib32:/usr/lib32 LD_LIBRARY64_PATH_default=:/lib64:/usr/lib64 LIBPATH_default=:/lib:/usr/lib SHLIB_PATH_default=:/shlib:/usr/shlib:/lib:/usr/lib nl=" " optimize=1 occ=cc one= out= posix_read=-check case `(set -f && set x * && echo $# && set +f) 2>/dev/null` in 2) posix_noglob="set -f" posix_glob="set +f" ;; *) case `(set -F && set x * && echo $# && set +F) 2>/dev/null` in 2) posix_noglob="set -F" posix_glob="set +F" ;; *) posix_noglob=":" posix_glob=":" ;; esac ;; esac protoflags= puthdr= putlib= pragma= case `eval 'v=NOposixNO; w=$(export "w=$v"; echo "${w%%NO}"); echo "${w##NO}"' 2>/dev/null` in posix) shell=posix # or at least POSIX-ish case $BASH_VERSION in [1-9]*) shell=bash ;; esac case `eval 'PATH=/dev/null && let i=93-5 && typeset -u v=ksh$i && print -r - "$v"' 2>/dev/null` in KSH88) shell=ksh ;; # also pdksh, mksh, zsh esac ;; *) shell=bsh # ancient pre-POSIX Bourne shell ($executable .) 2>/dev/null || executable='test -r' ($exists .) 2>/dev/null || exists='test -r' ;; esac reallystatic= reallystatictest= regress= static=. statictest= case $COTEMP in "") case $HOSTNAME in ""|?|??|???|????|????) tmp=${HOSTNAME} ;; *) case $shell in bsh) eval `echo $HOSTNAME | sed 's/\\(....\\).*/tmp=\\1/'` ;; *) eval 'tmp=${HOSTNAME%${HOSTNAME#????}}' ;; esac ;; esac tmp=${tmp}$$ ;; *) tmp=x${COTEMP} ;; esac COTEMP=${tmp} export COTEMP case $tmp in ./*) ;; ??????????*) case $shell in bsh) eval `echo $tmp | sed 's/\\(.........\\).*/tmp=\\1/'` ;; *) eval 'tmp=${tmp%${tmp#?????????}}' ;; esac ;; ?????????) ;; ????????) tmp=F$tmp ;; esac case $tmp in ./*) ;; *) tmp=./$tmp ;; esac undef=0 verbose=0 vers= # options -- `-' for output to stdout otherwise usage case $1 in -) out=-; shift ;; esac set= case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) USAGE=$' [-? @(#)$Id: iffe (ksh 93u+m) '${version}$' $ ] [-author?Glenn Fowler ] [-author?Phong Vo ] [-copyright?(c) 1994-2012 AT&T Intellectual Property] [-copyright?(c) 2020-2021 Contributors to https://github.com/ksh93/ksh] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?iffe - C compilation environment feature probe] [+DESCRIPTION?\biffe\b is a command interpreter that probes the C compilation environment for features. A feature is any file, option or symbol that controls or is controlled by the C compiler. \biffe\b tests features by generating and compiling C programs and observing the behavior of the C compiler and generated programs.] [+?\biffe\b statements are line oriented. Statements may appear in the operand list with the \b:\b operand or \bnewline\b as the line delimiter. The standard input is read if there are no command line statements or if \afile\a\b.iffe\b is omitted.] [+?Though similar in concept to \bautoconf\b(1) and \bconfig\b(1), there are fundamental differences. The latter tend to generate global headers accessed by all components in a package, whereas \biffe\b is aimed at localized, self contained feature testing.] [+?Output is generated in \bFEATURE/\b\atest\a by default, where \atest\a is the base name of \afile\a\b.iffe\b or the \biffe\b \brun\b file operand. Output is first generated in a temporary file; the output file is updated if it does not exist or if the temporary file is different. If the first operand is \b-\b then the output is written to the standard output and no update checks are done.] [+?Files with suffixes \b.iffe\b and \b.iff\b are assumed to contain \biffe\b statements.] [a:all?Define failed test macros \b0\b. By default only successful test macros are defined \b1\b.] [c:cc?Sets the C compiler name and flags to be used in the feature tests.]:[C-compiler-name [C-compiler-flags ...]]] [C:config?Generate \bconfig\b(1) style \aHAVE_\a* macro names. This implies \b--undef\b. Since \bconfig\b(1) has inconsistent naming conventions, the \bexp\b op may be needed to translate from the (consistent) \biffe\b names. Unless otherwise noted a \bconfig\b macro name is the \biffe\b macro name prefixed with \bHAVE\b and converted to upper case. \b--config\b is set by default if the command arguments contain a \brun\b op on an input file with the base name \bconfig\b.] [d:debug?Sets the debug level. Level 0 inhibits most error messages, level 1 shows compiler messages, and level 2 traces internal \biffe\b \bsh\b(1) actions and does not remove core dumps on exit.]#[level] [D:define?Successful test macro definitions are emitted. This is the default.] [E:explicit?Disable implicit test output.] [F:features?Sets the feature test header to \ahdr\a. This header typically defines *_SOURCE feature test macros.]:[hdr:=NONE] [i:input?Sets the input file name to \afile\a, which must contain \biffe\b statements.]:[file] [I:include?Adds \b-I\b\adir\a to the C compiler flags.]:[dir] [L:library?Adds \b-L\b\adir\a to the C compiler flags.]:[dir] [n:name-value?Output \aname\a=\avalue\a assignments only.] [N!:optimize?\b--nooptimize\b disables compiler optimization options.] [o:output?Sets the output file name to \afile\a.]:[file] [O:stdio?Sets the standard io header to \ahdr\a.]:[hdr:=stdio.h] [e:package?Sets the \bproto\b(1) package name to \aname\a.]:[name] [p:prototyped?Emits \b#pragma prototyped\b at the top of the output file. See \bproto\b(1).] [P:pragma?Emits \b#pragma\b \atext\a at the top of the output file.]:[text] [r:regress?Massage output for regression testing.] [s:shell?Sets the internal shell name to \aname\a. Used for debugging Bourne shell compatibility (otherwise \biffe\b uses \aksh\a constructs if available). The supported names are \bksh\b, \bbsh\b, \bbash\b, and \bosh\b. \bosh\b forces the \bread -r\b compatibility read command to be compiled and used instead of \bread -r\b. The default is determined by probing the shell at startup.]:[name] [S:static?Sets the C compiler flags that force static linking. If not set then \biffe\b probes the compiler to determine the flags. \biffe\b must use static linking (no dlls) because on some systems missing library symbols are only detected when referenced at runtime from dynamically linked executables.]:[flags] [u:undef?\b#undef\b failed test macros. By default only successful test macros are defined \b1\b.] [v:verbose?Produce a message line on the standard error for each test as it is performed.] [x:cross?Some tests compile an executable (\ba.out\b) and then run it. If the C compiler is a cross compiler and the executable format is incompatible with the execution environment then the generated executables must be run in a different environment, possibly on another host. \acrosstype\a is the HOSTTYPE for generated executables (the \bpackage\b(1) command generates a consistent HOSTTYPE namespace). Generated executables are run via \bcrossexec\b(1) with \acrosstype\a as the first argument. \bcrossexec\b supports remote execution for cross-compiled executables. See \bcrossexec\b(1) for details.]:[crosstype] [X:exclude?Removes \b-I\b\adir\a and \b-I\b*/\adir\a C compiler flags.]:[dir] [ - ] [ file.iffe | statement [ : statement ... ] ] [+SYNTAX?\biffe\b input consists of a sequence of statement lines. Statements that span more than one line contain \abegin\a\b{\b as the last operand (where \abegin\a is command specific) and zero or more data lines terminated by a line containing \b}end\b as the first operand. The statement syntax is: [\aname\a \b=\b]] [\b!\b]] \atest\a[,\atest\a...]] [\b-\b]] [\aarg\a[,\aarg\a...]]]] [\aprereq\a ...]] [\abegin\a{ ... |\bend\b ...]] [= [\adefault\a]]]]. \atest\as and \aarg\as may be combined, separated by commas, to perform a set of tests on a set of arguments. \aname\a \b=\b before \atest\a overrides the default test variable and macro name, and \b-\b after \atest\a performs the test but does not define the test variable and macro values. \b!\b before \atest\a inverts the test sense for \bif\b, \belif\b, and \byes{\b and \bno{\b blocks.] [+?\aprereq\as are used when applying the features tests and may be combinations of:]{ [+compiler options?\b-D\b*, \b-L\b*, etc.] [+library references?\b-l\b*, *\b.a\b, etc. \b_LIB_\b\aname\a is defined to be 1 if \b-l\b\aname\a is a library.] [+header references?*\b.h\b. \a_dir_name\a is defined to be 1 if \adir/name\a\b.h\b is a header, or if \adir\a is omitted, \b_hdr_\b\aname\a is defined to be 1 if \aname\a\b.h\b is a header.] [+-?Prereq grouping mark; prereqs before the first \b-\b are passed to all feature tests. Subsequent groups are attempted in left-to-right order until the first successful group is found.] } [+?\abegin\a\b{\b ... \b}end\b delimit multiline code blocks that override or augment the default code provided by \biffe\b. User supplied code blocks should be compatible with the K&R, ANSI, and C++ C language dialects for maximal portability. Test code may call the function \bNOTE("...")\b to emit short text in \b--verbose\b output; only one \bNOTE()\b should be called per test for readability. In addition to all macro definitions generated by previous tests, all generated code contains the following at the top to hide dialect differences:]{ [+ ?#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)] [+ ?#define _STD_ 1] [+ ?#define _ARG_(x) x] [+ ?#define _VOID_ void] [+ ?#else] [+ ?#define _STD_ 0] [+ ?#define _ARG_(x) ()] [+ ?#define _VOID_ char] [+ ?#endif] [+ ?#if defined(__cplusplus)] [+ ?#define _BEGIN_EXTERNS_ extern "C" {] [+ ?#define _END_EXTERNS_ }] [+ ?#else] [+ ?#define _BEGIN_EXTERNS_] [+ ?#define _END_EXTERNS_] [+ ?#endif] [+ ?#define _NIL_(x) ((x)0)] [+ ?#include /* unless changed using the "stdio" option */] } [+?In addition, if and when available, standards macros set as a result of the \bsrc/lib/libast/features/standards\b feature test are incorporated here, ensuring the compilation environment is consistent between the tests and the code that uses the test results.] [+?= \adefault\a may be specified for the \bkey\b, \blib\b, \bmac\b, \bmth\b and \btyp\b tests. If the test fails for \aarg\a then \b#define\b \aarg\a \adefault\a is emitted. \bkey\b accepts multiple \b= \b\adefault\a values; the first valid one is used.] [+?Each test statement generates a portion of a C language header that contains macro definitions, comments, and other text corresponding to the feature tests. \b#ifndef _def_\b\aname\a\b_\b\adirectory\a ... \b#endif\b guards the generated header from multiple \b#include\bs, where \aname\a is determined by either the \brun\b statement input file name if any, or the first \atest\a in the first statement, and \adirectory\a is the basename component of either the \brun\b statement file, if any, or the current working directory. The output file name is determined in this order:]{ [+-?If the first command line operand is \b-\b then the output is written to the standard output.] [+--output=\afile\a?Output is \afile\a.] [+set out \afile\a?Output is \afile\a.] [+[run]] [\adirectory\a/]]\abase\a[\a.suffix\a]]?Output is \bFEATURE/\b\abase\a.] } [+?Generated \biffe\b headers are often referenced in C source as: \b#include "FEATURE/\b\afile\a". The \bnmake\b(1) base rules contain metarules for generating \bFEATURE/\b\afile\a from \bfeatures/\b\afile\a[\asuffix\a]], where \asuffix\a may be omitted, \b.c\b, or \b.sh\b (see the \brun\b test below). Because \b#include\b prerequisites are automatically detected, \bnmake\b(1) ensures that all prerequisite \biffe\b headers are generated before compilation. Note that the directories are deliberately named \bFEATURE\b and \bfeatures\b to keep case-ignorant file systems happy.] [+?The feature tests are:]{ [+# \acomment\a?Comment line - ignored.] [+api \aname\a \aYYYYMMDD\a \asymbol ...\a?Emit API compatibility tests for \aname\a and \b#define\b \asymbol\a \asymbol\a_\aYYYYMMDD\a when \aNAME\a_API is >= \aYYYYMMDD\a (\aNAME\a is \aname\a converted to upper case). If \aNAME\a_API is not defined then \asymbol\a maps to the newest \aYYYYMMDD\a for \aname\a.] [+define \aname\a [ (\aarg,...\a) ]] [ \avalue\a ]]?Emit a macro \b#define\b for \aname\a if it is not already defined. The definition is passed to subsequent tests.] [+extern \aname\a \atype\a [ (\aarg,...\a) | [\adimension\a]] ]]?Emit an \bextern\b prototype for \aname\a if one is not already defined. The prototype is passed to subsequent tests.] [+header \aheader\a?Emit \b#include <\b\aheader\a\b>\b if \aheader\a exists. The \b#include\b is passed to subsequent tests.] [+print \atext\a?Copy \atext\a to the output file. \atext\a is passed to subsequent tests.] [+reference \aheader\a?If \aheader\a exists then add \b#include\b \aheader\a to subsequent tests.] [+ver \aname\a \aYYYYMMDD\a?\b#define\b \aNAME\a_VERSION \aYYYYMMDD\a (\aNAME\a is \aname\a converted to upper case).] [+cmd \aname\a?Defines \b_cmd_\b\aname\a if \aname\a is an executable in one of the standard system directories (as output by \bgetconf PATH\b). \b_\b\adirectory\a\b_\b\aname\a is defined for \adirectory\a in which \aname\a is found (with \b/\b translated to \b_\b).] [+dat \aname\a?Defines \b_dat_\b\aname\a if \aname\a is a data symbol in the default libraries.] [+def \aname\a?Equivalent to \bcmd,dat,hdr,key,lib,mth,sys,typ\b \aname\a.] [+dfn \aname\a?If \aname\a is a macro in the candidate headers then a \b#define\b \aname\a \avalue\a statement is output for the \avalue\a defined in the headers. The definition is \b#ifndef\b guarded.] [+exp \aname\a \aexpression\a?If \aexpression\a is a \"...\" string then \aname\a is defined to be the string, else if the \bexpr\b(1) evaluation of \aexpression\a is not 0 then \aname\a is defined to be 1, otherwise \aname\a is defined to be 0. Identifiers in \aexpression\a may be previously defined names from other \biffe\b tests; undefined names evaluate to 0. If \aname\a was defined in a previous successful test then the current and subsequent \bexp\b test on \aname\a are skipped. If \aname\a is \b-\b then the \aexpression\a is simply evaluated.] [+hdr \aname\a?Defines \b_hdr_\b\aname\a if the header \b<\b\aname\a\b.h>\b exists. The \b--config\b macro name is \bHAVE_\b\aNAME\a\b_H\b.] [+if \astatement\a ... | \belif\b \astatement\a ... | \belse\b | \bendif\b? Nested if-else test control.] [+iff \aname\a?The generated header \b#ifndef-#endif\b macro guard is \b_\b\aname\a\b_H\b.] [+inc \afile\a [ re ]]?Read #define macro names from \afile\a and arrange for those names to evaluate to 1 in \bexp\b expressions. If \are\a is specified then macros not matching \are\a are ignored.] [+key \aname\a?Defines \b_key_\b\aname\a if \aname\a is a reserved word (keyword).] [+lcl \aname\a?Generates a \b#include\b statement for the native version of the header \b<\b\aname\a\b.h>\b if it exists. Defines \b_lcl_\b\aname\a on success. The \b--config\b macro name is \bHAVE_\b\aNAME\a\b_H\b. The default \are\a is \b^HAVE_\b for \b--config\b and \b^_\b otherwise.] [+lib \aname\a?Defines \b_lib_\b\aname\a if \aname\a is an external symbol in the default libraries.] [+mac \aname\a?Defines \b_mac_\b\aname\a if \aname\a is a macro.] [+mem \astruct.member\a?Defines \b_mem_\b\amember\a\b_\b\astruct\a if \amember\a is a member of the structure \astruct\a.] [+mth \aname\a?Defines \b_mth_\b\aname\a if \aname\a is an external symbol in the math library.] [+nop \aname\a?If this is the first test then \aname\a may be used to name the output file and/or the output header guard macro. Otherwise this test is ignored.] [+npt \aname\a?Defines \b_npt_\b\aname\a if the \aname\a symbol requires a prototype. The \b--config\b macro name is \bHAVE_\aNAME\a\b_DECL\b with the opposite sense.] [+num \aname\a?Defines \b_num_\b\aname\a if \aname\a is a numeric constant \aenum\a or \amacro\a.] [+nxt \aname\a?Defines a string macro \b_nxt_\b\aname\a suitable for a \b#include\b statement to include the next (on the include path) or native version of the header \b<\b\aname\a\b.h>\b if it exists. Also defines the \"...\" form \b_nxt_\b\aname\a\b_str\b. The \b--config\b macro name is \bHAVE_\b\aNAME\a\b_NEXT\b.] [+one \aheader\a ...?Generates a \b#include\b statement for the first header found in the \aheader\a list.] [+opt \aname\a?Defines \b_opt_\b\aname\a if \aname\a is a space-separated token in the global environment variable \bPACKAGE_OPTIONS\b.] [+pth \afile\a [ \adir\a ... | { \ag1\a - ... - \agn\a } | < \apkg\a [\aver\a ...]] > ]]?Defines \b_pth_\b\afile\a, with embedded \b/\b chars translated to \b_\b, to the path of the first instance of \afile\a in the \adir\a directories. \b{\b ... \b}\b forms a directory list from the cross-product of \b-\b separated directory groups \ag1\a ... \agn\a. < ... > forms a directory list for the package \apkg\a with optional versions. If no operands are specified then the default PATH directories are used. The \b--config\b macro name is \aNAME\a\b_PATH\b.] [+run \afile\a?Runs the tests in \afile\a based on the \afile\a suffix:]{ [+.c?\afile\a is compiled and executed and the output is copied to the \biffe\b output file. Macros and headers supplied to \bbegin{\b ... \b}end\b are also supplied to \afile\a.] [+.sh?\afile\a is executed as a shell script and the output is copied to the \biffe\b output file.] [+.iffe \bor no suffix?\afile\a contains \biffe\b statements.] } [+set \aoption value\a?Sets option values. The options are described above.] [+siz \aname\a?Defines \b_siz_\b\aname\a to be \bsizeof\b(\aname\a) if \aname\a is a type in any of \b, , , \b. Any \b.\b characters in \aname\a are translated to space before testing and are translated to \b_\b in the output macro name.] [+sym \aname\a?Defines \b_ary_\b\aname\a if \aname\a is an array, \b_fun_\b\aname\a if \aname\a is a function pointer, \b_ptr_\b\aname\a if \aname\a is a pointer, or \b_reg_\b\aname\a if \aname\a is a scalar. In most cases \aname\a is part of a macro expansion.] [+sys \aname\a?Defines \b_sys_\b\aname\a if the header \b\b exists. The \b--config\b macro name is \bHAVE_SYS_\b\aNAME\a\b_H\b.] [+tst \aname\a?A user defined test on name. A source block must be supplied. Defines \b_\b\aname\a on success. \btst - ...\b is treated as \btst - - ...\b.] [+typ \aname\a?Defines \b_typ_\b\aname\a if \aname\a is a type in any of \b, , , \b. Any \b.\b characters in \aname\a are translated to space before testing and are translated to \b_\b in the output macro name.] [+val \aname\a?The output of \becho\b \aname\a is written to the output file.] [+var \aname\a?A user defined test on name. A source block must be supplied. Sets the \bexp\b variable \b_\b\aname\a on success but does not define a macro.] [+(\aexpression\a)?Equivalent to \bexp -\b \aexpression\a.] } [+?Code block names may be prefixed by \bno\b to invert the test sense. The block names are:]{ [+cat?The block is copied to the output file.] [+compile?The block is compiled (\bcc -c\b).] [+cross?The block is executed as a shell script using \bcrossexec\b(1) if \b--cross\b is on, or on the local host otherwise, and the output is copied to the output file. Test macros are not exported to the script.] [+execute?The block is compiled, linked, and executed. \b0\b exit status means success.] [+fail?If the test fails then the block text is evaluated by \bsh\b(1).] [+link?The block is compiled and linked (\bcc -o\b).] [+macro?The block is preprocessed (\bcc -E\b) and lines containing text bracketed by \b<<"\b ... \b">>\b (\aless-than\a \aless-than\a \adouble-quote\a ... \adouble-quote\a \agreater-than\a \agreater-than\a) are copied to the output file with the brackets omitted.] [+no?If the test fails then the block text is copied to the output file. Deprecated: use { \bif\b \belif\b \belse\b \bendif\b } with unnamed \b{\b ... \b}\b blocks.] [+note?If the test succeeds then the block is copied to the output as a \b/*\b ... \b*/\b comment.] [+output?The block is compiled, linked, and executed, and the output is copied to the output file.] [+pass?If the test succeeds then the block text is evaluated by \bsh\b(1).] [+preprocess?The block is preprocessed (\bcc -E\b).] [+run?The block is executed as a shell script and the output is copied to the output file. Successful test macros are also defined as shell variables with value \b1\b and are available within the block. Likewise, failed test macros are defined as shell variables with value \b0\b.] [+status?The block is compiled, linked, and executed, and the exit status is the test outcome, 0 for \afailure\a, the value otherwise.] [+yes?If the test succeeds then the block text is copied to the output file. \byes{\b ... \b}end\b is equivalent to the unnamed block \b{\b ... \b}\b. Deprecated: use { \bif\b \belif\b \belse\b \bendif\b } with unnamed \b{\b ... \b}\b blocks.] } [+SEE ALSO?\bautoconf\b(1), \bconfig\b(1), \bgetconf\b(1), \bcrossexec\b(1), \bnmake\b(1), \bpackage\b(1), \bproto\b(1), \bsh\b(1)] ' while getopts -a "$command" "$USAGE" OPT do case $OPT in a) set="$set set all :" ;; c) set="$set set cc $OPTARG :" ;; C) set="$set set config :" ;; d) set="$set set debug $OPTARG :" ;; D) set="$set set define :" ;; E) set="$set set explicit :" ;; F) set="$set set features $OPTARG :" ;; i) set="$set set input $OPTARG :" ;; I) set="$set set include $OPTARG :" ;; L) set="$set set library $OPTARG :" ;; n) set="$set set namval $OPTARG :" ;; N) set="$set set nooptimize $OPTARG :" ;; o) set="$set set output $OPTARG :" ;; e) set="$set set package $OPTARG :" ;; p) set="$set set prototyped :" ;; P) set="$set set pragma $OPTARG :" ;; r) set="$set set regress :" ;; s) set="$set set shell $OPTARG :" ;; S) set="$set set static $OPTARG :" ;; O) set="$set set stdio $OPTARG :" ;; u) set="$set set undef :" ;; v) set="$set set verbose :" ;; x) set="$set set cross $OPTARG :" ;; X) set="$set set exclude $OPTARG :" ;; esac done shift `expr $OPTIND - 1` ;; *) while : do case $# in 0) break ;; esac case $1 in -) break ;; --) shift break ;; --a|--al|--all) REM=a ;; --cc=*) REM=c`echo X$1 | sed 's,[^=]*=,,'` ;; --co|--con|--conf|--confi|--config) REM=C ;; --cr=*|--cro=*|--cros=*|--cross=*) REM=x`echo X$1 | sed -e 's,[^=]*=,,'` ;; --d=*|--de=*|--deb=*|--debu=*|--debug=*) REM=d`echo X$1 | sed 's,[^=]*=,,'` ;; --def|--defi|--defin|--define) REM=D ;; --e=*|--ex=*|--exc=*|--excl=*|--exclu=*|--exclud=*|--exclude=*) REM=X`echo X$1 | sed 's,[^=]*=,,'` ;; --e|--ex|--exp|--expl|--expli|--explic|--explici|--explicit) REM=E ;; --f=*|--fe=*|--fea=*|--feat=*|--featu=*|--featur=*|--feature=*|--features=*) REM=F`echo X$1 | sed 's,[^=]*=,,'` ;; --inp=*|--inpu=*|--input=*) REM=i`echo X$1 | sed 's,[^=]*=,,'` ;; --inc=*|--incl=*|--inclu=*|--includ=*|--include=*) REM=I`echo X$1 | sed 's,[^=]*=,,'` ;; --l=*|--li=*|--lib=*|--libr=*|--libra=*|--librar=*|--library=*) REM=L`echo X$1 | sed 's,[^=]*=,,'` ;; --n|--na|--nam|--name|--name-v|--name-va|--name-val|--name-valu|--name-value) REM=n ;; --o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*) REM=o`echo X$1 | sed 's,[^=]*=,,'` ;; --pa=*|--pac=*|--pack=*|--packa=*|--packag=*|--package=*) REM=e`echo X$1 | sed 's,[^=]*=,,'` ;; --pro|--prot|--proto|--protot|--prototy|--prototyp|--prototype|--prototyped) REM=p ;; --pra=*|--prag=*|--pragma=*) REM=P`echo X$1 | sed 's,[^=]*=,,'` ;; --r|--re|--reg|--regre|--regres|--regress) REM=r ;; --sh=*|--she=*|--shel=*|--shell=*) REM=s`echo X$1 | sed 's,[^=]*=,,'` ;; --sta=*|--stat=*|--stati=*|--static=*) REM=S`echo X$1 | sed 's,[^=]*=,,'` ;; --std=*|--stdi=*|--stdio=*) REM=O`echo X$1 | sed 's,[^=]*=,,'` ;; --u|--un|--und|--unde|--undef) REM=u ;; --v|--ve|--ver|--verb|--verbo|--verbos|--verbose) REM=v ;; --*) echo $command: $1: unknown option >&2 exit 2 ;; -*) REM=`echo X$1 | sed 's,X-,,'` ;; *) break ;; esac shift while : do case $REM in '') break ;; esac eval `echo $REM | sed "s,\(.\)\(.*\),OPT='\1' REM='\2',"` case $OPT in [cdFiILoOePsSxX]) case $REM in '') case $# in 0) echo $command: -$OPT: option argument expected >&2 exit 1 ;; esac OPTARG=$1 shift ;; *) OPTARG=$REM REM='' ;; esac esac case $OPT in a) set="$set set all :" ;; c) set="$set set cc $OPTARG :" ;; C) set="$set set config :" ;; d) set="$set set debug $OPTARG :" ;; D) set="$set set define :" ;; E) set="$set set explicit :" ;; F) set="$set set features $OPTARG :" ;; i) set="$set set input $OPTARG :" ;; I) set="$set set include $OPTARG :" ;; L) set="$set set library $OPTARG :" ;; n) set="$set set namval $OPTARG :" ;; N) set="$set set nooptimize $OPTARG :" ;; o) set="$set set output $OPTARG :" ;; e) set="$set set package $OPTARG :" ;; p) set="$set set prototyped :" ;; P) set="$set set pragma $OPTARG :" ;; r) set="$set set regress :" ;; s) set="$set set shell $OPTARG :" ;; S) set="$set set static $OPTARG :" ;; O) set="$set set stdio $OPTARG :" ;; u) set="$set set undef :" ;; v) set="$set set verbose :" ;; x) set="$set set cross $OPTARG :" ;; X) set="$set set exclude $OPTARG :" ;; *) echo "Usage: $command [-aCDEnpruv] [-c C-compiler-name [C-compiler-flags ...]] [-d level] [-F features-header] [-i file] [-o file] [-O stdio-header] [-e name] [-P text] [-s shell-path] [-S[flags]] [-x cross-exec-prefix] [-I dir] [-L dir] [-X dir] [ - ] [ file.iffe | statement [ : statement ... ] ]" >&2 exit 2 ;; esac done done ;; esac case $1 in -) out=-; shift ;; esac case $# in 0) in=- ;; esac set -- $set "$@" case " $* " in *' set config '*|*' run config.'*|*' run '*' config.'*|*' run '*'/config.'*) config=1 ;; esac # standard error to /dev/null unless debugging # standard output to the current output file # # stdout original standard output # stderr original standard error # nullin /dev/null input # nullout /dev/null output stdout=5 stderr=6 nullin=7 nullout=8 eval "exec $nullin/dev/null $stdout>&1 $stderr>&2" case " $* " in *" set debug "[3456789]*) ;; *) eval "exec 2>&$nullout" ;; esac # prompt complications case `print -n aha /dev/null` in aha) show='print -n' SHOW='' ;; *) case `echo -n aha 2>/dev/null` in -n*) show=echo SHOW='\c' ;; *) show='echo -n' SHOW='' ;; esac ;; esac # tmp files cleaned up on exit # status: 0:success 1:failure 2:interrupt status=1 case $debug in 2) core= ;; *) if (ulimit -c 0) >/dev/null 2>&1 then ulimit -c 0 core= else core="core core.??*" fi ;; esac trap "rm -f $core $tmp*" 0 if (:>$tmp.c) 2>/dev/null then rm -f $tmp.c else echo "$command: cannot create tmp files in current dir" >&2 exit 1 fi status=2 # standard header for c source std='#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) #define _STD_ 1 #define _ARG_(x) x #define _VOID_ void #else #define _STD_ 0 #define _ARG_(x) () #define _VOID_ char #endif #if defined(__cplusplus) #define _BEGIN_EXTERNS_ extern "C" { #define _END_EXTERNS_ } #else #define _BEGIN_EXTERNS_ #define _END_EXTERNS_ #endif #define _NIL_(x) ((x)0)' # To ensure the environment tested is the same as that used, add standards # compliance macros as probed by libast as soon as they are available. if test -f "${INSTALLROOT}/src/lib/libast/FEATURE/standards" then std=${std}${nl}`cat "${INSTALLROOT}/src/lib/libast/FEATURE/standards"` fi tst= ext="#include " # loop on op [ arg [ ... ] ] [ : op [ arg [ ... ] ] ] argx=0 cur=. can= cansep= cctest= file= hdrtest= ifelse=NONE ifstack= ini= init=1 line=0 nan= prototyped= while : do case $in in "") case $argx:$* in 1:$argv);; 1:*) argx=0 set x $argv shift ;; esac ;; *) case $ini in '') if read lin then case $shell in ksh) let line=line+1 ;; *) line=`expr $line + 1` ;; esac $posix_noglob set x $lin $posix_glob case $# in 1) continue ;; esac else set x fi ;; *) $posix_noglob set x $ini $posix_glob ini= ;; esac shift case $init in 1) case $1 in iff) init=0 ;; print|ref|set) ;; *) init=0 ini=$* set ini ;; esac esac ;; esac case $# in 0) case $ifstack in ?*) echo "$command: $file$line: missing endif" >&$stderr exit 1 ;; esac set set out + ;; esac # if nesting while : do case $1 in "if") ifstack="$ifelse:$ifstack" case $ifelse in KEEP|NONE) ifelse=TEST ;; TEST) ;; *) ifelse=DONE ;; esac shift case $explicit in 1) set '' - "$@"; shift ;; esac ;; "elif") case $ifelse in SKIP) ifelse=TEST ;; TEST) ;; *) ifelse=DONE ;; NONE) echo "$command: $file$line: $1: no matching if" >&$stderr exit 1 ;; esac shift case $explicit in 1) set '' - "$@"; shift ;; esac ;; "else") case $ifelse in KEEP) ifelse=DONE ;; SKIP|TEST) ifelse=KEEP ;; NONE) echo "$command: $file$line: $1: no matching if" >&$stderr exit 1 ;; esac shift ;; "endif")case $ifelse in NONE) echo "$command: $file$line: $1: no matching if" >&$stderr exit 1 ;; esac case $shell in ksh) ifelse=${ifstack%%:*} ifstack=${ifstack#*:} ;; *) eval `echo $ifstack | sed 's,\([^:]*\):\(.*\),ifelse=\1 ifstack=\2,'` ;; esac shift ;; *) break ;; esac done # check if "run xxx" is equivalent to "set in xxx" case $1 in "("*) set exp - "$@" ;; *.iffe|*.iff) set run "$@" ;; esac case $1 in :) shift continue ;; run) case $shell in bsh) case $2 in */*) x=`echo $2 | sed 's,.*[\\\\/],,'` ;; *) x=$2 ;; esac ;; *) eval 'x=${2##*[\\/]}' ;; esac case $x in *.iffe|*.iff) set set in $2 ;; *.*) ;; *) set set in $2 ;; esac ;; esac # { inc set } drop out early case $1 in ""|"#"*)continue ;; inc) case $ifelse in DONE|SKIP) set ''; shift; continue ;; esac shift case $# in 0) echo "$command: $file$line: path expected" >&$stderr exit 1 ;; esac p=$1 shift if test ! -f $p then echo "$command: $file$line: $p: file not found" >&$stderr exit 1 fi case $# in 0) case $config in 1) e="^HAVE_" ;; *) e="^_" ;; esac ;; 1) e=$1 ;; *) shift echo "$command: $file$line: warning: $*: operands ignored" >&$stderr ;; esac eval `sed -e '/^#define[ ]/!d' -e 's/#define[ ]//' -e 's/[ (].*//' ${e:+"-e/$e/!d"} -e 's/.*/&=1/' $p | LC_ALL=C sort -u` continue ;; set) case $ifelse in DONE|SKIP) set ''; shift; continue ;; esac shift case $1 in ""|"#"*)op= ;; *) arg= op=$1 case $op in --*) case $shell in bsh) op=`echo X$op | sed 's/X--//'` ;; *) op=${op#--} ;; esac ;; -*) case $op in -??*) case $shell in bsh) arg=`echo X$op | sed 's/X-.//'` op=`echo X$op | sed 's/X\\(-.\\).*/\\1/'` ;; *) arg=${op#-?} op=${op%$arg} ;; esac ;; esac case $op in a) op=all ;; c) op=cc ;; C) op=config ;; d) op=debug ;; D) op=define ;; E) op=explicit ;; F) op=features ;; i) op=input ;; I) op=include ;; L) op=library ;; n) op=namval ;; N) op=nooptimize ;; o) op=output ;; e) op=package ;; p) op=prototyped ;; P) op=pragma ;; r) op=regress ;; s) op=shell ;; S) op=static ;; O) op=stdio ;; u) op=undef ;; v) op=verbose ;; x) op=cross ;; X) op=exclude ;; esac ;; esac shift while : do case $# in 0) break ;; esac case $1 in *" "*) shift continue ;; ""|"#"*)break ;; :) shift break ;; esac case $arg in "") arg=$1 ;; *) arg="$arg $1" ;; esac shift done ;; esac case $op in all) all=1 continue ;; cc) occ= for x in $arg do case $occ in "") case $x in *=*) case $shell in bsh) eval $x export `echo $x | sed 's/=.*//'` ;; *) export $x ;; esac ;; -O*) case $optimize in 1) occ=$x ;; esac ;; *) occ=$x ;; esac ;; *) occ="$occ $x" ;; esac done exclude occ continue ;; config) config=1 continue ;; cross) case $arg in ""|-) cross= ;; *) cross="$arg" libpaths= ;; esac continue ;; debug) debug=$arg case $arg in 0) exec 2>&$nullout set - show=echo SHOW= ;; ""|1) exec 2>&$stderr set - show=echo SHOW= ;; 2|3) exec 2>&$stderr case $shell in ksh) eval 'PS4="${PS4%+*([ ])}+\$LINENO+ "' esac show=echo SHOW= set -x ;; *) echo "$command: $arg: debug levels are 0, 1, 2, 3" >&$stderr ;; esac continue ;; define) define=1 continue ;; exclude)case $arg in ""|-) excludes= ;; *) excludes="$excludes $arg" ;; esac exclude includes occ continue ;; explicit) explicit=1 continue ;; features)case $arg in '') tst= ;; *) tst="#include \"$arg\"" ;; esac continue ;; "in"|input) case $arg in "") in=- ;; *) in=$arg if test ! -r $in then echo "$command: $in: not found" >&$stderr exit 1 fi exec < $in file=$in: case $out in "") case $in in *[.\\/]*) case $shell in bsh) eval `echo $in | sed -e 's,.*[\\\\/],,' -e 's/\\.[^.]*//' -e 's/^/out=/'` ;; *) eval 'out=${in##*[\\/]}' eval 'out=${out%.*}' ;; esac ;; *) out=$in ;; esac ;; esac ;; esac continue ;; include)case $arg in ""|-) includes= ;; *) includes="$includes -I$arg" ;; esac exclude includes continue ;; library)for y in $libpaths do eval $y=\"\$$y:\$arg\$${y}_default\" eval export $y done continue ;; namval) define=n continue ;; nodebug)exec 2>&$nullout set - continue ;; nodefine) define=0 continue ;; nooptimize) optimize=0 case $occ in *" -O"*)occ=`echo $occ | sed 's/ -O[^ ]*//g'` cc=$occ ;; esac ;; optimize) optimize=1 ;; out|output) out=$arg defhdr= usr= deflib= one= puthdr= putlib= case $op in output) continue ;; esac def= test= ;; package)protoflags="$protoflags -e $arg" continue ;; prototyped|noprototyped) pragma="$pragma $op" case $op in prototyped) prototyped=1 ;; *) prototyped= ;; esac continue ;; pragma) pragma="$pragma $arg" continue ;; regress)regress=1 version=1995-03-19 continue ;; shell) case $arg in osh) posix_read=-no shell=bsh ;; esac shell=$arg continue ;; static) static=$arg continue ;; stdio) case $arg in '') ext= ;; *) ext= sep= for i in $arg do case $i in -) case $ext in '') continue ;; *) break ;; esac ;; esac echo "#include \"$i\"" > t.c if $cc -E t.c > /dev/null 2>&1 then ext="$ext$sep#include \"$arg\"" sep=$nl fi done ;; esac continue ;; undef) undef=1 continue ;; verbose)verbose=1 continue ;; *) echo "$command: $op: unknown option" >&$stderr exit 1 ;; esac ;; api|define|extern|header|include|print|reference|ver) op=$1 shift arg= ;; *) case $2 in '=') def=$1 shift shift ;; *) case $1 in '-'|'?')def=- shift ;; *) def= ;; esac ;; esac case $1 in '!') not=1 shift ;; *) not= ;; esac case $1 in *'{') op=- ;; '('*|'"'*'"'|'<'*'>') op=exp case $def in '') def=- ;; esac ;; *) op=$1 shift ;; esac arg= cc="$occ $includes" group= groups= fail= hdr= lib= mac= no= note= opt= pass= pth= run= set= src= test= yes= case $# in 0) ;; *) case $1 in "#"*) set x shift ;; *) case $op in ref) ;; *) case $1 in '-') case $op:$2 in tst:*) arg=$1 case $2 in -) shift ;; esac ;; *:-*) arg=$1 shift ;; *) def=- shift case $1 in '('*|*'{'|'"'*'"'|'<'*'>') arg=- ;; *) arg=$1 case $# in 0) ;; *) shift ;; esac ;; esac ;; esac ;; -*|+*|'('*|*'{'|'"'*'"'|'<'*'>') arg=- ;; *) arg=$1 shift ;; esac ;; esac ;; esac case $1 in '('*|'"'*'"'|'<'*'>') while : do case $# in 0) break ;; esac case $1 in *[.{}]*)break ;; esac case $test in '') test=$1 ;; *) test="$test $1" ;; esac shift done case $arg in '') arg=- ;; esac case $op in exp) case $def in ''|'-') ;; *) arg=$def ;; esac ;; esac ;; esac sline=$line while : do case $# in 0) break ;; esac case $1 in "") ;; "#"*) set x ;; "=") shift set=$* case $set in "") set=" " ;; esac while : do case $# in 0) break ;; esac shift done break ;; [abcdefghijklmnopqrstuvwxyz]*'{'|'{') v=$1 shift x= case $v in "note{") sep=" " ;; *) sep=$nl ;; esac case $v in '{') e='}' ;; *) e='}end' ;; esac n=1 SEP= while : do case $# in 0) case $posix_read in -*) checkread ;; esac case $in in "") echo "$command: $file$line: missing }end" >&$stderr exit 1 ;; esac while : do case $posix_read in 1) case $shell in ksh) IFS= read -r lin eof=$? while : do lin="${lin#[' ']}" case $lin in [' ']*'#'*);; *) break ;; esac done ;; *) IFS= read -r lin eof=$? IFS=$ifs case $lin in [' ']*) lin=`sed -e 's,^[ ],,' -e 's,^[ ]*#,#,' <&$stderr exit 1 ;; esac done ;; esac case $1 in $v) case $shell in ksh) let n=n+1 ;; *) n=`expr $n + 1` ;; esac ;; $e|$e';') case $n in 1) break ;; esac case $shell in ksh) let n=n-1 ;; *) n=`expr $n - 1` ;; esac ;; esac x="$x$SEP$1" SEP=$sep shift done case $v in 'note{');; *) x="$x$nl" # \r\n bash needs this barf # ;; esac case $v in 'fail{') fail=$x ;; 'nofail{') pass=$x v='pass{' ;; 'nopass{') fail=$x v='fail{' ;; 'no{') no=$x ;; 'note{') note=$x ;; 'pass{') pass=$x ;; 'test{') test=$x ;; 'yes{'|'{') yes=$x ;; *) src=$x run=$v ;; esac ;; :) shift break ;; *[\"\'\(\)\{\}\ \ ]*) case $op in pth) pth="$pth $1" ;; *) case $test in '') test=$1 ;; *) test="$test $1" ;; esac ;; esac ;; -) group=$group$1 case $group in -) com_hdr=$hdr com_lib=$lib com_mac=$mac com_opt=$opt com_pth=$pth com_test=$test ;; *) groups="$groups $1" ;; esac ;; -l*) case $group in --*) groups="$groups $1" ;; *) lib="$lib $1" ;; esac ;; +l*) case $shell in bsh) x=`echo X$1 | sed 's/X+/-/'` ;; *) eval 'x=-${1#+}' ;; esac case $group in --*) groups="$groups $x" ;; *) lib="$lib $x" ;; esac ;; -*|+*) case $op in ref) cc="$cc $1" occ="$occ $1" case $1 in -L*) case $shell in ksh) x=${1#-L} ;; *) x=`echo x$1 | sed 's,^x-L,,'` ;; esac for y in $libpaths do eval $y=\"\$$y:\$x\$${y}_default\" eval export $y done ;; esac ;; *) case $group in --*) groups="$groups $1" ;; *) case $op in run) opt="$opt $1" ;; *) case $1 in -D*) mac="$mac $1" ;; *) cc="$cc $1" ;; esac ;; esac ;; esac ;; esac ;; *.[aAxX]|*.[dD][lL][lL]|*.[lL][iI][bB]) case $group in --*) groups="$groups $1" ;; *) lib="$lib $1" ;; esac ;; *[.\\/]*) case $group in --*) groups="$groups $1" ;; *) case $op in pth) pth="$pth $1" ;; *) hdr="$hdr $1" ;; esac ;; esac ;; *) case $group in --*) groups="$groups $1" ;; *) case $op in pth) pth="$pth $1" ;; *) case $test in '') test=$1 ;; *) test="$test $1" ;; esac ;; esac ;; esac ;; esac shift done case $group in -) group= ;; esac ;; esac ;; esac case $ifelse in DONE|SKIP) continue ;; esac # make sure $cc compiles C case $cc in "") cc="$occ $includes" ;; esac case $cctest in "") checkcc ;; esac # some ops allow no args case $arg in '') case $op in api) arg=- case $1:$2 in [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) a=$1 shift case " $apis " in *" $a "*) ;; *) apis="$apis $a" eval api_sym_${a}= api_ver_${a}= ;; esac rel= while : do case $# in 0) break ;; esac case $1 in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) rel="$rel $1" ;; *) break ;; esac shift done while : do case $# in 0) break ;; esac case $1 in :) break ;; esac eval syms='$'api_sym_${a} case $syms in '') sep='' ;; *) sep=$nl ;; esac for r in $rel do syms=$syms$sep${1}:${r} sep=$nl done eval api_sym_${a}='$'syms shift done ;; *) echo "$command: $op: expected: name YYYYMMDD symbol ..." >&$stderr ;; esac while : do case $# in 0) break ;; esac case $1 in :) break ;; esac shift done ;; iff|ini)arg=- ;; comment)copy - "/* $* */" continue ;; define) x=$1 shift case $1 in '('*')') arg=$1 shift ;; esac case $in in "") v= while : do case $# in 0) break ;; esac t=$1 shift case $t in ":") break ;; esac v="$v $t" done ;; *) v=$* ;; esac is mac $x copy $tmp.c "$std $usr #ifndef $x ( #endif int x; " if compile $cc -c $tmp.c <&$nullin >&$nullout then success - else failure - copy - "#define $x$arg $v" usr="$usr${nl}#define $x$arg $v" fi continue ;; extern) x=$1 shift t=$1 shift is npt $x copy $tmp.c " $std #include $usr _BEGIN_EXTERNS_ struct _iffe_struct { int _iffe_member; }; extern struct _iffe_struct* $x _ARG_((struct _iffe_struct*)); _END_EXTERNS_ " # some compilers with -O only warn for invalid intrinsic prototypes case " $cc " in *" -O "*) xx=`echo $cc | sed 's/ -O / /g'` ;; *) xx=$cc ;; esac if compile $xx -c $tmp.c <&$nullin >&$nullout then success - while : do case $1 in ''|'('*|'['*) break ;; esac t="$t $1" shift done case $in in "") v= while : do case $# in 0) break ;; esac t=$1 shift case $t in ":") break ;; esac v="$v $t" done ;; *) v=$* ;; esac copy - "extern $t $x$v;" # NOTE: technically if prototyped is on all tests should # be run through proto(1), but we'd like iffe to # work sans proto -- so we drop the extern's in # the test headers case $prototyped in '') usr="$usr${nl}extern $t $x$v;" ;; esac else failure - case $in in "") while : do case $# in 0) break ;; esac case $1 in ":") break ;; esac done ;; esac fi continue ;; header|include|reference) while : do case $# in 0) break ;; esac x=$1 shift case $x in ":") break ;; esac case " $gothdr " in *" - $x "*) ;; *" + $x "*) case $usr in *"# include <"$x">"*) ;; *) case $op in reference) ;; *) copy - "#include <$x>" ;; esac usr="$usr${nl}#include <$x>" ;; esac ;; *) copy $tmp.c "$std $usr #include <$x> int x; " if is_hdr - $x then gothdr="$gothdr + $x" case $op in reference) ;; *) copy - "#include <$x>" ;; esac usr="$usr${nl}#include <$x>" else gothdr="$gothdr - $x" fi ;; esac done continue ;; print) case $in in "") v= while : do case $# in 0) break ;; esac t=$1 shift case $t in ":") break ;; esac v="$v $t" done ;; *) v=$* ;; esac copy - "$*" usr="$usr${nl}$v" continue ;; ver) arg=- case $1:$2 in [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) vers="$vers$nl$1" eval ver_$1=$2 ;; *) echo "$command: $op: expected: name YYYYMMDD" >&$stderr ;; esac while : do case $# in 0) break ;; esac case $1 in :) break ;; esac shift done ;; esac ;; esac # NOTE() support case $ext in *""*) case $ext in *"#define NOTE("*) ;; *) ext="$ext #define NOTE(s) do{write(9,\" \",1);write(9,s,strlen(s));write(9,\" ...\",4);}while(0)" ;; esac ;; esac # save $* for ancient shells argx=1 argv=$* # loop on all candidate groups while : do # check the candidate macros cc="$cc $mac" # check for global default headers (some cc -E insist on compiling) case $hdrtest in '') hdrtest=1 allinc= for x in types do case $config in 0) c=_sys_${x} ;; 1) case $shell in ksh) typeset -u u=$x ;; *) u=`echo $x | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac c=HAVE_SYS_${u}_H ;; esac x=sys/$x.h echo "${allinc}#include <$x>" > $tmp.c if is_hdr $x then gothdr="$gothdr + $x" case $explicit in 0) can="$can$cansep#define $c 1 /* #include <$x> ok */" nan="$nan$cansep$c=1" cansep=$nl ;; esac eval $c=1 allinc="${allinc}#include <$x>$nl" else gothdr="$gothdr - $x" case $explicit$all$config$undef in 0?1?|0??1) can="$can$cansep#undef $c /* #include <$x> not ok */" nan="$nan$cansep$c=" cansep=$nl ;; 01??) can="$can$cansep#define $c 0 /* #include <$x> not ok */" nan="$nan$cansep$c=0" cansep=$nl ;; esac fi done ;; esac # add implicit headers/libraries before the checks case $op in npt) hdr="sys/types.h stdlib.h unistd.h $hdr" ;; siz|typ)hdr="sys/types.h time.h sys/time.h sys/times.h stddef.h stdlib.h $hdr" ;; esac # check the candidate headers case $hdr in ?*) z=$hdr hdr= dis=0 for x in $z do case $x in *.h) case " $gothdr " in *" - $x "*) continue ;; *" + $x "*) ;; *) case $shell in bsh) eval `echo $x | sed -e 's,^\\([^\\\\/]*\\).*[\\\\/]\\([^\\\\/]*\\)\$,\\1_\\2,' -e 's/\\..*//' -e 's/^/c=/'` ;; *) eval 'c=${x##*[\\/]}' eval 'c=${c%%.*}' case $x in */*) eval 'c=${x%%[\\/]*}_${c}' ;; esac ;; esac case $explicit in 0) dis=0 ;; *) case $x in */*) dis=$c ;; *) dis=hdr ;; esac case ${dis}_ in ${op}_*)dis=0 ;; *) dis=1 ;; esac ;; esac case $config in 0) case $x in */*) c=_${c} ;; *) c=_hdr_${c} ;; esac ;; 1) case $shell in ksh) typeset -u u=$c ;; *) u=`echo $c | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac c=HAVE_${u}_H ;; esac echo "${allinc}#include <$x>" > $tmp.c if is_hdr $x then gothdr="$gothdr + $x" case $dis in 0) can="$can$cansep#define $c 1 /* #include <$x> ok */" nan="$nan$cansep$c=1" cansep=$nl ;; esac eval $c=1 else gothdr="$gothdr - $x" case $dis$all$config$undef in 0?1?|0??1) can="$can$cansep#undef $c /* #include <$x> not ok */" nan="$nan$cansep$c=" cansep=$nl ;; 01??) can="$can$cansep#define $c 0 /* #include <$x> not ok */" nan="$nan$cansep$c=0" cansep=$nl ;; esac continue fi ;; esac ;; *) test -r $x || continue ;; esac hdr="$hdr $x" done ;; esac # check the candidate libraries case $lib in ?*) z= for p in $lib do z="$p $z" done lib= p= hit=0 echo "int main(){return(0);}" > $tmp.c for x in $z do p=$x case " $gotlib " in *"- $p "*) failure + p= ;; *"+ $p "*) success + lib="$p $lib" ;; *) rm -f $tmp.exe is LIB $p if compile $cc -o $tmp.exe $tmp.c $p $lib <&$nullin >&$nullout then success gotlib="$gotlib + $p" lib="$p $lib" e=0 else a= e=1 for l in $z do case $l in -) a= continue ;; $p) a=$p continue ;; *) case $gotlib in *" $l "*) continue ;; esac ;; esac case $a in $p) a="$a $l" if compile $cc -o $tmp.exe $tmp.c $a <&$nullin >&$nullout then success gotlib="$gotlib + $p" lib="$p $lib" e=0 break fi ;; esac done case $e in 1) failure gotlib="$gotlib - $p" ;; esac fi y= for x in $p do case $shell in bsh) c=`echo X$x | sed 's,X-l,,'` ;; *) eval 'c=${x#-l}' ;; esac case $c in *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*) c=`echo '' $c | sed -e 's,.*[\\\\/],,' -e 's,\.[^.]*$,,' -e 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_],_,g' -e '/^lib./s,^lib,,'` ;; esac case $config in 0) case $e$p in 0*' '*) case " $gotlib " in *[-+]" $x "*) ;; *) can="$can$cansep#define _LIB_$c 1 /* $x is a library */" nan="$nan${cansep}_LIB_$c=1" cansep=$nl eval _LIB_$c=1 ;; esac ;; esac ;; 1) case $shell in ksh) typeset -u u=$c ;; *) u=`echo $c | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac c=$u case $e in 0*' '*) case " $gotlib " in *[-+]" $x "*) ;; *) can="$can$cansep#define HAVE_${c}_LIB 1 /* $x is a library */" nan="$nan${cansep}HAVE_${c}_LIB=1" cansep=$nl eval HAVE_${c}_LIB=1 ;; esac ;; esac ;; esac y=${y}_$c done case $config in 0) c=_LIB${y} ;; 1) c=HAVE${y}_LIB ;; esac case $p in *' '*) q="a library group" ;; *) q="a library" ;; esac case $e in 0) can="$can$cansep#define $c 1 /* $p is $q */" nan="$nan$cansep$c=1" cansep=$nl eval $c=1 case $hit in 1) break ;; esac ;; 1) case $all$config$undef in ?1?|??1)can="$can$cansep#undef $c /* $p is not $q */" nan="$nan$cansep$c=" cansep=$nl ;; 1??) can="$can$cansep#define $c 0 /* $p is not $q */" nan="$nan$cansep$c=0" cansep=$nl ;; esac eval $c=0 ;; esac p= ;; esac done ;; esac # last op precheck case $op in ref) deflib="$deflib $lib" defhdr="$defhdr $hdr" break ;; esac IFS=" ," case $shell in bash) op=`echo $op` arg=`echo $arg` ;; *) eval op=\"$op\" eval arg=\"$arg\" ;; esac IFS=$ifs # check for op aliases x= for o in $op do case $o in def|default) x="$x cmd dat hdr key lib mth sys typ" ;; *) x="$x $o" ;; esac done # loop on the ops o and args a result=UNKNOWN for o in $x do for a in $arg do c= case $a in *[.\\/]*) case $o in hdr|lcl|nxt|pth|sys) x=$a case $x in *.lcl|*.nxt) case $o in sys) x=sys/$x ;; esac case $shell in bsh) eval `echo $x | sed 's,\\(.*\\)\.\\([^.]*\\),x=\\1 o=\\2,'` ;; *) o=${x##*.} x=${x%.${o}} ;; esac v=$x ;; esac case $x in *[\\/]*)case $shell in bsh) eval `echo $x | sed 's,\\(.*\\)[\\\\//]\\(.*\\),p=\\1 v=\\2,'` ;; *) eval 'p=${x%/*}' eval 'v=${x##*/}' ;; esac ;; *.*) case $shell in bsh) eval `echo $x | sed 's,\\(.*\\)\\.\\(.*\\),p=\\1 v=\\2,'` ;; *) eval 'p=${x%.*}' eval 'v=${x##*.}' ;; esac ;; *) p= ;; esac case $o in lcl|nxt) c=$v.$o ;; *) c=$v ;; esac ;; *) case $shell in bsh) eval `echo $a | sed -e 's,.*[\\\\/],,' -e 's/\\(.*\\)\\.\\(.*\\)/p=\\1 v=\\2/'` ;; *) eval 'p=${a%.*}' eval 'p=${p##*[\\/]}' eval 'v=${a##*.}' eval 'v=${v##*[\\/]}' ;; esac ;; esac case $p in '') f=${v} ;; *) f=${p}/${v} ;; esac case $o in run) v=$p p= m=_${v} ;; mem) case $p in *.*) case $shell in bsh) eval `echo $p | sed 's/\\([^.]*\\)\\.\\(.*\\)/p=\\1 m=\\2/'` ;; *) eval 'm=${p#*.}' eval 'p=${p%%.*}' ;; esac v=${m}.${v} esac case $config in 0) m=_${v}_${p} ;; 1) m=_${v}_in_${p} ;; esac ;; *) case $p in '') m=_${v} ;; *) m=_${p}_${v} ;; esac ;; esac ;; *) p= v=$a f=$a m=_${v} ;; esac case $c in '') c=$v ;; esac M=$m case $o in out) case $a in -) a=- ;; ?*) test="$a $test" a= ;; esac ;; *) case " $idyes " in *" $m "*) i=1 ;; *) case " $idno " in *" $m "*) i=0 ;; *) case $m in *'*') m=`echo "$m" | sed 's,\*,_ptr,g'` ;; esac case $m in *[-+/\\]*) i=0 ;; *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*) is id $m copy $tmp.c "int $m = 0;" if compile $cc -c $tmp.c then success - idyes="$idyes $m" i=1 else failure - idno="$idno $m" i=0 fi ;; *) i=1 ;; esac ;; esac case $i in 0) case $o in dat|dfn|key|lib|mac|mth|nos|npt|siz|sym|typ|val) continue ;; esac ;; esac ;; esac ;; esac case $m in *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*) m=`echo "X$m" | sed -e 's,^.,,' -e 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_],_,g'` ;; esac # check output redirection case $out in $cur) ;; *) case $cur in $a|$c) ;; *) case $cur in .) ;; *) case $vers in ?*) echo for api in $vers do API=`echo $api | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` eval ver='${'ver_${api}'}' echo "#define ${API}_VERSION ${ver}" done esac case $apis in ?*) for api in $apis do API=`echo $api | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` echo "#define ${API}API(rel) ( _BLD_${api} || !_API_${api} || _API_${api} >= rel )" map= sep= eval syms='"${'api_sym_${api}'}"' # old Solaris requires -k # set x x `echo "$syms" | sort -t: -u -k 1,1 -k 2,2nr 2>/dev/null | sed 's/:/ /'` case $# in 2) # ancient sort doesn't have -k # set x x `echo "$syms" | sort -t: -u +0 -1 +1 -2nr 2>/dev/null | sed 's/:/ /'` ;; esac sym= while : do shift 2 case $# in [01]) break ;; esac prv=$sym sym=$1 rel=$2 case $prv in $sym) echo "#elif _API_${api} >= $rel" ;; *) case $prv in '') echo echo "#if !defined(_API_${api}) && defined(_API_DEFAULT)" echo "#define _API_${api} _API_DEFAULT" echo "#endif" ;; *) echo "#endif" ;; esac echo echo "#if ${API}API($rel)" ;; esac echo "#undef ${sym}" echo "#define ${sym} ${sym}_${rel}" map=$map$sep${sym}_${rel} sep=' ' done echo "#endif" echo echo "#define _API_${api}_MAP \"$map\"" done echo ;; esac case $iff in ?*) echo "#endif" ;; esac case $cur in -) ;; *) exec >/dev/null case $cur in *[\\/]*|*.h) x=$cur ;; *) x=$dir/$cur ;; esac case $define in n) sed '/^#/d' $tmp.h > $tmp.c sed '/^#/d' $x > $tmp.t ;; *) (proto -r $protoflags $tmp.h) >/dev/null 2>&1 sed 's,/\*[^/]*\*/, ,g' $tmp.h > $tmp.c sed 's,/\*[^/]*\*/, ,g' $x > $tmp.t ;; esac if cmp -s $tmp.c $tmp.t then rm -f $tmp.h case $verbose in 1) echo "$command: $x: unchanged" >&$stderr ;; esac touch "$x" # avoid rerunning test on subsequent runs else case $x in ${dir}[\\/]$cur) test -d $dir || mkdir $dir || exit 1 ;; esac mv $tmp.h $x fi ;; esac ;; esac case $out in +) case $status in 1) ;; *) status=0 ;; esac exit $status ;; -) eval "exec >&$stdout" ;; *) exec >$tmp.h ;; esac case $out in "") case $a in *[\\/]*|???????????????*) cur=$c ;; *) cur=$a ;; esac ;; *) cur=$out ;; esac case $in in ""|-|+) case $o in run) x=" from $a" ;; *) x= ;; esac ;; *) x=" from $in" ;; esac # output header comments case $define in n) ;; ?) echo "/* : : generated$x by $command version $version : : */" for x in $pragma do echo "#pragma $x" done case $out in ""|-|+) x=$m ;; *.*) case $shell in bsh) eval `echo $in | sed -e 's,\\.,_,g' -e 's/^/x=/'` ;; *) i=$out x=_ while : do case $i in *.*) eval 'x=$x${i%%.*}_' eval 'i=${i#*.}' ;; *) x=$x$i break ;; esac done ;; esac ;; *) x=_$out ;; esac case $o in iff) case $M in ""|*-*) ;; *) iff=${m}_H ;; esac ;; *) case $regress in '') case $x in *-*) ;; *) x=`pwd | sed -e 's,.*[\\\\/],,' -e 's,\\..*,,' -e 's,^lib,,' -e 's,^,'${x}_',' -e 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_],_,g'` # ksh n+ bug workaround case $x in *[!_]*) ;; *) x=_$$ ;; esac iff=_def${x} ;; esac ;; *) case $x in *-*) ;; *) iff=_REGRESS ;; esac ;; esac ;; esac case $iff in ?*) echo "#ifndef $iff" echo "#define $iff 1" ;; esac ;; esac ;; esac ;; esac case $can in ?*) case $define in 1) echo "$can" ;; n) echo "$nan" ;; esac can= nan= cansep= ;; esac # set up the candidate include list pre= inc= for x in $defhdr - $hdr do case $x in -) case $pre in ?*) continue ;; esac case $v in *.*) for x in `echo $v | sed 's,\\., ,g'` do pre="$pre #undef $x" done ;; *) case $o in siz|typ)case $v in char|short|int|long) ;; *) pre="#undef $v" ;; esac ;; *) pre="#undef $v" ;; esac ;; esac ;; *.h) case $shell in bsh) eval `echo $x | sed -e 's,^\\([^\\\\/]*\\).*[\\\\/]\\([^\\\\/]*\\)\$,\\1_\\2,' -e 's/\\..*//' -e 's/^/c=/'` ;; *) eval 'c=${x##*[\\/]}' eval 'c=${c%%.*}' case $x in */*) eval 'c=${x%%[\\/]*}_${c}' ;; esac ;; esac case $config in 0) case $x in */*) c=_${c} ;; *) c=_hdr_${c} ;; esac ;; 1) case $shell in ksh) typeset -u u=$c ;; *) u=`echo $c | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac c=HAVE_${u}_H ;; esac case " $puthdr " in *" $c "*) ;; *) puthdr="$puthdr $c" usr="$usr$nl#define $c 1" ;; esac inc="$inc #include <$x>" ;; esac done # set up the candidate lib list for x in $lib $deflib do case $shell in ksh) eval 'c=${x#-l}' ;; *) c=`echo X$x | sed 's,X-l,,'` ;; esac case $c in *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*) c=`echo '' $c | sed -e 's,.*[\\\\/],,' -e 's,\.[^.]*$,,' -e 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_],_,g' -e '/^lib./s,^lib,,'` ;; esac case $config in 0) c=_LIB_${c} ;; 1) case $shell in ksh) typeset -u u=$c ;; *) u=`echo $c | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac c=HAVE_${u}_LIB ;; esac case " $putlib " in *" $c "*) ;; *) putlib="$putlib $c" usr="$usr$nl#define $c 1" ;; esac done # src overrides builtin test case $config:$def in 0:) case $o in tst|var);; *) m=_${o}${m} ;; esac ;; 1:) case $o in tst|var)m=${v} ;; esac case $shell in ksh) typeset -u u=$m ;; *) u=`echo $m | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac case $o in tst|var)case $m in $u) ;; *) case $m in hdr_*|lib_*|sys_*) case $shell in ksh) u=${u#????} ;; *) u=`echo $u | sed 's/....//'` ;; esac ;; esac m=HAVE_${u} ;; esac ;; dat) m=HAVE${u}_DATA ;; hdr|lcl)m=HAVE${u}_H ;; key) m=HAVE${u}_RESERVED ;; mth) m=HAVE${u}_MATH ;; npt) m=HAVE${u}_DECL ;; pth) m=${u}_PATH case $shell in ksh) m=${m#_} ;; *) m=`echo $m | sed 's,^_,,'` ;; esac ;; nxt) m=HAVE${u}_NEXT ;; siz) m=SIZEOF${u} ;; sys) m=HAVE_SYS${u}_H ;; *) m=HAVE${u} ;; esac ;; *) m=$def M=$m ;; esac case $src in ?*) case $src in *[\<\"][Ss][Tt][Dd][Ii][Oo].[Hh][\"\>]* | *\* | *\* | */[*]\[*]/*) EXT= ;; *) EXT="$tst $ext" ;; esac copy $tmp.c "$std $EXT $usr $inc $src " V=1 e=0 is tst "${note:-$run}" case $run in cat*|nocat*) copy - "$src" ;; cross*|nocross*) copy $tmp.sh "$src" chmod +x $tmp.sh execute $tmp.sh <&$nullin || e=1 ;; run*|norun*) (eval "$src") <&$nullin || e=1 ;; mac*|nomac*) if compile $cc -E -P $tmp.c <&$nullin >$tmp.i then sed -e '/<<[ ]*".*"[ ]*>>/!d' -e 's/<<[ ]*"//g' -e 's/"[ ]*>>//g' $tmp.i else e=1 fi ;; p*|nop*)compile $cc -DTEST=$p -DID=$v -E $tmp.c <&$nullin >&$nullout || e=1 ;; c*|noc*)compile $cc -DTEST=$p -DID=$v -c $tmp.c <&$nullin >&$nullout || e=1 ;; *) case $run in status*)ccflags= ;; s*|nos*)case $reallystatictest in '') #UNDENT... reallystatictest=. echo "$tst $ext int main(){printf("hello");return(0);}" > ${tmp}s.c rm -f ${tmp}s.exe if compile $cc -c ${tmp}s.c <&$nullin >&$nullout && compile $cc -o ${tmp}s.exe ${tmp}s.o <&$nullin >&$nullout 2>${tmp}s.e && $executable ${tmp}s.exe then e=`wc -l ${tmp}s.e` eval set x x $binding while : do shift shift case $# in 0) break ;; esac rm -f ${tmp}s.exe compile $cc -o ${tmp}s.exe $1 ${tmp}s.o <&$nullin >&$nullout 2>${tmp}s.e && $executable ${tmp}s.exe || continue case `wc -l ${tmp}s.e` in $e) ;; *) continue ;; esac d=`ls -s ${tmp}s.exe` rm -f ${tmp}s.exe compile $cc -o ${tmp}s.exe $2 ${tmp}s.o <&$nullin >&$nullout 2>${tmp}s.e && $executable ${tmp}s.exe || continue case `wc -l ${tmp}s.e` in $e) ;; *) continue ;; esac case `ls -s ${tmp}s.exe` in $d) ;; *) reallystatic=$2 set x shift break ;; esac done fi rm -f ${tmp}s.* #...INDENT ;; esac ccflags=$reallystatic ;; *) ccflags= ;; esac set x $mac e=1 while : do o= shift while : do case $# in 0) break ;; esac case $1 in -) break ;; esac o="$o $1" shift done rm -f $tmp.exe if compile $cc $ccflags $o -DTEST=$p -DID=$v -o $tmp.exe $tmp.c $lib $deflib <&$nullin >&$nullout && $executable $tmp.exe then case $run in status*)execute $tmp.exe <&$nullin >&$nullout V=$? case $V in 0) e=1 ;; *) e=0 ;; esac break ;; no[ls]*);; [ls]*) e=0 && break ;; noo*) execute $tmp.exe <&$nullin >$tmp.out || break ;; o*) execute $tmp.exe <&$nullin >$tmp.out && e=0 && break ;; no*) execute $tmp.exe <&$nullin >&$nullout || break ;; *) execute $tmp.exe <&$nullin >&$nullout && e=0 && break ;; esac else case $run in no[els]*)e=1 && break ;; esac fi case $# in 0) case $run in no*) e=0 ;; esac break ;; esac done ;; esac o=1 case $run in no*) case $e in 0) e=1 ;; *) e=0 ;; esac ;; esac case $run in o*|noo*)case $e in 0) cat $tmp.out ;; esac rm -f $tmp.out ;; esac report $e $V "${note:-$run\ passed}" "${note:-$run} failed" continue ;; esac # initialize common builtin state case $o in dat|lib|mth|run) case $statictest in "") statictest=FoobaR copy $tmp.c " $tst $ext $std $usr _BEGIN_EXTERNS_ extern int $statictest; _END_EXTERNS_ int main(){char* i = (char*)&$statictest; return ((unsigned int)i)^0xaaaa;} " rm -f $tmp.exe if compile $cc -o $tmp.exe $tmp.c <&$nullin >&$nullout && $executable $tmp.exe then case $static in .) static= copy $tmp.c " $tst $ext int main(){printf("hello");return(0);} " rm -f $tmp.exe if compile $cc -c $tmp.c <&$nullin >&$nullout && compile $cc -o $tmp.exe $tmp.o <&$nullin >&$nullout && $executable $tmp.exe then e=`wc -l $tmp.e` eval set x x $binding while : do shift shift case $# in 0) break ;; esac rm -f $tmp.exe compile $cc -o $tmp.exe $1 $tmp.o <&$nullin >&$nullout && $executable $tmp.exe || continue case `wc -l $tmp.e` in $e) ;; *) continue ;; esac d=`ls -s $tmp.exe` rm -f $tmp.exe compile $cc -o $tmp.exe $2 $tmp.o <&$nullin >&$nullout && $executable $tmp.exe || continue case `wc -l $tmp.e` in $e) ;; *) continue ;; esac case `ls -s $tmp.exe` in $d) ;; *) static=$2 set x shift break ;; esac done fi ;; esac else static= fi ;; esac ;; esac # builtin tests case $o in api) ;; cmd) case $p in ?*) continue ;; esac is $o $a k=1 pkg $pth # set system default path for d in $pth do if test -f "$d/$a" then s=`echo "$d" | LC_ALL=C sed 's,[^0-9A-Za-z],_,g'` case $k in 1) k=0 case $M in *-*) ;; *) usr="$usr$nl#define $m 1" case $define in 1) echo "#define $m 1 /* $a in $pth */" ;; n) echo "$m=1" ;; esac ;; esac ;; esac c=${s}_${v} usr="$usr$nl#define $c 1" case $define in 1) echo "#define $c 1 /* $d/$a found */" ;; n) echo "$c=1" ;; esac fi done case $k in 0) success ;; 1) failure ;; esac ;; dat) case $p in ?*) continue ;; esac { copy - " $tst $ext $std $usr $pre " case $inc in ?*) echo "$inc" ;; *) echo "_BEGIN_EXTERNS_ extern int $v; _END_EXTERNS_" ;; esac echo " #ifdef _DLL #define _REF_ #else #define _REF_ & #endif int main(){char* i = (char*) _REF_ $v; return ((unsigned int)i)^0xaaaa;}" } > $tmp.c is $o $v rm -f $tmp.exe compile $cc -c $tmp.c <&$nullin >&$nullout && compile $cc $static -o $tmp.exe $tmp.o $lib $deflib <&$nullin >&$nullout && $executable $tmp.exe report $? 1 "$v in default lib(s)" "$v not in default lib(s)" ;; dfn) case $p in ?*) continue ;; esac is dfn $v echo "$pre $tst $ext $inc #ifdef $v <<\"#ifndef $v\">> <<\"#define $v\">> $v <<\"/* native $v */\">> <<\"#endif\">> #endif" > $tmp.c if compile $cc -E -P $tmp.c <&$nullin >$tmp.i then sed -e '/<<[ ]*".*"[ ]*>>/!d' -e 's/<<[ ]*"//g' -e 's/"[ ]*>>//g' $tmp.i > $tmp.t if test -s $tmp.t then success cat $tmp.t else failure fi else failure fi ;; exp) case $test in '') echo "$command: $file$sline: test expression expected for $o" >&$stderr exit 1 ;; esac case $a in -|'') ;; *) eval x='$'$a case $x in 1) result=FAILURE continue ;; esac ;; esac case $test in [01]|'"'*'"'|'<'*'>') case $a in -|'') ;; *) case $define$note in 1) echo "#define $a $test" ;; 1*) echo "#define $a $test /* $note */" ;; n) echo "$a=$test" ;; esac eval $a='$test' ;; esac ;; *) case $note in '') note=$test ;; esac case $test in '') c=1 ;; *) is exp "$note" x= for i in `echo '' $test | sed 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_], & ,g'` do case $i in [\ \ ]) ;; [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]*) eval i='${'$i'}' case $i in '') i=0 ;; '"'*'"');; *[!-+0123456789]*) case $i in *'"'*) i=1 ;; *) i='"'$i'"' ;; esac ;; esac x="$x $i" ;; '!') x="$x 0 =" ;; '&'|'|')case $x in *"$i") ;; *) x="$x \\$i" ;; esac ;; *) x="$x \\$i" ;; esac done c=`eval expr $x 2>&$stderr` ;; esac case $c in 0) c=1 ;; *) c=0 ;; esac M=$a m=$a report $c 1 "$note is true" "$note is false" ;; esac ;; hdr|lcl|nxt|sys) case $o in lcl|nxt)case $M in *-*) continue ;; esac eval x='$'_$m case $x in ?*) continue ;; esac eval _$m=1 is $o $f echo "$pre $tst $ext $inc #include <$f.h>" > $tmp.c case $f in sys/*) e= ;; *) e='-e /[\\\\\/]sys[\\\\\/]'$f'\\.h"/d' ;; esac if compile $cc -E $tmp.c <&$nullin >$tmp.i then i=`sed -e '/^#[line ]*[0123456789][0123456789]*[ ][ ]*"[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:]*[\\\\\/].*[\\\\\/]'$f'\\.h"/!d' $e -e s'/.*"\\(.*\\)".*/\\1/' -e 's,\\\\,/,g' -e 's,///*,/,g' $tmp.i | sed 1q` case $i in [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]:[\\/]*) ;; */*/*) k=`echo "$i" | sed 's,.*/\([^/]*/[^/]*\)$,../\1,'` echo "$pre $tst $ext $inc #include <$k>" > $tmp.c if compile $cc -E $tmp.c <&$nullin >$tmp.i then j=`sed -e '/^#[line ]*[0123456789][0123456789]*[ ][ ]*"[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:]*[\\\\\/].*[\\\\\/]'$f'\\.h"/!d' $e -e s'/.*"\\(.*\\)".*/\\1/' -e 's,\\\\,/,g' -e 's,///*,/,g' $tmp.i | sed 1q` wi=`wc < "$i"` wj=`wc < "$j"` case $wi in $wj) i=$k ;; esac fi ;; *) echo "$pre $tst $ext $inc #include <../include/$f.h>" > $tmp.c if compile $cc -E $tmp.c <&$nullin >&$nullout then i=../include/$f.h fi ;; esac else i= fi case $i in [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]:[\\/]*|[\\/]*) success case $o in lcl) echo "#if defined(__STDPP__directive)" echo "__STDPP__directive pragma pp:hosted" echo "#endif" echo "#include <$i> /* the native <$f.h> */" echo "#undef $m" usr="$usr$nl#define $m 1" echo "#define $m 1" ;; nxt) echo "#define $m <$i> /* include path for the native <$f.h> */" echo "#define ${m}_str \"$i\" /* include string for the native <$f.h> */" usr="$usr$nl#define $m <$i>$nl#define ${m}_str \"$i\"" eval $m=\\\<$i\\\> ;; esac break ;; ../*/*) success case $o in lcl) echo "#include <$i> /* the native <$f.h> */" echo "#undef $m" usr="$usr$nl#define $m 1" echo "#define $m 1" eval $m=1 ;; nxt) echo "#define $m <$i> /* include path for the native <$f.h> */" echo "#define ${m}_str \"$i\" /* include string for the native <$f.h> */" usr="$usr$nl#define $m <$i>$nl#define ${m}_str \"$i\"" eval $m=\\\<$i\\\> ;; esac break ;; *) failure case $o in lcl) case $all$config$undef in ?1?|??1)echo "#undef $m /* no native <$f.h> */" ;; 1??) echo "#define $m 0 /* no native <$f.h> */" ;; esac eval $m=0 ;; nxt) case $all$config$undef in ?1?|??1)echo "#undef $m /* no include path for the native <$f.h> */" ;; esac ;; esac ;; esac ;; *) case $o in hdr) x=$f.h ;; sys) x=sys/$f.h ;; esac case " $gothdr " in *" - $x "*) failure + ;; *" + $x "*) success + ;; *) echo " $tst $ext $allinc $inc #include <$x>" > $tmp.c if is_hdr $x then gothdr="$gothdr + $x" case $M in *-*) ;; *) case " $puthdr " in *" $m "*) ;; *) puthdr="$puthdr $m" usr="$usr$nl#define $m 1" ;; esac case $define in 1) echo "#define $m 1 /* #include <$x> ok */" ;; n) echo "$m=1" ;; esac eval $m=1 ;; esac else gothdr="$gothdr - $x" case $M in *-*) ;; *) case $define$all$config$undef in 1?1?|1??1)echo "#undef $m /* #include <$x> not ok */" ;; 11??) echo "#define $m 0 /* #include <$x> not ok */" ;; n1?1) echo "$m=" ;; n1??) echo "$m=0" ;; esac eval $m=0 ;; esac fi ;; esac continue ;; esac ;; iff) ;; ini) ;; key) case $p in ?*) continue ;; esac w=$v while : do is $o $w echo "$pre $tst $ext int f(){int $w = 1;return($w);}" > $tmp.c if compile $cc -c $tmp.c <&$nullin >&$nullout then failure case $set in *" ="|*" = "*) set x $set shift w= while : do case $# in 0) break ;; esac case $1 in =) break ;; esac case $w in '') w=$1 ;; *) w="$w $1" ;; esac shift done case $1 in =) shift case $# in 0) set=" " ;; *) set=$* ;; esac ;; *) set= ;; esac case $shell in ksh) typeset -u u=$w ;; *) u=`echo $w | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` ;; esac u=_$u M=$w case $M in *[!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]*) M=`echo "X$m" | sed -e 's,^.,,' -e 's,[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_],_,g'` ;; esac case $config in 1) m=HAVE${u}_RESERVED ;; *) m=_key_${w} ;; esac continue ;; esac report - 1 - - "$w is not a reserved keyword" "default for reserved keyword $v" else report 0 1 "$w is a reserved keyword" - case $M in *-*) ;; *) case $define$w in 1$v) ;; 1*) echo "#define $v $w /* alternate for reserved keyword $v */" ;; n*) echo "$v=$w" ;; esac ;; esac fi break done ;; lib|mth)case $p in ?*) continue ;; esac case $v in -) continue ;; esac is $o $v copy $tmp.c " $tst $ext $std $usr $pre $inc #ifdef _IFFE_type $v i; #else typedef int (*_IFFE_fun)(); #ifdef _IFFE_extern _BEGIN_EXTERNS_ extern int $v(); _END_EXTERNS_ #endif static _IFFE_fun i=(_IFFE_fun)$v;int main(){return ((unsigned int)i)^0xaaaa;} #endif " d=-D_IFFE_extern if compile $cc -c $tmp.c <&$nullin >&$nullout then d= elif compile $cc $d -c $tmp.c <&$nullin >&$nullout then : else d=error fi if test error != "$d" then rm -f $tmp.exe if compile $cc $d $static -o $tmp.exe $tmp.o $lib $deflib <&$nullin >&$nullout && $executable $tmp.exe then case $o in lib) c=0 ;; *) c=1 ;; esac report $c 1 "$v() in default lib(s)" "$v() not in default lib(s)" "default for function $v()" else case $o in mth) rm -f $tmp.exe compile $cc $d $static -o $tmp.exe $tmp.o -lm <&$nullin >&$nullout && $executable $tmp.exe report $? 1 "$v() in math lib" "$v() not in math lib" "default for function $v()" ;; *) report 1 1 - "$v() not in default lib(s)" "default for function $v()" ;; esac fi else if compile $cc -D_IFFE_type -c $tmp.c <&$nullin >&$nullout then c=1 else case $intrinsic in '') copy $tmp.c " $tst $ext $std $usr $pre $inc _BEGIN_EXTERNS_ extern int foo(); _END_EXTERNS_ static int ((*i)())=foo;int main(){return(i==0);} " compile $cc -c $tmp.c <&$nullin >&$nullout intrinsic=$? ;; esac c=$intrinsic fi case $o in mth) report $c 1 "$v() in math lib" "$v() not in math lib" "default for function $v()" ;; *) report $c 1 "$v() in default lib(s)" "$v() not in default lib(s)" "default for function $v()" ;; esac fi ;; mac) case $p in ?*) continue ;; esac is mac $v echo " $tst $ext $pre $inc #ifdef $v '$m:$v' #endif" > $tmp.c compile $cc -E $tmp.c <&$nullin | grep -c "'$m:$v'" >&$nullout report $? 1 "$v is a macro" "$v is not a macro" "default for macro $v" ;; mem) case $p in ?*) eval i='$'_iffe_typedef_$p case $i in 0|1) ;; *) echo "$pre $tst $ext $inc static $p i; int n = sizeof(i);" > $tmp.c is typ $p if compile $cc -c $tmp.c <&$nullin >&$nullout then success - eval _iffe_typedef_$p=1 i=1 else failure - eval _iffe_typedef_$p=0 i=0 fi ;; esac case $i in 0) i="$v is not a member of $p" p="struct $p" ;; *) i=- ;; esac is mem $v "$p" echo "$pre $tst $ext $inc static $p i; int n = sizeof(i.$v);" > $tmp.c compile $cc -c $tmp.c <&$nullin >&$nullout report $? 1 "$v is a member of $p" "$i" ;; *) p=$v eval i='$'_iffe_typedef_$p case $i in 0|1) ;; *) echo "$pre $tst $ext $inc static $p i; int n = sizeof(i);" > $tmp.c is typ $p if compile $cc -c $tmp.c <&$nullin >&$nullout then success - eval _iffe_typedef_$p=1 i=1 else failure - eval _iffe_typedef_$p=0 i=0 fi ;; esac case $i in 0) i="$p is not a non-opaque struct" p="struct $p" ;; *) i=- ;; esac is nos "$p" echo "$pre $tst $ext $inc static $p i; int n = sizeof(i);" > $tmp.c if compile $cc -c $tmp.c <&$nullin >&$nullout then echo "$pre $tst $ext $inc static $p i; unsigned long f() { return (unsigned long)i; }" > $tmp.c if compile $cc -c $tmp.c <&$nullin >&$nullout then c=1 else c=0 fi else c=1 fi report $c 1 "$p is a non-opaque struct" "$i" esac ;; nop) ;; npt) is npt $v copy $tmp.c " $tst $ext $std $usr $pre $inc _BEGIN_EXTERNS_ struct _iffe_struct { int _iffe_member; }; #if _STD_ extern struct _iffe_struct* $v(struct _iffe_struct*); #else extern struct _iffe_struct* $v(); #endif _END_EXTERNS_ " # some compilers with -O only warn for invalid intrinsic prototypes case " $cc " in *" -O "*) xx=`echo $cc | sed 's/ -O / /g'` ;; *) xx=$cc ;; esac compile $xx -c $tmp.c <&$nullin >&$nullout report -$config $? 1 "$v() needs a prototype" "$v() does not need a prototype" ;; num) is num $v copy $tmp.c " $tst $ext $std $usr $pre $inc _BEGIN_EXTERNS_ int _iffe_int = $v / 2; _END_EXTERNS_ " compile $cc -c $tmp.c <&$nullin >&$nullout report $? 1 "$v is a numeric constant" "$v is not a numeric constant" ;; one) for i in $a $hdr do x="#include <$i>" case " $gothdr " in *" - $i "*) continue ;; *" + $i "*) ;; *) echo "$x" > $tmp.c if is_hdr $x then gothdr="$gothdr + $x" else gothdr="$gothdr - $x" continue fi ;; esac case $one in "") one=$x ;; *"$x"*) break ;; *) echo "$one" > $tmp.c if compile $cc -E $tmp.c <&$nullin >$tmp.i then c=$i case $c in *[\\/]*) c=`echo $c | sed 's,[\\\\/],[\\\\/],g'` ;; esac case `sed -e '/^#[line ]*1[ ][ ]*"[\\\\\/].*[\\\\\/]'$c'"/!d' $tmp.i` in ?*) break ;; esac fi one="$one$nl$x" ;; esac echo "$x" break done ;; opt) M=$m is opt $a case " $PACKAGE_OPTIONS " in *" $a "*) c=0 ;; *) c=1 ;; esac report $c 1 "$a is set in \$PACKAGE_OPTIONS" "$a is not set in \$PACKAGE_OPTIONS" ;; out|output) ;; pth) is pth $a pkg $pth tab=" " e= f= for i in $pth do case $i in '{') e="${nl}}" l= x=i v="\$${x}" t=${nl}${tab} b="fnd()${nl}{${t}for ${x} in" ;; '}') b="${b}${t}do${tab}if $exists ${v}/\${1}${t}${tab}${tab}then${tab}f=${v}/\${1}${t}${tab}${tab}${tab}return${t}${tab}${tab}fi" e="${t}done${e}" eval "${b}${e}" fnd $a case $f in ?*) break ;; esac ;; -) b="${b}${t}do${tab}test \"${v}\" = '' -o -d \"${v}\" &&${t}${tab}${tab}" x=${x}i v="${v}\$${x}" b="${b}for ${x} in" e="${t}done${e}" t="${t}${tab}${tab}" ;; *) case $e in '') if $exists ${i}/${a} then f=${i}/${a} break fi ;; *) case $i in /|.) b="${b} ''" ;; *) b="${b} /${i}" ;; esac ;; esac ;; esac done case $f in '') case $set in ' ') f=$a ;; ?*) f=$set ;; esac ;; esac case $f in '') c=1 ;; *) c=0 f="\"$f\"" ;; esac report $c "$f" "${note:-$a path}" "$a path not found" ;; run) is run $a if test ! -r $a then failure not found case $verbose in 0) echo "$command: $file$line: $a: not found" >&$stderr ;; esac exit 1 fi noisy case $a in *.c) rm -f $tmp.exe { echo "$tst $ext $std $usr $inc" cat $a } > $tmp.c compile $cc -o $tmp.exe $tmp.c $lib $deflib <&$nullin >&$stderr 2>&$stderr && $executable $tmp.exe && execute $tmp.exe $opt <&$nullin ;; *.sh) { copy - ": set \"cc='$cc' executable='$executable' id='$m' static='$static' tmp='$tmp'\" $opt $hdr $test" cat $a } > $tmp.sh chmod +x $tmp.sh ( . $tmp.sh ) <&$nullin ;; *) false ;; esac case $? in 0) success ;; *) failure cannot run case $verbose in 0) echo "$command: $file$line: $a: cannot run" >&$stderr ;; esac exit 1 ;; esac ;; siz) case $p in "") x= ;; *) x="$p " ;; esac is siz "$x$v" { case $p:$v in long:*|*:*[_0123456789]int[_0123456789]*) echo "$pre $tst $ext $inc static $x$v i; $x$v f() { $x$v v; i = 1; v = i;" echo "i = v * i; i = i / v; v = v + i; i = i - v;" case $v in float|double) ;; *) echo "v <<= 4; i = v >> 2; i = 10; i = v % i; i |= v; v ^= i; i = 123; v &= i;" ;; esac echo "return v; }" ;; *) echo "$pre $inc struct xxx { $x$v mem; }; static struct xxx v; struct xxx* f() { return &v; }" ;; esac case $x in ""|"struct "|"union ") echo "int g() { return 0; }" ;; *) echo "int g() { return sizeof($x$v)<=sizeof($v); }" ;; esac copy - " int main() { f(); g(); printf(\"%u\\n\", sizeof($x$v)); return 0; }" } > $tmp.c rm -f $tmp.exe $tmp.dat if compile $cc -o $tmp.exe $tmp.c $lib $deflib <&$nullin >&$nullout && $executable $tmp.exe && execute $tmp.exe > $tmp.dat then z=`cat $tmp.dat` c=0 else z=0 c=1 fi report $c "$z" "sizeof($x$v)" "$x$v not a type with known size" ;; sym) case $test in "") x=$v ;; *) x=$test ;; esac echo "$pre $tst $ext $inc '=' $x '='" > $tmp.c compile $cc -E $tmp.c <&$nullin \ | sed \ -e "/'='/!d" \ -e "s/'='//g" \ -e 's/[ ]//g' \ -e 's/((([^()]*)))->/->/g' \ -e 's/(([^()]*))->/->/g' \ -e 's/([^()]*)->/->/g' \ -e 's/\([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*\)\[/\ ary \1[/g' \ -e 's/\([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*\)(/\ fun \1[/g' \ -e 's/\*->\([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]\)/->\ ptr \1/g' \ -e 's/->\([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]\)/->\ reg \1/g' \ -e "/^$v\$/d" \ -e 's/^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*$/\ nam &/g' \ | sed \ -e '/^... /!d' \ | LC_ALL=C sort \ -u \ | sed \ -e 's/\(...\) \([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*\).*/#ifndef _\1_'$v'\ #define _\1_'$v' \2\ #define _\1_'$v'_str "\2"\ #endif/' ;; typ) case $p in "") x= ;; *) x="$p " ;; esac is typ "$x$v" { case $p:$v in long:*|*:*[_0123456789]int[_0123456789]*) echo "$pre $tst $ext $inc static $x$v i; $x$v f() { $x$v v; i = 1; v = i;" echo "i = v * i; i = i / v; v = v + i; i = i - v;" case $v in float|double) ;; *) echo "v <<= 4; i = v >> 2; i = 10; i = v % i; i |= v; v ^= i; i = 123; v &= i;" ;; esac echo "return v; }" ;; *) echo "$pre $tst $ext $inc struct xxx { $x$v mem; }; static struct xxx v; struct xxx* f() { return &v; }" ;; esac case $x in ""|"struct "|"union ") echo "int main() { f(); return 0; }" ;; *) echo "int main() { f(); return sizeof($x$v)<=sizeof($v); }" ;; esac } > $tmp.c rm -f $tmp.exe compile $cc -o $tmp.exe $tmp.c $lib $deflib <&$nullin >&$nullout && $executable $tmp.exe && execute $tmp.exe report $? 1 "$x$v is a type" "$x$v is not a type" "default for type $x$v" ;; val) case $arg in '"'*'"')echo $arg=\'$val\' ;; *) echo $arg=\"$val\" ;; esac ;; ver) ;; 0) result=FAILURE ;; 1) result=SUCCESS ;; :) ;; -) ;; *) echo "$command: $file$line: $o: unknown feature test" >&$stderr status=1 ;; esac done done case $not in 1) case $result in FAILURE) result=SUCCESS ;; *) result=FAILURE ;; esac ;; esac case $result in FAILURE) user_pf=$fail user_yn=$no ;; *) user_pf=$pass user_yn=$yes ;; esac case $user_pf in ?*) eval "$user_pf" <&$nullin ;; esac case $user_yn in ?*) case $def in -) ;; *) case $note in ?*) case $user_yn in *$nl*) user_yn="/* $note */$nl$user_yn" ;; *) user_yn="$user_yn /* $note */" ;; esac ;; esac ;; esac copy - "$user_yn" ;; esac case $ifelse:$result in TEST:SUCCESS) ifelse=KEEP ;; TEST:*) ifelse=SKIP ;; esac case $group:$result in :*|*:SUCCESS) break ;; esac set '' $groups '' "$@" shift case $1 in '') shift; break ;; esac shift # set up and try the next group hdr=$com_hdr lib=$com_lib mac=$com_mac opt=$com_opt pth=$com_pth test=$com_test cc="$occ $includes" group= groups= while : do case $1 in '') shift; break ;; esac case $1 in *[\"\'\(\)\{\}\ \ ]*) case $op in pth) pth="$pth $1" ;; *) case $test in '') test=$1 ;; *) test="$test $1" ;; esac ;; esac ;; -) group=$group$1 groups="$groups $1" ;; -l*) case $group in -*) groups="$groups $1" ;; *) lib="$lib $1" ;; esac ;; +l*) case $shell in bsh) x=`echo X$1 | sed 's/X+/-/'` ;; *) eval 'x=-${1#+}' ;; esac case $group in -*) groups="$groups $x" ;; *) lib="$lib $x" ;; esac ;; -*|+*) case $group in -*) groups="$groups $1" ;; *) case $op in run) opt="$opt $1" ;; *) case $1 in -D*) mac="$mac $1" ;; *) cc="$cc $1" ;; esac ;; esac ;; esac ;; *.[aAxX]|*.[dD][lL][lL]|*.[lL][iI][bB]) case $group in -*) groups="$groups $1" ;; *) lib="$lib $1" ;; esac ;; *[.\\/]*) case $group in -*) groups="$groups $1" ;; *) case $op in pth) pth="$pth $1" ;; *) hdr="$hdr $1" ;; esac ;; esac ;; *) case $group in -*) groups="$groups $1" ;; *) case $op in pth) pth="$pth $1" ;; *) case $test in '') test=$1 ;; *) test="$test $1" ;; esac ;; esac ;; esac ;; esac shift done done done ksh-1.0.0-beta.2/src/cmd/INIT/iffe.tst000066400000000000000000001317361415700074400171250ustar00rootroot00000000000000# regression tests for the iffe command TEST 01 'command line basics' EXEC -r -v - hdr stdio OUTPUT - $'/* : : generated by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes' EXEC -r -v -s bsh - hdr stdio EXEC -r -v - hdr stdio,limits OUTPUT - $'/* : : generated by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _hdr_limits 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is limits.h a header ... yes' EXEC -r -v -s bsh - hdr stdio,limits EXEC -r -v - hdr,lib no_foo_bar,no_bar_foo stdio.h OUTPUT - $'/* : : generated by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is no_foo_bar.h a header ... no iffe: test: is no_bar_foo.h a header ... no iffe: test: is no_foo_bar a library function ... no iffe: test: is no_bar_foo a library function ... no' EXEC -r -v -s bsh - hdr,lib no_foo_bar,no_bar_foo stdio.h EXEC -r -v - hdr no_foo_bar,no_bar_foo stdio.h : lib no_foo_bar,no_bar_foo stdio.h EXEC -r -v -s bsh - hdr no_foo_bar,no_bar_foo stdio.h : lib no_foo_bar,no_bar_foo stdio.h TEST 02 'file input basics' EXEC -r -v - t1.iffe INPUT t1.iffe $'hdr stdio' OUTPUT - $'/* : : generated from t1.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes' EXEC -r -v -s bsh - t1.iffe EXEC -r -v - t2.iffe INPUT t2.iffe $'hdr stdio,limits' OUTPUT - $'/* : : generated from t2.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _hdr_limits 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is limits.h a header ... yes' EXEC -r -v -s bsh - t2.iffe EXEC -r -v - t3.iffe INPUT t3.iffe $'hdr,lib no_foo_bar,no_bar_foo stdio.h' OUTPUT - $'/* : : generated from t3.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is no_foo_bar.h a header ... no iffe: test: is no_bar_foo.h a header ... no iffe: test: is no_foo_bar a library function ... no iffe: test: is no_bar_foo a library function ... no' EXEC -r -v -s bsh - t3.iffe EXEC -r -v - t3.iffe INPUT t3.iffe $'hdr no_foo_bar,no_bar_foo stdio.h lib no_foo_bar,no_bar_foo stdio.h' EXEC -r -v -s bsh - t3.iffe TEST 03 'nested if' EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if hdr stdio if lib open { HIT 1 } elif lib close { HIT 2 } else { HIT 3 } endif elif hdr limits { HIT 4 } else { HIT 5 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _lib_open 1 /* open() in default lib(s) */ HIT 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is open a library function ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if hdr _XXX_stdio if lib open { HIT 1 } elif lib close { HIT 2 } else { HIT 3 } endif elif hdr limits { HIT 4 } else { HIT 5 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _hdr_limits 1 /* #include ok */ HIT 4 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is _XXX_stdio.h a header ... no iffe: test: is limits.h a header ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if hdr _XXX_stdio if lib open { HIT 1 } elif lib close { HIT 2 } else { HIT 3 } endif elif hdr _XXX_limits { HIT 4 } else { HIT 5 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ HIT 5 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is _XXX_stdio.h a header ... no iffe: test: is _XXX_limits.h a header ... no' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if hdr stdio if lib _XXX_open { HIT 1 } elif lib close { HIT 2 } else { HIT 3 } endif elif hdr limits { HIT 4 } else { HIT 5 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _lib_close 1 /* close() in default lib(s) */ HIT 2 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is _XXX_open a library function ... no iffe: test: is close a library function ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if hdr stdio if lib _XXX_open { HIT 1 } elif lib _XXX_close { HIT 2 } else { HIT 3 } endif elif hdr limits { HIT 4 } else { HIT 5 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ HIT 3 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is _XXX_open a library function ... no iffe: test: is _XXX_close a library function ... no' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if mem stat.st_atime sys/types.h sys/stat.h { #define ATIME 1 } elif mem stat.st_ctime sys/types.h sys/stat.h { #define CTIME 1 } elif mem stat.st_mtime sys/types.h sys/stat.h { #define MTIME 1 } else pass{ no_stat_time=1 }end { #define NOTIME 1 } endif if ( !no_stat_time ) { #define YESTIME 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _sys_stat 1 /* #include ok */ #define _mem_st_atime_stat 1 /* st_atime is a member of struct stat */ #define ATIME 1 #define YESTIME 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is sys/stat.h a header ... yes iffe: test: is stat a type or typedef ... no iffe: test: is st_atime a member of struct stat ... yes iffe: test: is ( !no_stat_time ) true ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if mem foo_stat.st_atime sys/types.h sys/stat.h { #define ATIME 1 } elif mem stat.st_ctime sys/types.h sys/stat.h { #define CTIME 1 } elif mem stat.st_mtime sys/types.h sys/stat.h { #define MTIME 1 } else pass{ no_stat_time=1 }end { #define NOTIME 1 } endif if ( !no_stat_time ) { #define YESTIME 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _sys_stat 1 /* #include ok */ #define _mem_st_ctime_stat 1 /* st_ctime is a member of struct stat */ #define CTIME 1 #define YESTIME 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is sys/stat.h a header ... yes iffe: test: is foo_stat a type or typedef ... no iffe: test: is st_atime a member of struct foo_stat ... no iffe: test: is stat a type or typedef ... no iffe: test: is st_ctime a member of struct stat ... yes iffe: test: is ( !no_stat_time ) true ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if mem foo_stat.st_atime sys/types.h sys/stat.h { #define ATIME 1 } elif mem foo_stat.st_ctime sys/types.h sys/stat.h { #define CTIME 1 } elif mem stat.st_mtime sys/types.h sys/stat.h { #define MTIME 1 } else pass{ no_stat_time=1 }end { #define NOTIME 1 } endif if ( !no_stat_time ) { #define YESTIME 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _sys_stat 1 /* #include ok */ #define _mem_st_mtime_stat 1 /* st_mtime is a member of struct stat */ #define MTIME 1 #define YESTIME 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is sys/stat.h a header ... yes iffe: test: is foo_stat a type or typedef ... no iffe: test: is st_atime a member of struct foo_stat ... no iffe: test: is st_ctime a member of struct foo_stat ... no iffe: test: is stat a type or typedef ... no iffe: test: is st_mtime a member of struct stat ... yes iffe: test: is ( !no_stat_time ) true ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff ifelse if mem foo_stat.st_atime sys/types.h sys/stat.h { #define ATIME 1 } elif mem foo_stat.st_ctime sys/types.h sys/stat.h { #define CTIME 1 } elif mem foo_stat.st_mtime sys/types.h sys/stat.h { #define MTIME 1 } else pass{ no_stat_time=1 }end { #define NOTIME 1 } endif if ( !no_stat_time ) { #define YESTIME 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _ifelse_H #define _ifelse_H 1 #define _sys_types 1 /* #include ok */ #define _sys_stat 1 /* #include ok */ #define NOTIME 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is sys/stat.h a header ... yes iffe: test: is foo_stat a type or typedef ... no iffe: test: is st_atime a member of struct foo_stat ... no iffe: test: is st_ctime a member of struct foo_stat ... no iffe: test: is st_mtime a member of struct foo_stat ... no iffe: test: is ( !no_stat_time ) true ... no' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'set explicit iff previous hdr stdio if hdr stdio { OK } else { OK } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _previous_H #define _previous_H 1 #define _hdr_stdio 1 /* #include ok */ OK #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes' EXEC -r -v -s bsh - t.iffe TEST 04 'test variable/macro override' EXEC -r -v - t.iffe INPUT t.iffe $'iff macro HAVE_STDIO = hdr stdio' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define HAVE_STDIO 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if hdr - stdio { #define HIT 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define HIT 1 #endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if - hdr stdio { #define HIT 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if ? hdr stdio { #define HIT 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if hdr - stdio { #define HIT 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if HAVE_STDIO = hdr stdio { #define HIT 1 } endif if ( HAVE_STDIO ) { #define TOO ALSO } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define HAVE_STDIO 1 /* #include ok */ #define HIT 1 #define TOO ALSO #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is ( HAVE_STDIO ) true ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if HAVE_STDIO = hdr stdio { #define HIT 1 } endif exp ALSO HAVE_STDIO' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define HAVE_STDIO 1 /* #include ok */ #define HIT 1 #define ALSO 1 /* HAVE_STDIO is true */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is HAVE_STDIO true ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if HAVE_STDIO = hdr stdio { #define HIT 1 } endif ALSO = ( HAVE_STDIO )' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define HAVE_STDIO 1 /* #include ok */ #define HIT 1 #define ALSO 1 /* ( HAVE_STDIO ) is true */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is ( HAVE_STDIO ) true ... yes' EXEC -r -v -s bsh - t.iffe TEST 05 'test code option sequence' EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 1 && B == 0 #define t long #else #define t error #endif t n = 0; }end' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #define _seq 1 /* long int type */ #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 1 #define t long #else #define t error #endif t n = 0; }end' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 0 && B == 1 #define t long #else #define t error #endif t n = 0; }end' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 2 #define t long #else #define t error #endif t n = 0; }end' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 0 && B == 0 #define t long #else #define t error #endif t n = 0; }end' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... no' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro tst seq -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 0 #define t long #else #define t error #endif t n = 0; }end' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 1 && B == 0 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ /* long int type */ #define seq 1 #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 1 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 0 && B == 1 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 2 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DA=1 - -DB=1 note{ long int type }end compile{ #if A == 0 && B == 0 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... no' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst -DG=1 - -DN=1 - -DN=2 note{ long int type }end compile{ #if G == 1 && N == 0 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DN=1 - -DN=2 - -DN=3 note{ long int type }end compile{ #if N == 1 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ /* long int type */ #define seq 1 #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DN=1 - -DN=2 - -DN=3 note{ long int type }end compile{ #if N == 2 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DN=1 - -DN=2 - -DN=3 note{ long int type }end compile{ #if N == 3 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... iffe: test: long int type ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v - t.iffe INPUT t.iffe $'iff macro if tst - -DN=1 - -DN=2 - -DN=3 note{ long int type }end compile{ #if N == 0 #define t long #else #define t error #endif t n = 0; }end { #define seq 1 } endif' OUTPUT - '/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _macro_H #define _macro_H 1 #define _sys_types 1 /* #include ok */ #endif' ERROR - 'iffe: test: is sys/types.h a header ... yes iffe: test: long int type ... iffe: test: long int type ... iffe: test: long int type ... no' EXEC -r -v -s bsh - t.iffe TEST 06 'block side effects' EXEC -r - t.iffe INPUT t.iffe $'iff - tst output{ int main() { printf("HIT\\n"); return 0; } }end' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #define _sys_types 1 /* #include ok */ HIT' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'iff tst - output{ int main() { printf("HIT\\n"); return 0; } }end' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'iff tst - output{ int main() { printf("HIT\\n"); return 1; } }end' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #define _sys_types 1 /* #include ok */' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'iff tst - nooutput{ int main() { printf("HIT\\n"); return 1; } }end' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #define _sys_types 1 /* #include ok */ HIT' EXEC -r -s bsh - t.iffe TEST 07 'diagnostics' EXEC -r - t.iffe INPUT t.iffe $'tst foo' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #endif' ERROR - $'iffe: t.iffe:1: tst: unknown feature test' EXIT 1 EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'if (1)' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */' ERROR - $'iffe: t.iffe:1: missing endif' EXIT 1 EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'if' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */' ERROR - $'iffe: t.iffe:1: missing endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'endif' ERROR - $'iffe: t.iffe:1: endif: no matching if' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'if { }end' ERROR - $'iffe: t.iffe:2: missing }' EXEC -r -s bsh - t.iffe TEST 08 'negation consternation' EXEC -r - t.iffe INPUT t.iffe $'npt fopen,fooon stdio.h' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdlib 1 /* #include ok */ #define _hdr_unistd 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _npt_fooon 1 /* fooon() needs a prototype */ #endif' EXEC -r -u - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdlib 1 /* #include ok */ #define _hdr_unistd 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #undef _npt_fopen /* fopen() does not need a prototype */ #define _npt_fooon 1 /* fooon() needs a prototype */ #endif' EXEC -r -a - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdlib 1 /* #include ok */ #define _hdr_unistd 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define _npt_fopen 0 /* fopen() does not need a prototype */ #define _npt_fooon 1 /* fooon() needs a prototype */ #endif' EXEC -r -C - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define HAVE_SYS_TYPES_H 1 /* #include ok */ #define HAVE_STDLIB_H 1 /* #include ok */ #define HAVE_UNISTD_H 1 /* #include ok */ #define HAVE_STDIO_H 1 /* #include ok */ #define HAVE_FOPEN_DECL 1 /* fopen() does not need a prototype */ #undef HAVE_FOOON_DECL /* fooon() needs a prototype */ #endif' EXEC -r - t.iffe INPUT t.iffe $'NEED_FOPEN = npt fopen stdio.h HAVE_FOPEN = ! npt fopen stdio.h NEED_FOOON = npt fooon stdio.h HAVE_FOOON = ! npt fooon stdio.h' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdlib 1 /* #include ok */ #define _hdr_unistd 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #define HAVE_FOPEN 1 /* fopen() does not need a prototype */ #define NEED_FOOON 1 /* fooon() needs a prototype */ #endif' EXEC -r -u - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_stdlib 1 /* #include ok */ #define _hdr_unistd 1 /* #include ok */ #define _hdr_stdio 1 /* #include ok */ #undef NEED_FOPEN /* fopen() does not need a prototype */ #define HAVE_FOPEN 1 /* fopen() does not need a prototype */ #define NEED_FOOON 1 /* fooon() needs a prototype */ #undef HAVE_FOOON /* fooon() needs a prototype */ #endif' EXEC -r -C - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define HAVE_SYS_TYPES_H 1 /* #include ok */ #define HAVE_STDLIB_H 1 /* #include ok */ #define HAVE_UNISTD_H 1 /* #include ok */ #define HAVE_STDIO_H 1 /* #include ok */ #undef NEED_FOPEN /* fopen() does not need a prototype */ #define HAVE_FOPEN 1 /* fopen() does not need a prototype */ #define NEED_FOOON 1 /* fooon() needs a prototype */ #undef HAVE_FOOON /* fooon() needs a prototype */ #endif' TEST 09 'exp vs. if' EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_false { ONE } exp _tst_hit !_tst_hit&_tst_true pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_false is true */ /* !_tst_false */ ONE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&_tst_true pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_hit&_tst_true is true */ TWO 0 1 #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&_tst_false pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_hit&_tst_true is true */ /* !_tst_hit&_tst_true */ THREE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&_tst_false pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_false { ONE } exp _tst_hit !_tst_hit&&_tst_true pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_false is true */ /* !_tst_false */ ONE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&&_tst_true pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_hit&&_tst_true is true */ TWO 0 1 #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&&_tst_false pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #define _tst_hit 1 /* !_tst_hit&&_tst_true is true */ /* !_tst_hit&&_tst_true */ THREE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) exp _tst_hit !_tst_true { ONE } exp _tst_hit !_tst_hit&&_tst_false pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_false ) { ONE } elif ( _tst_true ) pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ ONE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_true ) { ONE } elif ( _tst_true ) pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ TWO #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_true ) { ONE } elif ( _tst_false ) pass{ cat < ok */ #define _tst_true 1 /* ( 1 ) is true */ THREE #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_true ) yes{ typedef struct { int dd_fd; /* file descriptor */ } DIR; }end endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _tst_true 1 /* ( 1 ) is true */ #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_true ) { typedef struct { int dd_fd; /* file descriptor */ } DIR; } else { OK } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _tst_true 1 /* ( 1 ) is true */ OK #endif' EXEC -r -s bsh - t.iffe EXEC -r - t.iffe INPUT t.iffe $'_tst_false = ( 0 ) _tst_true = ( 1 ) if ( ! _tst_true ) { typedef struct { int dd_fd; /* file descriptor */ }; } else { OK } endif' EXEC -r -s bsh - t.iffe TEST 10 'exp details' EXEC -r -v - t.iffe INPUT t.iffe $'_str = "string" _hdr =
_aaa = ( 0 ) _zzz = ( 1 ) ( _str ) ( ! _str ) ( _hdr ) ( ! _hdr ) ( _aaa ) ( ! _aaa ) ( _zzz ) ( ! _zzz )' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _str "string" #define _hdr
#define _zzz 1 /* ( 1 ) is true */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is ( 0 ) true ... no iffe: test: is ( 1 ) true ... yes iffe: test: is ( _str ) true ... yes iffe: test: is ( ! _str ) true ... no iffe: test: is ( _hdr ) true ... yes iffe: test: is ( ! _hdr ) true ... no iffe: test: is ( _aaa ) true ... no iffe: test: is ( ! _aaa ) true ... yes iffe: test: is ( _zzz ) true ... yes iffe: test: is ( ! _zzz ) true ... no' EXEC -r -v -s bsh - t.iffe TEST 11 'set [no]define' EXEC -r -v - t.iffe INPUT t.iffe $'set nodefine mem stat.st_mtime sys/types.h sys/stat.h set define mem stat.st_mode sys/types.h sys/stat.h if ( _mem_st_mtime_stat ) { 1 } endif if ( _mem_st_mode_stat ) { 2 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _mem_st_mode_stat 1 /* st_mode is a member of struct stat */ 1 2 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is sys/stat.h a header ... yes iffe: test: is stat a type or typedef ... no iffe: test: is st_mtime a member of struct stat ... yes iffe: test: is st_mode a member of struct stat ... yes iffe: test: is ( _mem_st_mtime_stat ) true ... yes iffe: test: is ( _mem_st_mode_stat ) true ... yes' EXEC -r -v -s bsh - t.iffe TEST 12 'non-opaque mem' EXEC -r -v - mem OPAQUE -I. t.h INPUT t.h $'typedef struct opaque OPAQUE;' OUTPUT - $'/* : : generated by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_t 1 /* #include ok */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is t.h a header ... yes iffe: test: is OPAQUE a type or typedef ... no iffe: test: is struct OPAQUE a non-opaque struct ... no' EXEC -r -v - mem NONOPAQUE -I. t.h INPUT t.h $'struct nonopaque { int pad; }; typedef struct nonopaque NONOPAQUE;' OUTPUT - $'/* : : generated by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _hdr_t 1 /* #include ok */ #define _mem_NONOPAQUE 1 /* NONOPAQUE is a non-opaque struct */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is t.h a header ... yes iffe: test: is NONOPAQUE a type or typedef ... yes iffe: test: is NONOPAQUE a non-opaque struct ... yes' TEST 13 'key states' EXEC -r -v - t.iffe INPUT t.iffe $'key int key const = key foo key bar = key aha = huh = int key chr = char = int' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _key_int 1 /* int is a reserved keyword */ #define _key_const 1 /* const is a reserved keyword */ #define bar /* default for reserved keyword bar */ #define aha int /* default for reserved keyword aha */ #define _key_char 1 /* char is a reserved keyword */ #define chr char /* alternate for reserved keyword chr */ #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is int a reserved keyword ... yes iffe: test: is const a reserved keyword ... yes iffe: test: is foo a reserved keyword ... no iffe: test: is bar a reserved keyword ... no iffe: test: is aha a reserved keyword ... no iffe: test: is huh a reserved keyword ... no iffe: test: is chr a reserved keyword ... no iffe: test: is char a reserved keyword ... yes' EXEC -r -v -s bsh - t.iffe EXEC -u -r -v - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _key_int 1 /* int is a reserved keyword */ #define _key_const 1 /* const is a reserved keyword */ #undef _key_foo /* foo is not a reserved keyword */ #undef _key_bar /* bar is not a reserved keyword */ #define bar /* default for reserved keyword bar */ #undef _key_huh /* huh is not a reserved keyword */ #define aha int /* default for reserved keyword aha */ #define _key_char 1 /* char is a reserved keyword */ #define chr char /* alternate for reserved keyword chr */ #endif' EXEC -u -r -v -s bsh - t.iffe EXEC -a -r -v - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define _key_int 1 /* int is a reserved keyword */ #define _key_const 1 /* const is a reserved keyword */ #define _key_foo 0 /* foo is not a reserved keyword */ #define _key_bar 0 /* bar is not a reserved keyword */ #define bar /* default for reserved keyword bar */ #define _key_huh 0 /* huh is not a reserved keyword */ #define aha int /* default for reserved keyword aha */ #define _key_char 1 /* char is a reserved keyword */ #define chr char /* alternate for reserved keyword chr */ #endif' EXEC -a -r -v -s bsh - t.iffe EXEC -C -r -v - t.iffe OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define HAVE_SYS_TYPES_H 1 /* #include ok */ #define HAVE_INT_RESERVED 1 /* int is a reserved keyword */ #define HAVE_CONST_RESERVED 1 /* const is a reserved keyword */ #undef HAVE_FOO_RESERVED /* foo is not a reserved keyword */ #undef HAVE_BAR_RESERVED /* bar is not a reserved keyword */ #define bar /* default for reserved keyword bar */ #undef HAVE_HUH_RESERVED /* huh is not a reserved keyword */ #define aha int /* default for reserved keyword aha */ #define HAVE_CHAR_RESERVED 1 /* char is a reserved keyword */ #define chr char /* alternate for reserved keyword chr */ #endif' EXEC -C -r -v -s bsh - t.iffe TEST 14 'inc file' EXEC -r -v - t.iffe INPUT t.iffe $'inc t_lib.h if ( bar_foo ) { #define all 1 } elif ( _foo_bar ) { #define some 1 } endif' INPUT t_lib.h '#define bar_foo ALL #define _foo_bar SOME' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define some 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is ( bar_foo ) true ... no iffe: test: is ( _foo_bar ) true ... yes' EXEC -r -v - t.iffe INPUT t.iffe $'inc t_lib.h . if ( bar_foo ) { #define all 1 } elif ( _foo_bar ) { #define ok 1 } endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define all 1 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is ( bar_foo ) true ... yes' EXEC -r -v - t.iffe INPUT t.iffe $'inc t_lib.h . ? if ( bar_foo ) { #define all 1 } elif ( _foo_bar ) { #define ok 1 } endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: t.iffe:1: warning: ?: operands ignored iffe: test: is ( bar_foo ) true ... yes' EXEC -r -v - t.iffe INPUT t.iffe $'inc foo_lib.h' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: t.iffe:1: foo_lib.h: file not found' EXIT 1 EXEC -r -v - t.iffe INPUT t.iffe $'inc' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: t.iffe:1: path expected' TEST 15 'KnR compatibility' EXEC -r -v - t.iffe INPUT t.iffe $' if ( 1 ) { #define all 1 } endif if ( 2 ) { #define some 1 } endif cat{ #define a 1 #define b 2 #define c 3 #define d 4 }end' #define _foo_bar SOME' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define some 1 #endif' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #define all 1 #define some 1 #define a 1 #define b 2 #define c 3 #define d 4 #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is ( 1 ) true ... yes iffe: test: is ( 2 ) true ... yes iffe: test: cat{ ... }end ... yes' EXEC -r -v -s bsh - t.iffe EXEC -r -v -s osh - t.iffe TEST 16 '{ define extern include print }' EXEC -r -v - t.iffe INPUT t.iffe $' print /* test header */ header stdio.h define EOF -1 define FoobaR (a,b) ((a)+(b)) define FoomaC -1 extern fopen FILE* (char*, char*) extern BarfoO struct barfoo* (int) extern Tab_lE struct barfoo* [10]' OUTPUT - $'/* test header */ /* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _REGRESS #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #include #define FoobaR(a,b) ((a)+(b)) #define FoomaC -1 extern struct barfoo* BarfoO(int); extern struct barfoo* Tab_lE[10]; #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes iffe: test: is EOF a macro ... yes iffe: test: is FoobaR a macro ... no iffe: test: is FoomaC a macro ... no iffe: test: is fopen a symbol that needs a prototype ... no iffe: test: is BarfoO a symbol that needs a prototype ... yes iffe: test: is Tab_lE a symbol that needs a prototype ... yes' TEST 17 'features/* => FEATURE/*' EXEC -r -v run features/stdio INPUT features/stdio $'set prototyped header stdio.h' OUTPUT FEATURE/stdio $' /* : : generated by proto : : */ /* : : generated from features/stdio by iffe version 1995-03-19 : : */ #ifndef _REGRESS #if !defined(__PROTO__) # if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus) # if defined(__cplusplus) # define __LINKAGE__ "C" # else # define __LINKAGE__ # endif # define __STDARG__ # define __PROTO__(x) x # define __OTORP__(x) # define __PARAM__(n,o) n # if !defined(__STDC__) && !defined(__cplusplus) # if !defined(c_plusplus) # define const # endif # define signed # define void int # define volatile # define __V_ char # else # define __V_ void # endif # else # define __PROTO__(x) () # define __OTORP__(x) x # define __PARAM__(n,o) o # define __LINKAGE__ # define __V_ char # define const # define signed # define void int # define volatile # endif # define __MANGLE__ __LINKAGE__ # if defined(__cplusplus) || defined(c_plusplus) # define __VARARG__ ... # else # define __VARARG__ # endif # if defined(__STDARG__) # define __VA_START__(p,a) va_start(p,a) # else # define __VA_START__(p,a) va_start(p) # endif # if !defined(__INLINE__) # if defined(__cplusplus) # define __INLINE__ extern __MANGLE__ inline # else # if defined(_WIN32) && !defined(__GNUC__) # define __INLINE__ __inline # endif # endif # endif #endif #if !defined(__LINKAGE__) #define __LINKAGE__ /* 2004-08-11 transition */ #endif #define _REGRESS 1 #define _sys_types 1 /* #include ok */ #include #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes iffe: test: is stdio.h a header ... yes' TEST 18 'api + ver' EXEC -r -v - t.iffe INPUT t.iffe $'iff api ver foo 20100606 ver bar 19840919 api foo 19991231 dis dat tother api foo 20100601 dat api foo 20100606 dis api bar 19991231 moe larry shemp api bar 20020202 curly api bar 20030303 shemp api bar 20040404 joe_b api bar 20050505 joe_d ' OUTPUT - $'/* : : generated from t.iffe by iffe version 1995-03-19 : : */ #ifndef _api_H #define _api_H 1 #define _sys_types 1 /* #include ok */ #define FOO_VERSION 20100606 #define BAR_VERSION 19840919 #define FOOAPI(rel) ( _BLD_foo || !_API_foo || _API_foo >= rel ) #if !defined(_API_foo) && defined(_API_DEFAULT) #define _API_foo _API_DEFAULT #endif #if FOOAPI(20100601) #undef dat #define dat dat_20100601 #elif _API_foo >= 19991231 #undef dat #define dat dat_19991231 #endif #if FOOAPI(20100606) #undef dis #define dis dis_20100606 #elif _API_foo >= 19991231 #undef dis #define dis dis_19991231 #endif #if FOOAPI(19991231) #undef tother #define tother tother_19991231 #endif #define _API_foo_MAP "dat_20100601 dat_19991231 dis_20100606 dis_19991231 tother_19991231" #define BARAPI(rel) ( _BLD_bar || !_API_bar || _API_bar >= rel ) #if !defined(_API_bar) && defined(_API_DEFAULT) #define _API_bar _API_DEFAULT #endif #if BARAPI(20020202) #undef curly #define curly curly_20020202 #endif #if BARAPI(20040404) #undef joe_b #define joe_b joe_b_20040404 #endif #if BARAPI(20050505) #undef joe_d #define joe_d joe_d_20050505 #endif #if BARAPI(19991231) #undef larry #define larry larry_19991231 #endif #if BARAPI(19991231) #undef moe #define moe moe_19991231 #endif #if BARAPI(20030303) #undef shemp #define shemp shemp_20030303 #elif _API_bar >= 19991231 #undef shemp #define shemp shemp_19991231 #endif #define _API_bar_MAP "curly_20020202 joe_b_20040404 joe_d_20050505 larry_19991231 moe_19991231 shemp_20030303 shemp_19991231" #endif' ERROR - $'iffe: test: is sys/types.h a header ... yes' ksh-1.0.0-beta.2/src/cmd/INIT/ignore.sh000066400000000000000000000035441415700074400172720ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## # non-ksh script for the nmake ignore prefix # @(#)ignore (AT&T Research) 1992-08-11 (command set -o posix) 2>/dev/null && set -o posix modern_export=`v=; export v=ok 2>/dev/null; echo "$v"` while : do case $# in 0) exit 0 ;; esac case $1 in *=*) case $modern_export in ok) export "$1" ;; *) `echo $1 | sed "s/\\([^=]*\\)=\\(.*\\)/eval \\1='\\2'; export \\1/"` ;; esac shift ;; *) break ;; esac done "$@" exit 0 ksh-1.0.0-beta.2/src/cmd/INIT/intl.c000066400000000000000000000030101415700074400165510ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #ifndef gettext #include #endif int main() { gettext(0); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/ld.hp.pa000077500000000000000000000002071415700074400167760ustar00rootroot00000000000000: hp.pa ld wrapper for reasonable warning defaults # @(#)ld.hp.pa (AT&T Labs Research) 1998-01-23 /bin/ld +s +vnocompatwarnings "$@" ksh-1.0.0-beta.2/src/cmd/INIT/ldd.cygwin.i386000077500000000000000000000005641415700074400201320ustar00rootroot00000000000000#!/bin/env sh : cygwin.i386 ldd -- how many ways does this confirm the Windows bias? for f do case $f in *.exe) ;; *) f=$f.exe ;; esac p=$(type $f) case $p in *" not found"*) ;; *) p=${p##* } case $p in ?*) f=$p ;; esac ;; esac cygcheck $(cygpath -aw $f) | for w in $(sed -e 's/^[[:space:]]*//' -e '/^$/d' -e '/^Use /d') do cygpath -u "$w" done done ksh-1.0.0-beta.2/src/cmd/INIT/ldd.darwin000077500000000000000000000000351415700074400174170ustar00rootroot00000000000000: Mac OS X ldd otool -L "$@" ksh-1.0.0-beta.2/src/cmd/INIT/ldd.hp.pa000077500000000000000000000004611415700074400171440ustar00rootroot00000000000000: hp.pa ldd while : do case $# in 0) break ;; esac case $1 in -*|+*) ;; *) break ;; esac shift done trap ':' 15 for cmd do case $# in 1) ;; *) echo $cmd: ;; esac _HP_DLDOPTS=-ldd "$cmd" < /dev/null 2> /dev/null | sort -u # chatr "$cmd" | # sed -e '/^[ ]*dynamic[ ][ ]*/!d' -e 's// /' done ksh-1.0.0-beta.2/src/cmd/INIT/ldd.ibm.risc000077500000000000000000000003171415700074400176440ustar00rootroot00000000000000: ibm.risc ldd case $# in 1) header=0 ;; *) header=1 ;; esac for file do case $header in 1) echo "$file:" header=2 ;; 2) echo echo "$file:" ;; esac dump -H "$file" | sed '1,/\*\*\*Import/d' done ksh-1.0.0-beta.2/src/cmd/INIT/ldd.lynxos000077500000000000000000000000671415700074400174740ustar00rootroot00000000000000elflook -L "$@" | sed -e '/^NEEDED:/!d' -e 's/.*: *//' ksh-1.0.0-beta.2/src/cmd/INIT/ldd.mvs.390000077500000000000000000000003721415700074400172560ustar00rootroot00000000000000: mvs.390 ldd case $# in 1) header=0 ;; *) header=1 ;; esac for file do case $header in 1) echo "$file:" header=2 ;; 2) echo echo "$file:" ;; esac strings $file | sed -e '/\<[[:lower:]][[:alnum:]]*\.dll\>/!d' -e 's/^/ /' | sort -u done ksh-1.0.0-beta.2/src/cmd/INIT/ldd.sgi000077500000000000000000000000361415700074400167160ustar00rootroot00000000000000: sgi.mips ldd odump -Dl "$@" ksh-1.0.0-beta.2/src/cmd/INIT/m.c000066400000000000000000000030541415700074400160470ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #1 */ #ifndef sin #include #endif int main() { sin(0.0); fmod(100.234, 11.0); return 0; } ksh-1.0.0-beta.2/src/cmd/INIT/m2.c000066400000000000000000000031431415700074400161300ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #2 */ #include int main() { double value = 0; int exp = 0; int r = 0; r |= ldexp(value, exp) != 0; r |= frexp(value, &exp) != 0; return r; } ksh-1.0.0-beta.2/src/cmd/INIT/m3.c000066400000000000000000000031541415700074400161330ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #3 */ #include int main() { long double value = 0; int exp = 0; int r = 0; r |= ldexpl(value, exp) != 0; r |= frexpl(value, &exp) != 0; return r; } ksh-1.0.0-beta.2/src/cmd/INIT/m4.c000066400000000000000000000030271415700074400161330ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #4 */ #include int main() { double value = 0; return isnan(value); } ksh-1.0.0-beta.2/src/cmd/INIT/m5.c000066400000000000000000000030351415700074400161330ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #5 */ #include int main() { long double value = 0; return isnanl(value); } ksh-1.0.0-beta.2/src/cmd/INIT/m6.c000066400000000000000000000030671415700074400161410ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * -lm test #6 */ #define _ISOC99_SOURCE 1 #include int main() { double value = -0.0; return !signbit(value); } ksh-1.0.0-beta.2/src/cmd/INIT/make.probe000066400000000000000000001356151415700074400174260ustar00rootroot00000000000000: ### this script contains archaic constructs that work with all sh variants ### # Glenn Fowler # AT&T Research # # @(#)make.probe (AT&T Research) 2011-06-01 # # C probe for make # # NOTE: C.probe must be included or .'d here # cc_dll_def=-D_BLD_DLL probe_ar_arflags="-Xany" probe_arflags="-xar" probe_ccs="strip size nm ld ar" # longest to shortest probe_debug="-g" probe_dll="'-G 0' -Wc,dll,exportall,longname,rent -Wc,exportall -dynamic $cc_dll_def" probe_export_dynamic="-rdynamic -export-dynamic -Wl,-export-dynamic -Wl,-E -bexpall -force_flat_namespace" probe_gcc_optimize="-Os" probe_gcc_version="*[Gg][Cc][Cc]*" probe_include_local="'-ignore-source-dir -iquote' -iquote -I-" probe_ldlazy='-zlazyload -znolazyload -Wl,-zlazyload -Wl,-znolazyload' probe_ldlib="LD_LIBRARY_PATH LIBPATH LPATH" probe_ldmap="'-Wl,-M' '-Qoption ld -M' '-Wl,-m' '-m'" probe_ldorigin="-Wl,-z,origin" probe_ldrecord='-zrecord -zignore -Wl,-zrecord -Wl,-zignore' probe_ldrunpath="-Wl,-R, -R -Wl,-rpath, -L" probe_ldstrip="'-s -mr' -Wl,-s" probe_lib="a lib" probe_lib_append="/usr/lib/pa1.1" probe_lib_all_undef="-all -notall -all -none -Bwhole-archive -Bno-whole-archive -whole-archive -no-whole-archive -Wl,-whole-archive -Wl,-no-whole-archive -all_load '' -Wl,-zallextract -Wl,-zdefaultextract +forceload +noforceload" probe_lib_multiple="-Wl,-zmuldefs" probe_libdir="shlib lib" probe_nmflags="'' -p -B" probe_optimize="-Os -O" probe_pic="-Kpic -KPIC -fpic -fPIC -pic -PIC +z +Z" probe_no_protect="'-fno-stack-protector -fno-stack-protector-all' -GS-" probe_readonly="-R -Krodata -xMerge -Wa,-r" probe_shared="'' -G -b -c -shared -Wl,dll" probe_shared_name="-Wl,-soname= -h" probe_shared_nostart="-nostartfiles" case `gcc -v 2>&1 | egrep gcc.version` in *version' '[0123456].*) ;; *) probe_shared_nostart= ;; # gcc 7+ esac probe_shared_registry='"-update_registry $probe_shared_registry_file"' probe_shared_registry_file='registry.ld' probe_shared_registry_path="\$(LIBDIR)/$probe_shared_registry_file" probe_strict="'-ansi -pedantic' '-ansi -strict' -strict -ansi" probe_stripflags="'-f -s' -f -s" probe_unresolved="'-expect_unresolved \"*\"'" probe_warn="-Wall -fullwarn -w3 '-A -A' +w1" echo '#pragma pp:version' > libpp.$src echo '#define dDflag on' > dDflag.$src echo 'int main(){return 0;}' > doti.$src echo 'int code(){return 0;} int main(){return code();}' > export.$src echo '#include ' > imstd.$src echo '#include "_i_.h"' > imusr.$src echo 'int x;' > _i_.h mkdir im echo '(' > im/stdio.h echo '#include "implc_x.h" int main(){f(1);return 0;}' > implc.$src echo 'template void f(T){}' > implc_x.$src echo 'template void f(T);' > implc_x.h echo 'extern int NotalL(){return(0);}' > notall.$src echo '#include extern int i; int i = 1; extern int f(){return(!i);} int main(){FILE* fp=stdin;return(f());}' > pic.$src echo 'class x {int n;} m;' > plusplus.$src echo 'int prefix(){return 0;}' > prefix.$src echo 'template int gt(T a, T b); template int gt(T a, T b) { return a > b; } int main () { return gt(2,1); }' > ptr.$src echo 'int main(){return 0;}' > require.$src echo '#if mips && !sgi || __CYGWIN__ ( /* some systems choke on this probe */ #else #if test_const #define CONST const #else #define CONST #endif CONST char x[]={1,2,3,4,5,6,7,8,9,0}; int main(){*(char*)x=0; return x[0];} #endif' > readonly.$src # NOTE: sfclose() defined on UWIN, not defined on all other systems echo 'extern int sfclose(); extern int ShareD(){return(sfclose());}' > shared.$src echo '#define g(a,b) a ## b volatile int a; const int g(x,y)=1; extern int c(int);' > stdc.$src echo 'extern int f(); int main() { return f(); }' > sovmain.$src echo 'int f() { return 0; }' > sovlib.$src echo '#include int i; int main(){int j;j = i * 10;return j;}' > strip.$src echo 'template void f(T){} int main(){f(1);return 0;}' > toucho.$src echo '#if defined(__STDC__) || defined(__cplusplus) extern type call(int); #endif int main() {call(0);return(0);}' > tstlib.$src echo 'int main(){return 0;}' > warn.$src echo 'int f(){return 0;}' > warn1.$src echo 'int f(){}' > warn2.$src echo 'int f(){int i; return 0;}' > warn3.$src echo 'int f(){int i; return i;}' > warn4.$src echo 'int f(){return g();}' > warn5.$src warn_enum="1 2 3 4 5" chmod -w *.$src ar_arflags= arflags= cc_dll= cc_pic= cc_PIC= dDflag= debug= dialect= dll_dir='$(LIBDIR)' dll_libraries= dll_variants= doti= exectype= export_dynamic= gnu= implicitc= include_local= lddynamic= ldlazy= ldnolazy= ldnorecord= ldorigin= ldrecord= ldrunpath= ldscript= ldstatic= ldstrip= Lflag= lib_dll= lib_all= lib_undef= libpath= libpp= makeoptions= nmedit= nmflags= no_protect= optimize= plusplus= prefix_archive=lib prefix_dynamic= prefix_shared=lib ptrcopy= ptrimplicit= ptrmkdir= readonly= repository= require= runpath= shared= shared_name= shared_registry= shellmagic= soversion= stdc= strict= stripflags= symprefix= toucho= warn= set $probe_lib lib=$1 d= for f in $stdinclude $usrinclude do case $f in -I*) ;; *) d="$d $f" ;; esac done stdinclude=$d set x $cc cc_dir=`echo $2 | sed -e 's,/*[^/]*$,,'` for c in $probe_ccs do if $executable $cc_dir/$c then x=$cc_dir/$c else x=$c fi eval $c='$x' done ld_dir= rm -f doti.$obj if $cc -c doti.$src then eval set x $probe_verbose shift for o do $cc $o doti.$obj $cc $o doti.$obj -lF0oB@r done 2>&1 | sed -e 's/^[+ ]*//' -e 's/[ ].*//' -e '/^\//!d' -e 's/:$//' -e '/ld[a-zA-Z0-9.]*$/!d' -e 's,///*,/,g' > t for i in `cat t` do rm -f t.$obj if test -x $i && $i -r -o t.$obj doti.$obj && test -f t.$obj then case $ld in ld) ld=$i ;; esac ld_dir=`echo $i | sed 's,/[^/]*$,,'` break fi done fi IFS=: set x $PATH IFS=$ifs path=$* m= for c in $probe_ccs do eval o='$'$c case $o in $c) ;; *) continue ;; esac C='${c}' for x in $cc_dir $ld_dir do cd $x for p in "${C}" "${C}[!a-zA-Z]*" "*[!a-zA-Z]${C}" "*[!a-zA-Z]${C}[!a-zA-Z]*" do eval set x $p case $# in 2) if $executable $2 then case $2 in *$c*$c*);; *) m=$p break 3 ;; esac fi ;; esac done done done cd $tmpdir for c in $probe_ccs do eval o='$'$c case $o in $c) ;; *) continue ;; esac for x in $cc_dir $ld_dir do if $executable $x/$c then eval $c='$x/$c' continue 2 fi case $m in ?*) eval set x $x/$m case $# in 2) if $executable $2 then eval $c='$2' continue 2 fi ;; esac ;; esac done for x in $path do if $executable $x/$c then eval $c='$x/$c' break fi done done dld=$cc rm -f dynamic.$exe if $cc -o dynamic.$exe dynamic.$obj && $executable dynamic.$exe then mkdir mylib echo > mylib/libc.$lib eval set x $probe_ldlib while : do shift case $# in 0) break ;; esac rm -f dynamic.$exe if eval $1=./mylib '$'cc -o dynamic.$exe dynamic.$obj then : else libpath=$1 break fi done fi test `$cc -E libpp.$src | grep -c '^#pragma pp:version "libpp '` -eq 1 && libpp=1 $cc -E doti.$src > doti.i && $cc -c doti.i && test -s doti.$obj && doti=1 if $cc -c imusr.$src then eval set x $probe_include_local while : do shift case $# in 0) break ;; esac if $cc -c $1 imusr.$src then : "$1 should skip \"_i_.h\" in ." elif $cc -c imstd.$src then if $cc -c -Iim imstd.$src then : '-Idir should find in dir' elif $cc -c $1 -Iim imstd.$src then : "$1 -Idir should find in dir" elif $cc -c -Iim $1 imstd.$src then include_local=$1 break else : "-Idir $1 should skip in dir" fi else : should find stdio.h fi done else : 'should find "_i_.h" in .' fi if $cc -c pic.$src 2>e then e=`wc -l e` s=`$size pic.$obj; wc pic.$obj` eval set x $probe_pic shift while : do case $# in 0|1) break ;; esac pic=$1 shift PIC=$1 shift rm -f pic.$obj $cc $pic -c pic.$src 2>e && test -f pic.$obj || continue $cc $pic -o pic.$exe pic.$obj && test -f pic.$exe || { rm -f pic.$exe $cc -o pic.$exe pic.$obj && test -f pic.$exe && continue } case `wc -l e` in $e) ;; *) continue ;; esac case $pic in ???*) m=`echo " $pic" | sed -e 's/^ [-+]//g' -e 's/./-& /g' -e 's/[-+] //g'` rm -f pic.$obj pic1.$exe if $cc $m -c pic.$src 2>e && test -f pic.$obj && $cc -o pic1.$exe pic.$obj && test -f pic1.$exe then case `wc -l e` in $e) cc_pic=$m break ;; esac fi cc_pic=$pic break ;; *) case `$size pic.$obj; wc pic.$obj` in $s) ;; *) cc_pic=$pic break ;; esac ;; esac done # this works around gcc 2.95 sun4 -fpic a.out core dump after exit case $hosted:$cc_pic in 1:?*) if ./pic.$exe then # this catches lynxos.ppc gcc that dumps -fpic and not -mshared echo 'static int* f() { static int v; return &v; } int main() { f(); return 0; }' > picok.$src $cc $cc_pic -o picok.$exe picok.$src && ./picok.$exe || cc_pic= else cc_pic= fi ;; esac case $cc_pic in ?*) rm -f pic.$obj if $cc $PIC -c pic.$src 2>e && test -f pic.$obj then cc_PIC=$PIC else cc_PIC=$cc_pic fi ;; *) eval set x $probe_dll while : do shift case $# in 0) break ;; esac rm -f pic.$obj pic.$exe $cc $1 -c pic.$src 2>e && test -f pic.$obj || continue $cc $1 -o pic.$exe pic.$obj && test -f pic.$exe || { rm -f pic.$exe $cc -o pic.$exe pic.$obj && test -f pic.$exe && continue } case $1 in -Wc,*exportall*) # get specific since SGI gets this far too rm -f pic.$exe pic.x $cc -Wl,dll -o pic.$exe pic.$obj || continue test -f pic.$exe || continue test -f pic.x || continue cc_dll="-D_SHARE_EXT_VARS $1" so=.x sd=.dll dld=$cc shared=-Wl,dll prefix_shared= probe_sd= probe_shared= #unused# lddynamic=-Bdynamic #unused# ldstatic=-Bstatic lib_dll=SYMBOL break ;; esac case `wc -l e` in $e) cc_dll=$1 break ;; esac done ;; esac fi $cc -c plusplus.$src && plusplus=1 $cc -E -dD dDflag.$src > t case `grep '#define[ ][ ]*dDflag[ ][ ]*on' t` in ?*) dDflag=1 ;; esac case `grep '#define.*_GNUC_' t` in ?*) gnu=1 ;; esac case $plusplus in "") $cc -c stdc.$src && stdc=1 ;; *) mkdir ptr cd ptr $cc -c ../ptr.$src & NFS_locks_are_botched=$! cd .. if $cc -c require.$src && $cc require.$obj then set x `$cc require.$obj 2>&1` d= while : do shift case $# in 0) break ;; esac case $1 in -l*) d="$d $1" ;; esac done for f in ++ do if $cc require.$obj -l$f then set x `$cc require.$obj -l$f 2>&1` r= while : do shift case $# in 0) break ;; esac case $1 in -l*) case " $d $r " in *" "$1" "*) ;; *) r="$r $1" ;; esac esac done case $r in ?*) require="$require $f" echo '' $r > req.$f ;; esac fi done fi cd ptr for i in * do if test -d $i then repository=$i break fi done cd .. kill -9 $NFS_locks_are_botched rm -rf ptr case $repository in *?) mkdir ptr cd ptr i=PTR case $repository in $i) i=$i$i ;; esac $cc -ptr$i -c ../ptr.$src & NFS_locks_are_botched=$! cd .. sleep 5 if test -d ptr/$i/$repository then ptrimplicit=1 fi kill -9 $NFS_locks_are_botched rm -rf ptr ;; esac $cc -o implc implc.$src && $executable implc && implicitc=1 if $cc -c toucho.$src && test -f toucho.$obj then o=`ls -l toucho.$obj` if $cc -o toucho toucho.$obj && $executable toucho then n=`ls -l touch.$obj` case $n in "$o") ;; *) toucho=1 ;; esac fi fi ;; esac if $cc -c pic.$src then eval set x $probe_nmflags while : do shift case $# in 0) break ;; esac case `$nm $1 pic.$obj | grep -c '[0123456789][ ][ ]*T[ ][ ]*[_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'` in 0) ;; *) nmflags=$1 break ;; esac done case $# in 0) case `$nm -gh pic.$obj | grep -c '|\.*[TtDdBbC][EeAaSsOo][XxTtSsMm]'` in 0) ;; *) nmflags=-gh nmedit="-e '/\.*[TtDdBbC][EeAaSsOo][XxTtSsMm]/!d' -e 's/[| ].*//'" ;; esac ;; *) nmedit="-e '/[ ]T[ ][ ]*[_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]/!d' -e 's/.*[ ]T[ ][ ]*//'" ;; esac fi if $cc -c doti.$src then eval set x $probe_stripflags while : do shift case $# in 0) break ;; esac if $strip $1 doti.$obj then stripflags=$1 break fi done fi rm -f export.$obj export.exe if $cc -c export.$src then lm= if $cc -o export.exe export.$obj -lm 2>e && lm=-lm || $cc -o export.exe export.$obj 2>e then z=`wc -c < export.exe; $size export.exe 2>/dev/null` eval set x $probe_export_dynamic while : do shift case $# in 0) break ;; esac rm -f export.exe if $cc -o export.exe $1 export.$obj $lm 2>f && $executable export.exe then y=`wc -c < export.exe; $size export.exe 2>/dev/null` case $y in $z) ;; *) if cmp -s e f then export_dynamic=$1 break fi ;; esac fi done fi fi rm -f export.$obj export.exe rm -f strip.exe if $cc -o strip.exe strip.$src then z=`wc -c < strip.exe` eval set x $probe_ldstrip while : do shift case $# in 0) break ;; esac rm -f strip.exe if $cc -o strip.exe $1 strip.$src then case `wc -c < strip.exe` in $z) ;; *) ldstrip=$1 break ;; esac fi done fi rm -f strip.exe strip.$obj if $cc -c strip.$src && $cc -o strip.exe strip.$obj 2>e then eval set x x $probe_ldlazy while : do shift shift case $# in 0) break ;; esac rm -f strip.$exe $cc -o strip.$exe $1 strip.$obj $2 2>f && test -f strip.$exe || continue cmp -s e f || continue ldlazy=$1 ldnolazy=$2 break done eval set x x $probe_ldrecord while : do shift shift case $# in 0) break ;; esac rm -f strip.$exe $cc -o strip.$exe $1 strip.$obj $2 2>f && test -f strip.$exe || continue cmp -s e f || continue ldrecord=$1 ldnorecord=$2 break done fi case $cc_dll:$cc_pic:$so:$dynamic:$static in ::::|$cc_dll_def::::) : last chance dynamic checks while : do echo '__declspec(dllexport) int fun() { return 0; }' > exp.$src if $cc -c $cc_dll_def exp.$src then rm -f xxx.dll xxx.lib if $cc -shared -Wl,--enable-auto-image-base -Wl,--out-implib=xxx.lib -o xxx.dll exp.$obj && test -f xxx.lib -a -f xxx.dll then : Cygwin cc_dll=$cc_dll_def dll_dir='$(BINDIR)' sd=.dll so=.dll.a ldscript=".def .exp .ign .res" lib_dll=option lib_all=-Wl,-whole-archive lib_undef=-Wl,-no-whole-archive dld=$cc shared='-shared -Wl,--enable-auto-image-base -Wl,--out-implib=$(<:N=*'$so')' prefix_dynamic=cyg prefix_shared=lib break fi fi break done ;; *) if $cc -c $cc_dll $cc_pic shared.$src && $cc -c $cc_dll $cc_pic notall.$src then for xx in "$cc" "$ld" do eval set x $probe_shared while : do shift case $# in 0) break ;; esac rm -f xxx$dll # UNDENT ... if $xx $1 -o xxx$dll shared.$obj 2>e && test -r xxx$dll then if test -s e && egrep -i 'unknown|invalid|option' e > /dev/null then continue fi case `PATH=/bin:/usr/bin:$PATH file xxx$dll` in *lib*|*obj*|*shared*) ;; "") $executable xxx$dll || continue ;; *ELF*|*elf*) $executable xxx$dll || continue case `strings xxx$dll | sed -e 's,.*[ |],,' | sort -u | egrep -i '^([._](dynamic|dynstr|dynsym))$'` in [012]) continue ;; esac ;; *archive*not*stripped*|*data*dynamic*not*stripped*) $executable xxx$dll || continue ;; *) continue ;; esac dld=$xx shared=$1 # does -nostartfiles make sense for C? case $plusplus in '') z=`wc -c < xxx$dll` eval set x $probe_shared_nostart while : do shift case $# in 0) break ;; esac rm -f xxx$dll if $dld $shared $1 -o xxx$dll shared.$obj 2>e && test -r xxx$dll then case `wc -c < xxx$dll` in $z) ;; *) if test -s e then case `cat e` in *[Ee][Rr][Rr][Oo][Rr]*|*[Ww][Aa][Rr][Nn][Ii][Nn][Gg]*|*[Oo][Pp][Tt][Ii][Oo][Nn]*) continue ;; esac fi case $shared in '') shared=$1 ;; *) shared="$shared $1" ;; esac break ;; esac fi done ;; esac case $cc_dll in "") cc_dll=$cc_dll_def ;; esac eval set x x $probe_sd while : do shift shift case $# in [01]) break ;; esac rm -f xxx xxx$1 xxx$2 if $dld $shared -o xxx shared.$obj 2>e then if test -f xxx$1 -a \( -f xxx$2 -o "$cc_dll" = "$cc_dll_def" \) then sd=$1 so=$2 lddynamic=-Bdynamic ldstatic=-Bstatic break 2 elif test -f xxx -a -f xxx$2 then sd=$1 so=$2 break 2 else case $so in '') so=$1 ;; esac break fi fi done rm -f libxxx.$lib $ar cr libxxx.$lib shared.$obj ranlib libxxx.$lib eval set x x $probe_lib_all_undef rm -f xxx$dll if $dld $shared -o xxx$dll libxxx.$lib && test -r xxx$dll then if $nm $nmflags xxx$dll | grep ShareD then lib_dll=OPTION set x x fi fi while : do shift shift case $# in 0|1) break ;; esac rm -f xxx$dll if $dld $shared -o xxx$dll $1 libxxx.$lib $2 && test -r xxx$dll then if $nm $nmflags xxx$dll | grep ShareD then lib_dll=option lib_all=$1 lib_undef=$2 break fi fi case $2 in ?*) if $dld $shared -o xxx$dll $1 libxxx.$lib && test -r xxx$dll then if $nm $nmflags xxx$dll | grep ShareD then lib_dll=option lib_all=$1 break fi fi ;; esac done case $lib_dll in OPTION) lib_dll=option ;; option) case $lib_undef in "") rm -f libyyy.$lib $ar cr libyyy.$lib notall.$obj ranlib libyyy.$lib $cc -c prefix.$src eval set x x $probe_lib_all_undef while : do shift shift case $# in 0|1) break ;; esac rm -f xxx$dll if $dld $shared -o xxx$dll prefix.$obj $lib_all libxxx.$lib $2 libyyy.$lib && test -r xxx$dll then rm -f t $nm $nmflags xxx$dll > t case `grep -c ShareD t`:`grep -c NotalL t` in 0:*) ;; *:0) lib_undef=$2 break ;; esac fi done ;; esac case $lib_undef in "") eval set x $probe_lib_multiple rm -f libyyy.$lib cp libxxx.$lib libyyy.$lib rm -f xxx$dll if $dld $shared -o xxx$dll prefix.$obj $lib_all libxxx.$lib libyyy.$lib && test -r xxx$dll then : else while : do shift case $# in 0) break ;; esac rm -f xxx$dll if $dld $shared -o xxx$dll prefix.$obj $lib_all $1 libxxx.$lib libyyy.$lib && test -r xxx$dll then rm -f t $nm $nmflags xxx$dll > t case `grep -c ShareD t` in 0) ;; *) lib_all="$lib_all $1" break ;; esac fi done fi lib_dll=symbol ;; esac ;; *) lib_dll=symbol ;; esac case `cat e` in ?*) eval set x $probe_unresolved while : do shift case $# in 0) break ;; esac rm -f xxx$dll if eval '$dld $shared' $1 '-o xxx$dll shared.$obj 2>e && test -r xxx$dll' then case `cat e` in "") shared="$shared $1"; break ;; esac fi done ;; esac r= eval set x $probe_shared_registry while : do shift r=x$r case $# in 0) break ;; esac rm -f xxx$dll if eval \$dld \$shared -o xxx\$dll $1 shared.\$obj && test -r xxx$dll -a -r $probe_shared_registry_file then probe_shared_registry_file='$(CC.SHARED.REGISTRY.PATH)' eval set x $probe_shared_registry i= while : do shift i=x$i case $i in $r) break ;; esac done shared_registry=$1 fi done break 2 fi # ... INDENT done done fi case $so in ?*) rm -f xxx* if $dld $shared -g -o xxx shared.$obj 2>e then set x $probe_sdb while : do shift case $1 in 0) break ;; esac if test -f xxx$1 then sdb=$1 break fi done fi if $cc -c require.$src then p=' /usr/proberun/lib:/local/runprobe/lib ' eval set x $probe_ldrunpath while : do shift case $# in 0) break ;; esac rm -f require.exe if $cc -o require.exe $1"$p" require.$obj && grep -c /proberun/ require.exe >/dev/null && grep -c /runprobe/ require.exe > /dev/null then ldrunpath=$1 eval set x $probe_ldorigin while : do shift case $# in 0) break ;; esac rm -f origin.exe if $cc -o origin.exe $1 $ldrunpath'$ORIGIN' require.$obj then if ./origin.exe > /dev/null 2>&1 then ldorigin="$1 $ldrunpath"'\$ORIGIN/$(BINDIR:P=R=$(DLLDIR))' fi break fi done break fi done fi rm -f libxxx$so if $cc -c sovmain.$src && $cc -c $cc_dll $cc_pic sovlib.c && $dld $shared -o libxxx$so sovlib.$obj && $cc -o sovmain.$exe -L. sovmain.$obj -lxxx then rm -f sovmain.$exe mv libxxx$so libxxx$so.5.6 if $cc -o sovmain.$exe -L. sovmain.$obj -lxxx then soversion=1 fi fi rm -f doti.$obj std64=/lib64 lcl64=/usr/local/lib64 if test -d $std64 -a -d $lcl64 && $cc -c doti.$src then for i in `cd $lcl64; ls *$so 2>/dev/null | sed 's/lib\([^.]*\).*/\1/'` do if $cc -o runpath.$exe doti.$obj -l$i >/dev/null 2>&1 then LD_LIBRARY_PATH= ./runpath.$exe >/dev/null 2>&1 && continue if LD_LIBRARY_PATH=$lcl64 ./runpath.$exe >/dev/null 2>&1 then runpath=$lcl64 break elif LD_LIBRARY_PATH=$std64 ./runpath.$exe >/dev/null 2>&1 then runpath=$std64 break elif LD_LIBRARY_PATH=$lcl64:$std64 ./runpath.$exe >/dev/null 2>&1 then runpath=$lcl64:$std64 break fi fi done fi ;; esac ;; esac rm -f shared.$obj if $cc -c shared.$src then eval set x $probe_ar_arflags while : do shift case $# in 0) break ;; esac rm -f libxxx.$lib if $ar $1 r libxxx.$lib shared.$obj && $ar $1 t libxxx.$lib 2>&1 | grep shared.$obj >/dev/null then ar_arflags=$1 break fi done eval set x $probe_arflags while : do shift case $# in 0) break ;; esac rm -f libxxx.$lib if $cc $1 -o libxxx.$lib shared.$obj && $ar t libxxx.$lib 2>&1 | grep shared.$obj >/dev/null then arflags=$1 break fi done fi case $shared in -G) case $cc_dll in "") cc_dll=$cc_dll_def ;; esac ;; *) case $lib_dll in symbol) echo 'extern int f(); int main() { f(); return 0; }' > main.$src echo '#include int f() { printf("hello world"); return 0; }' > member.$src if $cc -c main.$src && $cc -c member.$src then echo f > lib.exp rm -f lib.$obj main.exe if $ld -o lib.$obj -L: -bexport:lib.exp -berok -bmodtype:SRE -T512 -H512 -lm -lc member.$obj && $cc -o main.exe main.$obj lib.$obj then dld=$ld shared='-T512 -H512 -L$(LIBDIR): -berok -bmodtype:SRE' lib_dll=export dll_libraries='-lm -lc' ldscript=.exp case $cc_dll in "") cc_dll=$cc_dll_def ;; esac case $so in "") so=.$obj ;; esac fi fi ;; esac ;; esac case $shared in ?*) if $cc -c $cc_dll $cc_pic shared.$src then eval set x $probe_shared_name while : do shift case $# in 0) break ;; esac rm -f xxx$dll if $dld $shared ${1}libfoo.1.2 -o xxx$dll shared.$obj 2>e && test -r xxx$dll then shared_name=$1 break fi done fi ;; esac case " $cc_dll " in *" $cc_dll_def "*) ;; " ") ;; *) cc_dll="$cc_dll_def $cc_dll" ;; esac case $hosttype in win32.*|cygwin.*|os2.*) Lflag=1 ;; *) if $cc -c doti.$src then if $cc -L. doti.$obj -lc >/dev/null then case $cc_dll in '') ;; *) Lflag=1 ;; esac fi fi ;; esac case $lib_dll in option) case $hosttype in linux.*) dll_libraries=-lc ;; esac ;; SYMBOL) lib_dll=symbol ;; symbol) echo "#include extern int fun() { puts(\"fun\"); return 0; }" > dllib.$src echo "extern int fun(); int main() { return fun(); }" > dlmain.$src pwd=`pwd` while : do if $cc -c $cc_dll $cc_pic dlmain.$src && $cc -c $cc_dll $cc_pic dllib.$src then rm -f libxxx$so if $dld $shared -o libxxx$so dllib.$obj && chmod 555 libxxx$so then rm -f dlmain.$exe if $cc -o dlmain.$exe dlmain.$obj $pwd/libxxx$so && (./dlmain.$exe) >/dev/null 2>&1 then break fi fi rm -f libxxx$so dlmain.$exe if $dld $shared -o libxxx$so dllib.$obj -lm -lc && chmod 555 libxxx$so && $cc -o dlmain.$exe dlmain.$obj $pwd/libxxx$so && (./dlmain.$exe) >/dev/null 2>&1 then dll_libraries='-lm -lc' fi fi break done # the dll_libraries probe is still lame case $dll_libraries in '') case $hosttype in sco.*|sol*.*|sun*) ;; *) dll_libraries='-lm -lc' ;; esac ;; esac ;; esac stdlib= a=`$cc -print-multi-directory 2>/dev/null` case $a in .) ;; *) for d in `$cc -print-search-dirs 2>/dev/null | sed -e '/^libraries:/!d' -e 's/.*=//' | tr : '\n' | grep /lib/` do if [ -d ${d}${a} ] then stdlib="$stdlib ${d}${a}" else case $d in */lib/) d=`echo '' $d | sed -e 's,/$,,'` if [ -d ${d}${a} ] then stdlib="$stdlib ${d}${a}" fi ;; esac fi done ;; esac case $stdlib in '') stdlib=`$cc -v doti.$src 2>&1 | sed 's/ */\n/g' | sed -e '/^-L/!d' -e 's/^-L//' | while read dir do if test -d "$dir" then (cd "$dir"; pwd) fi done` ;; *) eval set x $probe_verbose shift for o in "$@" do stdlib="$stdlib "`$cc $o doti.$src 2>&1 | sed 's/ */\n/g' | sed -e '/^-L/!d' -e '/\/lib64$/!d' -e 's/^-L//'` done ;; esac case $stdlib in ?*) keepstdlib=1 o=$stdlib stdlib= for dir in $o do case " $stdlib " in *" $o "*) continue ;; esac case $dir in /usr/lib64) i=/usr/local/lib64 a=/lib64 ;; /lib64) i=/usr/local/lib64 a=/usr/lib64 ;; /usr/lib) i=/usr/local/lib a=/lib ;; lib) i=/usr/local/lib a=/usr/lib ;; *) i= a= ;; esac if test "" != "$i" -a -d "$i" then case " $o " in *" $i "*) ;; *) stdlib="$stdlib $i" ;; esac fi stdlib="$stdlib $dir" if test "" != "$a" -a -d "$a" then case " $o " in *" $a "*) ;; *) stdlib="$stdlib $a" ;; esac fi done case $hosted in 1) case " $stdlib " in *" /usr/lib "*) ;; *) case " $stdlib " in *" /usr/local/lib "*) ;; *) stdlib="$stdlib /usr/local/lib" ;; esac stdlib="$stdlib /usr/lib" ;; esac case " $stdlib " in *" /lib "*) ;; *) stdlib="$stdlib /lib" ;; esac esac ;; *) keepstdlib=0 case $dir in */arch/$hosttype/lib/*) notlib=`echo $dir | sed "s,/arch/$hosttype/lib/.*,/arch/$hosttype/lib,"` ;; *) notlib=//// ;; esac tstlib= implib= if $cc -c hosted.$src then for f in `( eval set x $probe_verbose while : do shift case $# in 0) break ;; esac $cc $1 hosted.$obj done ) 2>&1 | sed -e 's/[ :]/\\ /g' -e 's/-L//g' -e 's/^P,//' -e "s/[\"']//g" -e 's,^[\\\\/]*[\\\\/],/,' | sed -e '/^\$/d' -e '/^[-+]/d' -e '/^[^\\\\\\/]/d' -e '/[\\\\\\/]tmp[\\\\\\/]/d' -e 's/:\$//' -e 's,//*$,,'` do case " $tstlib $implib " in *" $f "*) continue ;; esac case $f in $notlib) continue ;; esac if test -d $f then tstlib="$tstlib $f" elif test -f $f then d=`echo $f | sed -e 's,[\\\\/]*[^\\\\/]*\$,,'` case " $tstlib $implib " in *" $d "*) continue ;; esac case $d in *[\\/]usr[\\/]lib) x=$d d="`echo $d | sed -e 's,[\\\\/][\\\\/]*usr[\\\\/]lib\$,/lib,'`" case " $tstlib $implib " in *" $d "*) ;; *) implib="$implib $d" ;; esac implib="$implib $x" ;; *[\\/]lib) implib="$implib $d" d="`echo $d | sed -e 's,[\\\\/][\\\\/]*lib\$,/usr/lib,'`" case " $tstlib $implib " in *" $d "*) ;; *) implib="$implib $d" ;; esac ;; *) implib="$implib $d" ;; esac fi done fi tstlib="$tstlib $implib" if $cc -Dtype=void -Dcall=exit -c tstlib.$src && mv tstlib.$obj tst.$obj then case $plusplus in '') probe_lxx= ;; esac l= for sym in $probe_l $probe_lxx do case $l in "") l=$sym; continue ;; esac rm -f tstlib.$exe if $cc -o tstlib.$exe tst.$obj -l$l then eval set x $probe_ldmap while : do shift case $# in 0) break ;; esac d=`$cc -Dtype=int -Dcall=$sym $static $1 tstlib.$src -l$l 2>&1 | sed -e '/[\\\\\\/].*[\\\\\\/]lib[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+]*\.[^\\\\\\/]*\$/!d' -e 's,^[^\\\\\/]*,,' -e 's,[\\\\\\/]lib[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+]*\.[^\\\\\\/]*\$,,' -e '/^[\\\\\\/]/!d' | sort -u` case $d in ?*) tstlib="$tstlib $d" ;; esac done fi l= done fi libstd= libset= stdlibroot="/ /usr/" for d in $tstlib do case $d in [\\/]lib|[\\/]usr[\\/]lib) ;; *) case " $stdlib " in *\ $d\ *) ;; *) if ls $d ${PREROOT+$PREROOT/../$d} > tmp.tmp && test -s tmp.tmp then for i in $probe_lib $obj do if grep -i "\\.$i\$" tmp.tmp >/dev/null then case " $probe_lib_append " in *\ $d\ *) libstd="$libstd $d" ;; *) stdlib="$stdlib $d" case $d in /usr/lib|/usr/lib/*) ;; /usr/lib?*) e=`echo $d | sed -e 's,/usr,,'` g=`echo $d/libc.* $e/libc.*` case "$e $g " in *".* "*);; *) stdlib="$stdlib $e" stdlibroot= ;; esac ;; esac ;; esac case $libset in "") case $i in $obj) ;; *) libset=1 lib=$i ;; esac ;; esac break fi done fi ;; esac ;; esac done for d in `$ld --verbose 2>&1 | sed -e '/SEARCH_DIR/!d' -e 's/[ ][ ][ ]*/ /g' -e 's/SEARCH_DIR(\([^ ]*\));/\1/g' -e 's, //[^ ]*,,' -e 's,",,g'` do if test -d $d then case " $stdlib $libstd " in *\ ${d}\ *) ;; *) libstd="$libstd $d" ;; esac fi done case $hosted in "") tstlib= ;; *) tstlib="$stdlibroot /usr/ccs/ /usr/local/" ;; esac case $stdlibroot in ?*) d= for f in $stdinclude do f=`echo $f | sed -e 's,[^\\\\/]*\$,,'` d="$d $f" done tstlib="$d $tstlib" ;; esac $cc -c doti.$src > all.tmp for f in $probe_libdir do for d in $stdlib $libstd $tstlib do if test -d ${d}${f} then ls ${d}${f} ${PREROOT:+$PREROOT/../${d}${f}} | while read i do for j in ${d}${f}/${i} ${PREROOT:+$PREROOT/../${d}${f}/${i}} do if test -f $j -a -r $j -a -s $j then echo $i break fi done done > tmp.tmp if test -s tmp.tmp then if egrep -i "^${prefix_archive}[abcdefghijklmnopqrstuvwxyz0123456789_][abcdefghijklmnopqrstuvwxyz0123456789_]*\\.$lib\$" tmp.tmp >lib.tmp || egrep -i "\\.$obj\$" tmp.tmp >/dev/null || egrep -i "^${prefix_shared}[abcdefghijklmnopqrstuvwxyz0123456789_][abcdefghijklmnopqrstuvwxyz0123456789_]*\\$so(.[0-9]+)*\$" tmp.tmp >>lib.tmp then if test -s lib.tmp then sed -e "s,.*/,," -e 's,^'${prefix_archive}'\(.*\)\.'$lib'$,\1,g' -e 's,^'${prefix_shared}'\(.*\)\'$so'[.0-9]*,\1,g' lib.tmp | sort -u > tmp.tmp xs=`sort all.tmp all.tmp tmp.tmp | uniq -u` case $xs in '') continue ;; esac ok=0 for x in $xs do case $x in *_p) continue ;; # Linux gcc known to hang for -lc_p esac if $cc -o doti.$exe doti.$obj -l$x 2>e then ok=1 else if test -s e && egrep -i ":.*[ ](find|found|locate|search|-l$x)[ ]" e > /dev/null then if egrep -i ":.*[ ](access|permission)[ ]" e then : maybe else ok=0 break fi fi case $Lflag in 1) if $cc -L${d}${f} -o doti.$exe doti.$obj -l$x then ok=0 break fi ;; esac fi done case $ok in 0) continue ;; esac sort -u all.tmp tmp.tmp > lib.tmp mv lib.tmp all.tmp fi case " $stdlib $libstd " in *" ${d}${f} "*) ;; *) if test -d ${d}${f}/fsoft then stdlib="$stdlib ${d}${f}/"'$(FLOAT_OPTION)' fi stdlib="$stdlib ${d}${f}" ;; esac fi fi fi done done stdlib="$stdlib $libstd" case $stdlib in */shlib*) dy= st= for i in $stdlib $libstd do case $i in */shlib) dy="$dy $i" ;; *) st="$st $i" ;; esac done for i in /var do if test -d $i/shlib then dy="$dy $i/shlib" fi done stdlib="$dy $st" ;; esac ;; esac if $cc -c prefix.$src then eval set x $probe_symprefix while : do shift case $# in 0) break ;; esac if $nm $nmflags prefix.$obj | grep -c ${1}prefix >/dev/null then symprefix=$1 break fi done fi if $cc -c warn.$src 2>e && test -f warn.$obj then e=`wc -c < e` eval set x $probe_debug while : do shift case $# in 0) break ;; esac rm -f warn.$obj $cc $1 -c warn.$src 2>e && test -f warn.$obj || continue case `wc -c < e` in $e) debug=$1; break ;; esac done eval set x $probe_no_protect while : do shift case $# in 0) break ;; esac rm -f warn.$obj $cc $1 -c warn.$src 2>e && test -f warn.$obj || continue case `wc -c < e` in $e) no_protect=$1; break ;; esac done case $version_string in $probe_gcc_version) probe_optimize="$probe_gcc_optimize $probe_optimize" ;; esac for i in $probe_optimize do rm -f warn.$obj $cc $i -c warn.$src 2>e && test -f warn.$obj || continue case `wc -c < e` in $e) optimize=$i; break ;; esac done eval set x $probe_strict while : do shift case $# in 0) break ;; esac rm -f warn.$obj $cc $1 -c warn.$src 2>e && test -f warn.$obj || continue n=`wc -c < e` if test $n -ge $e then strict=$1 break fi done $cc -c warn1.$src 2>e o=`wc -c < e` eval set x $probe_warn while : do shift case $# in 0) break ;; esac rm -f warn.$obj warn.$exe $cc -o warn.$exe $1 warn.$src 2>e && test -f warn.$exe || continue n=`wc -c < e` for i in $warn_enum do rm -f warn$i.$obj $cc -c $1 warn$i.$src 2>e && test -f warn$i.$obj || continue n=`wc -c < e` if test $n -gt $o then warn=$1 break 2 fi done done fi while : do case $hosted in 1) rm -f readonly.$exe eval set x '""' $probe_readonly while : do shift case $# in 0) break ;; esac for co in '' -Dtest_const do rm -f readonly.$exe if $cc -o readonly.$exe $co $1 readonly.$src && $executable readonly.$exe then if ./readonly.$exe >/dev/null 2>&1 then : else readonly=$1 break 3 fi fi done done rm -f readonly.$exe readonly.s if $cc -S readonly.$src && test -f readonly.s then if sed -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)data/\1text/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)zero[ ][ ]*/\1set .,.+/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*1/\1byte 0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*2/\1byte 0,0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*3/\1byte 0,0,0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*4/\1byte 0,0,0,0/' \ readonly.s > ro.s && $cc -o readonly.$exe ro.s && $executable readonly.$exe then if ./readonly.$exe >/dev/null 2>&1 then : else readonly='-S.data' break fi fi rm -f readonly.$exe if sed -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)idat/\1code/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)zero[ ][ ]*/\1set .,.+/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*1/\1byte 0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*2/\1byte 0,0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*3/\1byte 0,0,0/' \ -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)space[ ][ ]*4/\1byte 0,0,0,0/' \ readonly.s > ro.s && $cc -o readonly.$exe ro.s && $executable readonly.$exe then if ./readonly.$exe >/dev/null 2>&1 then : else readonly='-S.idat' break fi fi if sed -e 's/^\([ ]*[.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$:]*[ ]*\.*\)data/\1rdata/' \ readonly.s > ro.s && $cc -o readonly.$exe ro.s && $executable readonly.$exe then if ./readonly.$exe >/dev/null 2>&1 then : else readonly='-S.rdata' break fi fi fi ;; esac break done case $stdc in ?*) dialect="$dialect ANSI" ;; esac case $plusplus in ?*) dialect="$dialect C++" ;; esac case $hosted in "") dialect="$dialect CROSS" ;; esac case $doti in ?*) dialect="$dialect DOTI" ;; esac case $gnu in ?*) dialect="$dialect GNU" ;; esac case $so:$dynamic:$static in ::) ;; *) dialect="$dialect DYNAMIC" case $soversion in ?*) dialect="$dialect VERSION" ;; esac ;; esac case $implicitc in ?*) dialect="$dialect IMPLICITC" ;; esac case $ptrcopy in ?*) dialect="$dialect PTRCOPY" ;; esac case $ptrimplicit in ?*) dialect="$dialect PTRIMPLICIT" ;; esac case $ptrmkdir in ?*) dialect="$dialect PTRMKDIR" ;; esac case $libpp in ?*) dialect="$dialect LIBPP" ;; esac case $toucho in ?*) dialect="$dialect TOUCHO" ;; esac case $dDflag in ?*) dialect="$dialect -dD" ;; esac # 2005-05-25 use $(CC.INCLUDE.LOCAL) instead case $include_local in ?*) dialect="$dialect -I-" ;; esac case $Lflag in ?*) dialect="$dialect -L" ;; esac ppcmd='$(CPP)' ppdir='$(CPP:D)' eval ppopt='"'$ppopt'"' eval ppenv='"'$ppenv'"' set x "" .$exe shift exe= for i do rm -f require$i done if $cc -o require require.$src then for i do if $executable require$i then exe=$i break fi done fi case $sa:$sd:$so in ::?*) eval set x $probe_sa while : do shift case $# in 0) break ;; esac for i in $stdlib do eval j="'" $i/lib*$1 "'" case $j in " $i/lib*$1 ") eval j="'" $i/lib*$1.[0123456789]* "'" case $j in " $i/lib*$1.[0123456789]* ") continue ;; esac ;; esac sa=$1 lddynamic=-Bdynamic ldstatic=-Bstatic break 2 done done ;; esac case $ldscript in "") case $so in .lib) ldscript=".def .exp" ;; *) ldscript=".ld" ;; esac ;; esac case $hosttype in '') hosttype=unknown ;; sgi.mips3) dll_variants='sgi.mips2:o32:-mips2 sgi.mips4:64:-mips4' ;; sgi.mips4) dll_variants='sgi.mips2:o32:-mips2 sgi.mips3:n32:-mips3' ;; esac case $hosted in "") ccnative=`echo $cc | sed -e 's,.*/,,'` ccs=$ccnative for c in cc gcc do case " $ccs " in *" $c "*) ;; *) ccs="$ccs $c" ;; esac done for p in $path do for c in $ccs do if $executable $p/$c then rm -f native.$exe if $p/$c -o native.$exe doti.$src && ./native.$exe then ccnative=$p/$c exectype=`package CC="$ccnative" || $SHELL -c "package CC='$ccnative'"` case $exectype in *[Uu][Ss][Aa][Gg][Ee]:*) exectype=`PATH=$_probe_PATH; export PATH; package CC="$ccnative" || $SHELL -c "package CC='$ccnative'"` ;; esac break 2 fi fi done done ;; *) ccnative=$cc exectype=$hosttype ;; esac # runtime shared lib exported symbol resolution case $cc_dll:$shared in :|:*|*:);; *) cat > cmd.c <<'!' #include #include typedef int (*Lib_f)(int**, int**, int**); int gbl_def = 1; int gbl_ref = 1; int gbl_ext; int main(int argc, char** argv) { void* dll; Lib_f lib; int* def; int* ref; int* ext; if (!(dll = dlopen(*++argv, RTLD_LAZY))) fprintf(stderr, "library not found\n"); else if (!((lib = (Lib_f)dlsym(dll, "lib"))) && !(lib = (Lib_f)dlsym(dll, "_lib"))) fprintf(stderr, "symbol not found\n"); else if ((*lib)(&def, &ref, &ext)) fprintf(stderr, "function failed\n"); else if (def == &gbl_def && ref == &gbl_ref && ext == &gbl_ext) printf("ALL\n"); else if (ref == &gbl_ref && ext == &gbl_ext) printf("REF\n"); else if (ext == &gbl_ext) printf("EXT\n"); return 0; } ! cat > lib.c <<'!' int gbl_def = 1; int gbl_ref; int gbl_ext; int lib(int** def, int** ref, int** ext) { *def = &gbl_def; *ref = &gbl_ref; *ext = &gbl_ext; return 0; } ! if $cc -c $cc_dll $cc_pic cmd.c && $cc -c $cc_dll $cc_pic lib.c && { $cc $cc_dll $export_dynamic -o cmd.exe cmd.o || $cc $cc_dll $export_dynamic -o cmd.exe cmd.o -ldl } && $dld $shared -o libgbl.dll lib.o then x=`./cmd.exe ./libgbl.dll` case $x in ?*) dialect="$dialect EXPORT=$x" ;; esac else case $sd:$hosttype in .dll:*win*) dialect="$dialect EXPORT=DLL" ;; esac fi ;; esac # shellmagic defined if installed shell scripts need magic echo ': got magic : echo ok' > ok chmod +x ok case `(eval ./ok | /bin/sh) 2>/dev/null` in ok) ;; *) echo '#!/bin/env sh : got magic : echo ok' > ok chmod +x ok case `(eval ./ok | /bin/sh) 2>/dev/null` in ok) shellmagic='$("#")!/bin/env sh' ;; *) for i in /emx/bin/bash.exe /emx/bin/sh.exe do if test -x $i then shellmagic='$("#")!'$i break fi done ;; esac ;; esac # # path cleanup # for i in ar ccnative dld ld nm size stdinclude stdlib strip do eval o='$'$i v=$o case $v in *//*) v=`echo $v | sed 's,///*,/,g'` ;; esac if (test . -ef "`pwd`") then k= for x in $v do case $x in */../*|*/..) case $x in /*) a=/ ;; *) a= ;; esac IFS=/ set '' $x IFS=$ifs r= for d do r="$d $r" done p= g= for d in $r do case $d in ..) g="$g $d" ;; *) case $g in '') case $p in '') p=$d ;; *) p=$d/$p ;; esac ;; *) set $g shift g=$* ;; esac ;; esac done case $a in '') for d in $g do p=$d/$p done ;; *) p=$a$p ;; esac case $p in /) continue ;; esac test $x -ef $p && x=$p ;; esac k="$k $x" done set '' $k shift v=$1 case $# in 0) ;; *) shift while : do case $# in 0) break ;; esac k= for d do for j in $v do test $d -ef $j && continue 2 done k="$k $d" done set '' $k case $# in 1) break ;; esac shift v="$v $1" shift done ;; esac fi case $v in $o) ;; *) eval $i='$'v ;; esac done case $keepstdlib in 1) ;; *) # # favor lib64 over lib # case $hosttype in *64|*[!0-9]64[!a-zA-Z0-9]*) o=$stdlib stdlib= for i in $o do case " $stdlib " in *" $i "*) continue ;; esac case $i in *64) stdlib="$stdlib $i" continue ;; esac case " $o " in *" ${i}64 "*) case " $stdlib " in *" ${i}64 "*) ;; *) stdlib="$stdlib ${i}64" ;; esac ;; esac stdlib="$stdlib $i" done ;; esac ;; esac # # set up for local override # CC_VERSION_STAMP=$version_stamp CC_VERSION_STRING=$version_string CC_CC=$cc CC_NATIVE=$ccnative CC_EXECTYPE=$exectype CC_HOSTTYPE=$hosttype CC_ALTPP_FLAGS=$ppopt CC_ALTPP_ENV=$ppenv CC_AR=$ar CC_AR_ARFLAGS=$ar_arflags CC_ARFLAGS=$arflags CC_DEBUG=$debug CC_DIALECT=$dialect CC_PICBIG=$cc_PIC CC_PICSMALL=$cc_pic CC_PIC=$CC_PICBIG CC_DLL_ONLY=$cc_dll case $CC_DLL_ONLY in '') CC_DLLBIG= CC_DLLSMALL= CC_DLL= ;; *) CC_DLLBIG="$CC_DLL_ONLY $CC_PICBIG" CC_DLLSMALL="$CC_DLL_ONLY $CC_PICSMALL" CC_DLL="$CC_DLL_ONLY $CC_PICBIG" ;; esac CC_DLL_DIR=$dll_dir CC_DLL_LIBRARIES=$dll_libraries CC_DLL_VARIANTS=$dll_variants CC_DYNAMIC=$dynamic CC_EXPORT_DYNAMIC=$export_dynamic CC_INCLUDE_LOCAL=$include_local CC_LD=$ld CC_LD_DYNAMIC=$lddynamic CC_LD_LAZY=$ldlazy CC_LD_NOLAZY=$ldnolazy CC_LD_ORIGIN=$ldorigin CC_LD_RECORD=$ldrecord CC_LD_NORECORD=$ldnorecord CC_LD_RUNPATH=$ldrunpath CC_LD_STATIC=$ldstatic CC_LD_STRIP=$ldstrip CC_LIB_DLL=$lib_dll CC_LIB_ALL=$lib_all CC_LIB_UNDEF=$lib_undef CC_MAKE_OPTIONS=$makeoptions CC_NM=$nm CC_NMEDIT=$nmedit CC_NMFLAGS=$nmflags CC_NOPROTECT=$no_protect CC_OPTIMIZE=$optimize CC_READONLY=$readonly CC_REPOSITORY=$repository CC_REQUIRE=$require CC_RUNPATH=$runpath CC_SHARED=$shared CC_SHARED_LD=$dld CC_SHARED_NAME=$shared_name CC_SHARED_REGISTRY=$shared_registry CC_SHARED_REGISTRY_PATH=$probe_shared_registry_path CC_SHELLMAGIC=$shellmagic CC_SIZE=$size CC_STATIC=$static CC_STDINCLUDE=$stdinclude CC_STDLIB=$stdlib CC_STRICT=$strict CC_STRIP=$strip CC_STRIP_FLAGS=$stripflags CC_PREFIX_ARCHIVE=$prefix_archive CC_PREFIX_DYNAMIC=$prefix_dynamic CC_PREFIX_SHARED=$prefix_shared CC_PREFIX_SYMBOL=$symprefix CC_SUFFIX_ARCHIVE=.$lib CC_SUFFIX_COMMAND=$suffix_command CC_SUFFIX_DEBUG=$sdb CC_SUFFIX_DYNAMIC=$sd CC_SUFFIX_LD=$ldscript CC_SUFFIX_OBJECT=.$obj CC_SUFFIX_SHARED=$so CC_SUFFIX_SOURCE=.$src CC_SUFFIX_STATIC=$sa CC_VERSION=$version_flags CC_WARN=$warn CC_ATTRIBUTES=$ATTRIBUTES exec >&3 # # check for local override # all CC_* but { CC_CC CC_VERSION_STAMP CC_VERSION_STRING } may be modified # additional CC.* may be printed on stdout # if test -f "$dir/probe.lcl" then . "$dir/probe.lcl" fi # # the payoff # case $version_stamp in ?*) echo "# $version_stamp" ;; esac echo CC.CC = $cc echo CC.NATIVE = $CC_NATIVE echo CC.EXECTYPE = $CC_EXECTYPE echo CC.HOSTTYPE = $CC_HOSTTYPE echo CC.ALTPP.FLAGS = $CC_ALTPP_FLAGS echo CC.ALTPP.ENV = $CC_ALTPP_ENV echo CC.AR = $CC_AR echo CC.AR.ARFLAGS = $CC_AR_ARFLAGS echo CC.ARFLAGS = $CC_ARFLAGS echo CC.DEBUG = $CC_DEBUG echo CC.DIALECT = $CC_DIALECT echo CC.DLLBIG = $CC_DLLBIG echo CC.DLLSMALL = $CC_DLLSMALL echo CC.DLL = $CC_DLL echo CC.DLL.DEF = $cc_dll_def echo CC.DLL.DIR = $CC_DLL_DIR echo CC.DLL.LIBRARIES = $CC_DLL_LIBRARIES echo CC.DLL.VARIANTS = $CC_DLL_VARIANTS echo CC.DYNAMIC = $CC_DYNAMIC echo CC.EXPORT.DYNAMIC = $CC_EXPORT_DYNAMIC echo CC.INCLUDE.LOCAL = $CC_INCLUDE_LOCAL # # 2004-02-14 release workaround # case $CC_SHARED_LD in $CC_CC) echo if LDSHARED echo CC.LD = $CC_LD echo else echo CC.LD = $CC_CC echo end ;; *) echo CC.LD = $CC_LD ;; esac echo CC.LD.DYNAMIC = $CC_LD_DYNAMIC echo CC.LD.LAZY = $CC_LD_LAZY echo CC.LD.NOLAZY = $CC_LD_NOLAZY echo CC.LD.ORIGIN = $CC_LD_ORIGIN echo CC.LD.RECORD = $CC_LD_RECORD echo CC.LD.NORECORD = $CC_LD_NORECORD echo CC.LD.RUNPATH = $CC_LD_RUNPATH echo CC.LD.STATIC = $CC_LD_STATIC echo CC.LD.STRIP = $CC_LD_STRIP echo CC.LIB.DLL = $CC_LIB_DLL echo CC.LIB.ALL = $CC_LIB_ALL echo CC.LIB.UNDEF = $CC_LIB_UNDEF echo CC.MAKE.OPTIONS = $CC_MAKE_OPTIONS echo CC.NM = $CC_NM case $CC_NMEDIT in ?*) CC_NMEDIT=" $CC_NMEDIT" ;; esac echo CC.NMEDIT ="$CC_NMEDIT" echo CC.NMFLAGS = $CC_NMFLAGS echo CC.NOPROTECT = $CC_NOPROTECT echo CC.OPTIMIZE = $CC_OPTIMIZE echo CC.PICBIG = $CC_PICBIG echo CC.PICSMALL = $CC_PICSMALL echo CC.PIC = $CC_PIC echo CC.READONLY = $CC_READONLY echo CC.REPOSITORY = $CC_REPOSITORY for f in $CC_REQUIRE do echo CC.REQUIRE.$f =`cat req.$f` done echo CC.RUNPATH = $CC_RUNPATH echo CC.SHARED = $CC_SHARED echo CC.SHARED.LD = $CC_SHARED_LD echo CC.SHARED.NAME = $CC_SHARED_NAME echo CC.SHARED.REGISTRY = $CC_SHARED_REGISTRY echo CC.SHARED.REGISTRY.PATH = $CC_SHARED_REGISTRY_PATH echo CC.SHELLMAGIC = $CC_SHELLMAGIC echo CC.SIZE = $CC_SIZE echo CC.STATIC = $CC_STATIC echo CC.STDINCLUDE = $CC_STDINCLUDE echo CC.STDLIB = $CC_STDLIB echo CC.STRICT = $CC_STRICT echo CC.STRIP = $CC_STRIP echo CC.STRIP.FLAGS = $CC_STRIP_FLAGS echo CC.PREFIX.ARCHIVE = $CC_PREFIX_ARCHIVE echo CC.PREFIX.DYNAMIC = $CC_PREFIX_DYNAMIC echo CC.PREFIX.SHARED = $CC_PREFIX_SHARED echo CC.PREFIX.SYMBOL = $CC_PREFIX_SYMBOL echo CC.SUFFIX.ARCHIVE = $CC_SUFFIX_ARCHIVE echo CC.SUFFIX.COMMAND = $CC_SUFFIX_COMMAND echo CC.SUFFIX.DEBUG = $CC_SUFFIX_DEBUG echo CC.SUFFIX.DYNAMIC = $CC_SUFFIX_DYNAMIC echo CC.SUFFIX.LD = $CC_SUFFIX_LD echo CC.SUFFIX.OBJECT = $CC_SUFFIX_OBJECT echo CC.SUFFIX.SHARED = $CC_SUFFIX_SHARED echo CC.SUFFIX.SOURCE = $CC_SUFFIX_SOURCE echo CC.SUFFIX.STATIC = $CC_SUFFIX_STATIC echo CC.VERSION = $CC_VERSION case $CC_VERSION_STRING in *\"*) i=`echo " $CC_VERSION_STRING" | sed -e 's,",\\\\",g' -e 's,^ ,,' -e 's,.*,"&",'` ;; *\'*) i=\"$CC_VERSION_STRING\" ;; *) i=$CC_VERSION_STRING ;; esac cat < * * * ***********************************************************************/ #pragma prototyped #pragma clang diagnostic ignored "-Wdeprecated-register" #pragma clang diagnostic ignored "-Wparentheses" /* * mamake -- MAM make * * coded for portability */ #define RELEASE_DATE "2021-01-21" static char id[] = "\n@(#)$Id: mamake (ksh 93u+m) " RELEASE_DATE " $\0\n"; #if _PACKAGE_ast #include #include static const char usage[] = "[-?\n@(#)$Id: mamake (ksh 93u+m) " RELEASE_DATE " $\n]" "[-author?Glenn Fowler ]" "[-copyright?(c) 1994-2012 AT&T Intellectual Property]" "[-copyright?(c) 2020-2021 Contributors to https://github.com/ksh93/ksh]" "[-license?http://www.eclipse.org/org/documents/epl-v10.html]" "[+NAME?mamake - make abstract machine make]" "[+DESCRIPTION?\bmamake\b reads \amake abstract machine\a target and" " prerequisite file descriptions from a mamfile (see \b-f\b) and executes" " actions to update targets that are older than their prerequisites." " Mamfiles are portable to environments that only have" " \bsh\b(1) and \bcc\b(1).]" "[+?Mamfiles are used rather than" " old-\bmake\b makefiles because some features are not reliably supported" " across all \bmake\b variants:]{" " [+action execution?Multi-line actions are executed as a" " unit by \b$SHELL\b. There are some shell constructs" " that cannot be expressed in an old-\bmake\b makefile.]" " [+viewpathing?\bVPATH\b is properly interpreted. This allows" " source to be separate from generated files.]" " [+recursion?Ordered subdirectory recursion over unrelated" " makefiles.]" " }" "[+?\bmamprobe\b(1) is called to probe and generate system specific variable" " definitions. The probe information is regenerated when it is older" " than the \bmamprobe\b command.]" "[+?For compatibility with \bnmake\b(1) the \b-K\b option and the" " \brecurse\b and \bcc-*\b command line targets are ignored.]" "[e:?Explain reason for triggering action. Ignored if -F is on.]" "[f:?Read \afile\a instead of the default.]:[file:=Mamfile]" "[i:?Ignore action errors.]" "[k:?Continue after error with sibling prerequisites.]" "[n:?Print actions but do not execute. Recursion actions (see \b-r\b) are still" " executed. Use \b-N\b to disable recursion actions too.]" "[r:?Recursively make leaf directories matching \apattern\a. Only leaf" " directories containing a makefile named \bNmakefile\b, \bnmakefile\b," " \bMakefile\b or \bmakefile\b are considered. The first makefile" " found in each leaf directory is scanned for leaf directory" " prerequisites; the recursion order is determined by a topological sort" " of these prerequisites.]:[pattern]" "[C:?Do all work in \adirectory\a. All messages will mention" " \adirectory\a.]:[directory]" "[D:?Set the debug trace level to \alevel\a. Higher levels produce more" " output.]#[level]" "[F:?Force all targets to be out of date.]" "[K:?Ignored.]" "[N:?Like \b-n\b but recursion actions (see \b-r\b) are also disabled.]" "[V:?Print the program version and exit.]" "[G:debug-symbols?Compile and link with debugging symbol options enabled.]" "[S:strip-symbols?Strip link-time static symbols from executables.]" "\n" "\n[ target ... ] [ name=value ... ]\n" "\n" "[+SEE ALSO?\bgmake\b(1), \bmake\b(1), \bmamprobe\b(1)," " \bnmake\b(1), \bsh\b(1)]" ; #else #define elementsof(x) (sizeof(x)/sizeof(x[0])) #define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x))) #define NiL ((char*)0) #endif #include #include #include #include #include #include #if !_PACKAGE_ast && defined(__STDC__) #include #include #endif #define delimiter(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)==';'||(c)=='('||(c)==')'||(c)=='`'||(c)=='|'||(c)=='&'||(c)=='=') #define add(b,c) (((b)->nxt >= (b)->end) ? append(b, "") : NiL, *(b)->nxt++ = (c)) #define get(b) ((b)->nxt-(b)->buf) #define set(b,o) ((b)->nxt=(b)->buf+(o)) #define use(b) (*(b)->nxt=0,(b)->nxt=(b)->buf) #define CHUNK 4096 #define KEY(a,b,c,d) ((((unsigned long)(a))<<15)|(((unsigned long)(b))<<10)|(((unsigned long)(c))<<5)|(((unsigned long)(d)))) #define NOW ((unsigned long)time((time_t*)0)) #define ROTATE(p,l,r,t) ((t)=(p)->l,(p)->l=(t)->r,(t)->r=(p),(p)=(t)) #define RULE_active 0x0001 /* active target */ #define RULE_dontcare 0x0002 /* ok if not found */ #define RULE_error 0x0004 /* not found or not generated */ #define RULE_exists 0x0008 /* target file exists */ #define RULE_generated 0x0010 /* generated target */ #define RULE_ignore 0x0020 /* ignore time */ #define RULE_implicit 0x0040 /* implicit prerequisite */ #define RULE_made 0x0080 /* already made */ #define RULE_virtual 0x0100 /* not a file */ #define STREAM_KEEP 0x0001 /* don't fclose() on pop() */ #define STREAM_MUST 0x0002 /* push() file must exist */ #define STREAM_PIPE 0x0004 /* pclose() on pop() */ #ifndef S_IXUSR #define S_IXUSR 0100 /* owner execute permission */ #endif #ifndef S_IXGRP #define S_IXGRP 0010 /* group execute permission */ #endif #ifndef S_IXOTH #define S_IXOTH 0001 /* other execute permission */ #endif struct Rule_s; typedef struct stat Stat_t; typedef FILE Stdio_t; typedef struct Buf_s /* buffer stream */ { struct Buf_s* old; /* next dropped buffer */ char* end; /* 1 past end of buffer */ char* nxt; /* next char to add */ char* buf; /* buffer space */ } Buf_t; typedef struct Dict_item_s /* dictionary item */ { struct Dict_item_s* left; /* left child */ struct Dict_item_s* right; /* right child */ void* value; /* user defined value */ char name[1];/* 0 terminated name */ } Dict_item_t; typedef struct Dict_s /* dictionary handle */ { Dict_item_t* root; /* root item */ } Dict_t; typedef struct List_s /* Rule_t list */ { struct List_s* next; /* next in list */ struct Rule_s* rule; /* list item */ } List_t; typedef struct Rule_s /* rule item */ { char* name; /* unbound name */ char* path; /* bound path */ List_t* prereqs; /* prerequisites */ struct Rule_s* leaf; /* recursion leaf alias */ int flags; /* RULE_* flags */ int making; /* currently make()ing */ unsigned long time; /* modification time */ } Rule_t; typedef struct Stream_s /* input file stream stack */ { Stdio_t* fp; /* read stream */ char* file; /* stream path */ unsigned long line; /* stream line */ int flags; /* stream flags */ } Stream_t; typedef struct View_s /* viewpath level */ { struct View_s* next; /* next level in viewpath */ int node; /* viewpath node path length */ char dir[1]; /* viewpath level dir prefix */ } View_t; static struct /* program state */ { Buf_t* buf; /* work buffer */ Buf_t* old; /* dropped buffers */ Buf_t* opt; /* option buffer */ Dict_t* leaf; /* recursion leaf dictionary */ Dict_t* libs; /* library dictionary */ Dict_t* rules; /* rule dictionary */ Dict_t* vars; /* variable dictionary */ View_t* view; /* viewpath levels */ char* directory; /* work in this directory */ char* id; /* command name */ char* file; /* first input file */ char* pwd; /* current directory */ char* recurse; /* recursion pattern */ char* shell; /* ${SHELL} */ int active; /* targets currently active */ int debug; /* negative of debug level */ int errors; /* some error(s) occurred */ int exec; /* execute actions */ int explain; /* explain actions */ int force; /* all targets out of date */ int ignore; /* ignore command errors */ int indent; /* debug indent */ int keepgoing; /* do siblings on error */ int never; /* never execute */ int peek; /* next line already in input */ int probed; /* probe already done */ int verified; /* don't bother with verify() */ Stream_t streams[4]; /* input file stream stack */ Stream_t* sp; /* input stream stack pointer */ char input[8*CHUNK]; /* input buffer */ } state; static unsigned long make(Rule_t*); static char mamfile[] = "Mamfile"; static char sh[] = "/bin/sh"; extern char** environ; #if !_PACKAGE_ast #if defined(NeXT) || defined(__NeXT) #define getcwd(a,b) getwd(a) #endif /* * emit usage message and exit */ static void usage() { fprintf(stderr, "Usage: %s [-iknFKNV] [-f mamfile] [-r pattern] [-C directory] [-D level] [target ...] [name=value ...]\n", state.id); exit(2); } #endif /* * output error message identification */ static void identify(Stdio_t* sp) { if (state.directory) fprintf(sp, "%s [%s]: ", state.id, state.directory); else fprintf(sp, "%s: ", state.id); } /* * emit error message * level: * <0 debug * 0 info * 1 warning * 2 error * >2 exit(level-2) */ static void report(int level, char* text, char* item, unsigned long stamp) { int i; if (level >= state.debug) { if (level) identify(stderr); if (level < 0) { fprintf(stderr, "debug%d: ", level); for (i = 1; i < state.indent; i++) fprintf(stderr, " "); } else { if (state.sp && state.sp->line) { if (state.sp->file) fprintf(stderr, "%s: ", state.sp->file); fprintf(stderr, "%ld: ", state.sp->line); } if (level == 1) fprintf(stderr, "warning: "); else if (level > 1) state.errors = 1; } if (item) fprintf(stderr, "%s: ", item); fprintf(stderr, "%s", text); if (stamp && state.debug <= -2) fprintf(stderr, " %10lu", stamp); fprintf(stderr, "\n"); if (level > 2) exit(level - 2); } } /* * don't know how to make or exit code making */ static void dont(Rule_t* r, int code, int keepgoing) { identify(stderr); if (!code) fprintf(stderr, "don't know how to make %s\n", r->name); else { fprintf(stderr, "*** exit code %d making %s%s\n", code, r->name, state.ignore ? " ignored" : ""); unlink(r->name); if (state.ignore) return; } if (!keepgoing) exit(1); state.errors++; r->flags |= RULE_error; } /* * local strrchr() */ static char* last(register char* s, register int c) { register char* r = 0; for (r = 0; *s; s++) if (*s == c) r = s; return r; } /* * open a buffer stream */ static Buf_t* buffer(void) { register Buf_t* buf; if (buf = state.old) state.old = state.old->old; else if (!(buf = newof(0, Buf_t, 1, 0)) || !(buf->buf = newof(0, char, CHUNK, 0))) report(3, "out of memory [buffer]", NiL, (unsigned long)0); buf->end = buf->buf + CHUNK; buf->nxt = buf->buf; return buf; } /* * close a buffer stream */ static void drop(Buf_t* buf) { buf->old = state.old; state.old = buf; } /* * append str length n to buffer and return the buffer base */ static char* appendn(Buf_t* buf, char* str, int n) { int m; int i; if ((n + 1) >= (buf->end - buf->nxt)) { i = buf->nxt - buf->buf; m = (((buf->end - buf->buf) + n + CHUNK + 1) / CHUNK) * CHUNK; if (!(buf->buf = newof(buf->buf, char, m, 0))) report(3, "out of memory [buffer resize]", NiL, (unsigned long)0); buf->end = buf->buf + m; buf->nxt = buf->buf + i; } memcpy(buf->nxt, str, n + 1); buf->nxt += n; return buf->buf; } /* * append str to buffer and return the buffer base * if str==0 then next pointer reset to base */ static char* append(Buf_t* buf, char* str) { if (str) return appendn(buf, str, strlen(str)); buf->nxt = buf->buf; return buf->buf; } /* * allocate space for s and return the copy */ static char* duplicate(char* s) { char* t; int n; n = strlen(s); if (!(t = newof(0, char, n, 1))) report(3, "out of memory [duplicate]", s, (unsigned long)0); strcpy(t, s); return t; } /* * open a new dictionary */ static Dict_t* dictionary(void) { Dict_t* dict; if (!(dict = newof(0, Dict_t, 1, 0))) report(3, "out of memory [dictionary]", NiL, (unsigned long)0); return dict; } /* * return the value for item name in dictionary dict * if value!=0 then name entry value is created if necessary and set * uses top-down splaying (ala Tarjan and Sleator) */ static void* search(register Dict_t* dict, char* name, void* value) { register int cmp; register Dict_item_t* root; register Dict_item_t* t; register Dict_item_t* left; register Dict_item_t* right; register Dict_item_t* lroot; register Dict_item_t* rroot; root = dict->root; left = right = lroot = rroot = 0; while (root) { if (!(cmp = strcmp(name, root->name))) break; else if (cmp < 0) { if (root->left && (cmp = strcmp(name, root->left->name)) <= 0) { ROTATE(root, left, right, t); if (!cmp) break; } if (right) right->left = root; else rroot = root; right = root; root = root->left; right->left = 0; } else { if (root->right && (cmp = strcmp(name, root->right->name)) >= 0) { ROTATE(root, right, left, t); if (!cmp) break; } if (left) left->right = root; else lroot = root; left = root; root = root->right; left->right = 0; } } if (root) { if (right) right->left = root->right; else rroot = root->right; if (left) left->right = root->left; else lroot = root->left; } else if (value) { if (!(root = newof(0, Dict_item_t, 1, strlen(name)))) report(3, "out of memory [dictionary]", name, (unsigned long)0); strcpy(root->name, name); } if (root) { if (value) root->value = value; root->left = lroot; root->right = rroot; dict->root = root; return value ? (void*)root->name : root->value; } if (left) { left->right = rroot; dict->root = lroot; } else if (right) { right->left = lroot; dict->root = rroot; } return 0; } /* * low level for walk() */ static int apply(Dict_t* dict, Dict_item_t* item, int (*func)(Dict_item_t*, void*), void* handle) { register Dict_item_t* right; do { right = item->right; if (item->left && apply(dict, item->left, func, handle)) return -1; if ((*func)(item, handle)) return -1; } while (item = right); return 0; } /* * apply func to each dictionary item */ static int walk(Dict_t* dict, int (*func)(Dict_item_t*, void*), void* handle) { return dict->root ? apply(dict, dict->root, func, handle) : 0; } /* * return a rule pointer for name */ static Rule_t* rule(char* name) { Rule_t* r; if (!(r = (Rule_t*)search(state.rules, name, NiL))) { if (!(r = newof(0, Rule_t, 1, 0))) report(3, "out of memory [rule]", name, (unsigned long)0); r->name = (char*)search(state.rules, name, (void*)r); } return r; } /* * prepend p onto rule r prereqs */ static void cons(Rule_t* r, Rule_t* p) { register List_t* x; for (x = r->prereqs; x && x->rule != p; x = x->next); if (!x) { if (!(x = newof(0, List_t, 1, 0))) report(3, "out of memory [list]", r->name, (unsigned long)0); x->rule = p; x->next = r->prereqs; r->prereqs = x; } } /* * initialize the viewpath */ static void view(void) { register char* s; register char* t; register char* p; register View_t* vp; View_t* zp; int c; int n; Stat_t st; Stat_t ts; char buf[CHUNK]; if (stat(".", &st)) report(3, "cannot stat", ".", (unsigned long)0); if ((s = (char*)search(state.vars, "PWD", NiL)) && !stat(s, &ts) && ts.st_dev == st.st_dev && ts.st_ino == st.st_ino) state.pwd = s; if (!state.pwd) { if (!getcwd(buf, sizeof(buf) - 1)) report(3, "cannot determine PWD", NiL, (unsigned long)0); state.pwd = duplicate(buf); search(state.vars, "PWD", state.pwd); } if ((s = (char*)search(state.vars, "VPATH", NiL)) && *s) { zp = 0; for (;;) { for (t = s; *t && *t != ':'; t++); if (c = *t) *t = 0; if (!state.view) { /* * determine the viewpath offset */ if (stat(s, &st)) report(3, "cannot stat top view", s, (unsigned long)0); if (stat(state.pwd, &ts)) report(3, "cannot stat", state.pwd, (unsigned long)0); if (ts.st_dev == st.st_dev && ts.st_ino == st.st_ino) p = "."; else { p = state.pwd + strlen(state.pwd); while (p > state.pwd) if (*--p == '/') { if (p == state.pwd) report(3, ". not under VPATH", s, (unsigned long)0); *p = 0; if (stat(state.pwd, &ts)) report(3, "cannot stat", state.pwd, (unsigned long)0); *p = '/'; if (ts.st_dev == st.st_dev && ts.st_ino == st.st_ino) { p++; break; } } if (p <= state.pwd) report(3, "cannot determine viewpath offset", s, (unsigned long)0); } } n = strlen(s); if (!(vp = newof(0, View_t, 1, strlen(p) + n + 1))) report(3, "out of memory [view]", s, (unsigned long)0); vp->node = n + 1; strcpy(vp->dir, s); *(vp->dir + n) = '/'; strcpy(vp->dir + n + 1, p); report(-4, vp->dir, "view", (unsigned long)0); if (!state.view) state.view = zp = vp; else zp = zp->next = vp; if (!c) break; *t++ = c; s = t; } } } /* * return next '?' or '}' in nested '}' */ static char* cond(register char* s) { register int n; if (*s == '?') s++; n = 0; for (;;) { switch (*s++) { case 0: break; case '{': n++; continue; case '}': if (!n--) break; continue; case '?': if (!n) break; continue; default: continue; } break; } return s - 1; } /* * expand var refs from s into buf */ static void substitute(Buf_t* buf, register char* s) { register char* t; register char* v; register char* q; register char* b; register int c; register int n; int a = 0; int i; while (c = *s++) { if (c == '$' && *s == '{') { b = s - 1; i = 1; for (n = *(t = ++s) == '-' ? 0 : '-'; (c = *s) && c != '?' && c != '+' && c != n && c != ':' && c != '=' && c != '[' && c != '}'; s++) if (!isalnum(c) && c != '_') i = 0; *s = 0; if (c == '[') { append(buf, b); *s = c; continue; } v = (char*)search(state.vars, t, NiL); if ((c == ':' || c == '=') && (!v || c == ':' && !*v)) { append(buf, b); *s = c; continue; } if (t[0] == 'A' && t[1] == 'R' && t[2] == 0) a = 1; *s = c; if (c && c != '}') { n = 1; for (t = ++s; *s; s++) if (*s == '{') n++; else if (*s == '}' && !--n) break; } switch (c) { case '?': q = cond(t - 1); if (v) { if (((q - t) != 1 || *t != '*') && strncmp(v, t, q - t)) v = 0; } else if (q == t) v = s; t = cond(q); if (v) { if (t > q) { c = *t; *t = 0; substitute(buf, q + 1); *t = c; } } else { q = cond(t); if (q > t) { c = *q; *q = 0; substitute(buf, t + 1); *q = c; } } break; case '+': case '-': if ((v == 0 || *v == 0) == (c == '-')) { c = *s; *s = 0; substitute(buf, t); *s = c; break; } if (c != '-') break; /* FALLTHROUGH */ case 0: case '=': case '}': if (v) { if (a && t[0] == 'm' && t[1] == 'a' && t[2] == 'm' && t[3] == '_' && t[4] == 'l' && t[5] == 'i' && t[6] == 'b') { for (t = v; *t == ' '; t++); for (; *t && *t != ' '; t++); if (*t) *t = 0; else t = 0; substitute(buf, v); if (t) *t = ' '; } else substitute(buf, v); } else if (i) { c = *s; *s = 0; append(buf, b); *s = c; continue; } break; } if (*s) s++; } else add(buf, c); } } /* * expand var refs from s into buf and return buf base */ static char* expand(Buf_t* buf, char* s) { substitute(buf, s); return use(buf); } /* * stat() with .exe check */ static char* status(Buf_t* buf, int off, char* path, struct stat* st) { int r; char* s; Buf_t* tmp; if (!stat(path, st)) return path; if (!(tmp = buf)) { tmp = buffer(); off = 0; } if (off) set(tmp, off); else append(tmp, path); append(tmp, ".exe"); s = use(tmp); r = stat(s, st); if (!buf) { drop(tmp); s = path; } if (r) { if (off) s[off] = 0; s = 0; } return s; } /* * return path to file */ static char* find(Buf_t* buf, char* file, struct stat* st) { char* s; View_t* vp; int node; int c; int o; if (s = status(buf, 0, file, st)) { report(-3, s, "find", (unsigned long)0); return s; } if (vp = state.view) { node = 0; if (*file == '/') { do { if (!strncmp(file, vp->dir, vp->node)) { file += vp->node; node = 2; break; } } while (vp = vp->next); } else vp = vp->next; if (vp) do { if (node) { c = vp->dir[vp->node]; vp->dir[vp->node] = 0; append(buf, vp->dir); vp->dir[vp->node] = c; } else { append(buf, vp->dir); append(buf, "/"); } append(buf, file); o = get(buf); s = use(buf); if (s = status(buf, o, s, st)) { report(-3, s, "find", (unsigned long)0); return s; } } while (vp = vp->next); } return 0; } /* * bind r to a file and return the modify time */ static unsigned long bind(Rule_t* r) { char* s; Buf_t* buf; struct stat st; buf = buffer(); if (s = find(buf, r->name, &st)) { if (s != r->name) r->path = duplicate(s); r->time = st.st_mtime; r->flags |= RULE_exists; } drop(buf); return r->time; } /* * pop the current input file */ static int pop(void) { int r; if (!state.sp) report(3, "input stack underflow", NiL, (unsigned long)0); if (!state.sp->fp || (state.sp->flags & STREAM_KEEP)) r = 0; else if (state.sp->flags & STREAM_PIPE) r = pclose(state.sp->fp); else r = fclose(state.sp->fp); if (state.sp == state.streams) state.sp = 0; else state.sp--; return r; } /* * push file onto the input stack */ static int push(char* file, Stdio_t* fp, int flags) { char* path; Buf_t* buf; struct stat st; if (!state.sp) state.sp = state.streams; else if (++state.sp >= &state.streams[elementsof(state.streams)]) report(3, "input stream stack overflow", NiL, (unsigned long)0); if (state.sp->fp = fp) { if(state.sp->file) free(state.sp->file); state.sp->file = strdup("pipeline"); if(!state.sp->file) report(3, "out of memory [push]", NiL, (unsigned long)0); } else if (flags & STREAM_PIPE) report(3, "pipe error", file, (unsigned long)0); else if (!file || !strcmp(file, "-") || !strcmp(file, "/dev/stdin")) { flags |= STREAM_KEEP; if(state.sp->file) free(state.sp->file); state.sp->file = strdup("/dev/stdin"); if(!state.sp->file) report(3, "out of memory [push]", NiL, (unsigned long)0); state.sp->fp = stdin; } else { buf = buffer(); if (path = find(buf, file, &st)) { if (!(state.sp->fp = fopen(path, "r"))) report(3, "cannot read", path, (unsigned long)0); if(state.sp->file) free(state.sp->file); state.sp->file = duplicate(path); drop(buf); } else { drop(buf); pop(); if (flags & STREAM_MUST) report(3, "not found", file, (unsigned long)0); return 0; } } state.sp->flags = flags; state.sp->line = 0; return 1; } /* * return the next input line */ static char* input(void) { char* e; if (!state.sp) report(3, "no input file stream", NiL, (unsigned long)0); if (state.peek) state.peek = 0; else if (!fgets(state.input, sizeof(state.input), state.sp->fp)) return 0; else if (*state.input && *(e = state.input + strlen(state.input) - 1) == '\n') *e = 0; state.sp->line++; e = state.input; while (isspace(*e)) e++; /* allow indentation */ return e; } /* * pass shell action s to ${SHELL:-/bin/sh} * the -c wrapper ensures that scripts are run in the selected shell * even on systems that otherwise demand #! magic (can you say Cygwin) */ static int execute(register char* s) { register int c; Buf_t* buf; if (!state.shell && (!(state.shell = (char*)search(state.vars, "SHELL", NiL)) || !strcmp(state.shell, sh))) state.shell = sh; buf = buffer(); append(buf, state.shell); append(buf, " -c '"); while (c = *s++) { if (c == '\'') { add(buf, c); for (s--; *s == c; s++) { add(buf, '\\'); add(buf, c); } } add(buf, c); } add(buf, '\''); s = use(buf); report(-5, s, "exec", (unsigned long)0); if ((c = system(s)) > 255) c >>= 8; drop(buf); return c; } /* * run action s to update r */ static unsigned long run(Rule_t* r, register char* s) { register Rule_t* q; register char* t; register int c; register View_t* v; int i; int j; int x; Stat_t st; Buf_t* buf; if (r->flags & RULE_error) return r->time; buf = buffer(); if (!strncmp(s, "mamake -r ", 10)) { state.verified = 1; x = !state.never; } else x = state.exec; if (x) append(buf, "trap - 1 2 3 15\nPATH=.:$PATH\nset -x\n"); if (state.view) { do { for (; delimiter(*s); s++) add(buf, *s); for (t = s; *s && !delimiter(*s); s++); c = *s; *s = 0; if (c == '=') { append(buf, t); continue; } if ((q = (Rule_t*)search(state.rules, t, NiL)) && q->path && !(q->flags & RULE_generated)) append(buf, q->path); else { append(buf, t); if (*t == '-' && *(t + 1) == 'I' && (*(t + 2) || c)) { if (*(t + 2)) i = 2; else { for (i = 3; *(t + i) == ' ' || *(t + i) == '\t'; i++); *s = c; for (s = t + i; *s && *s != ' ' && *s != '\t' && *s != '\n'; s++); c = *s; *s = 0; append(buf, t + 2); } if (*(t + i) && *(t + i) != '/') { v = state.view; while (v = v->next) { add(buf, ' '); for (j = 0; j < i; j++) add(buf, *(t + j)); append(buf, v->dir); if (*(t + i) != '.' || *(t + i + 1)) { add(buf, '/'); append(buf, t + i); } } } } } } while (*s = c); s = use(buf); } else if (x) { append(buf, s); s = use(buf); } if (x) { if (c = execute(s)) dont(r, c, state.keepgoing); if (status((Buf_t*)0, 0, r->name, &st)) { r->time = st.st_mtime; r->flags |= RULE_exists; } else r->time = NOW; } else { fprintf(stdout, "%s\n", s); if (state.debug) fflush(stdout); r->time = NOW; r->flags |= RULE_exists; } drop(buf); return r->time; } /* * return the full path for s using buf workspace */ static char* path(Buf_t* buf, char* s, int must) { register char* p; register char* d; register char* x; char* e; register int c; int t; int o; Stat_t st; for (e = s; *e && *e != ' ' && *e != '\t'; e++); t = *e; if ((x = status(buf, 0, s, &st)) && (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) return x; if (!(p = (char*)search(state.vars, "PATH", NiL))) report(3, "variable not defined", "PATH", (unsigned long)0); do { for (d = p; *p && *p != ':'; p++); c = *p; *p = 0; if (*d && (*d != '.' || *(d + 1))) { append(buf, d); add(buf, '/'); } *p = c; if (t) *e = 0; append(buf, s); if (t) *e = t; o = get(buf); x = use(buf); if ((x = status(buf, o, x, &st)) && (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) return x; } while (*p++); if (must) report(3, "command not found", s, (unsigned long)0); return 0; } /* * generate (if necessary) and read the MAM probe information * done on the first `setv CC ...' */ static void probe(void) { register char* cc; register char* s; unsigned long h; unsigned long q; Buf_t* buf; Buf_t* pro; Buf_t* tmp; struct stat st; static char let[] = "ABCDEFGHIJKLMNOP"; static char cmd[] = "mamprobe"; if (!(cc = (char*)search(state.vars, "CC", NiL))) cc = "cc"; buf = buffer(); s = path(buf, cmd, 1); q = stat(s, &st) ? (unsigned long)0 : (unsigned long)st.st_mtime; pro = buffer(); s = cc = path(pro, cc, 1); for (h = 0; *s; s++) h = h * 0x63c63cd9L + *s + 0x9c39c33dL; if (!(s = (char*)search(state.vars, "INSTALLROOT", NiL))) report(3, "variable must be defined", "INSTALLROOT", (unsigned long)0); append(buf, s); append(buf, "/lib/probe/C/mam/"); for (h &= 0xffffffffL; h; h >>= 4) add(buf, let[h & 0xf]); s = use(buf); h = stat(s, &st) ? (unsigned long)0 : (unsigned long)st.st_mtime; if (h < q || !push(s, (Stdio_t*)0, 0)) { tmp = buffer(); append(tmp, cmd); add(tmp, ' '); append(tmp, s); add(tmp, ' '); append(tmp, cc); if (execute(use(tmp))) report(3, "cannot generate probe info", s, (unsigned long)0); drop(tmp); if (!push(s, (Stdio_t*)0, 0)) report(3, "cannot read probe info", s, (unsigned long)0); } drop(pro); drop(buf); make(rule("")); pop(); } /* * add attributes in s to r */ static void attributes(register Rule_t* r, register char* s) { register char* t; register int n; for (;;) { for (; *s == ' '; s++); for (t = s; *s && *s != ' '; s++); if (!(n = s - t)) break; switch (*t) { case 'd': if (n == 8 && !strncmp(t, "dontcare", n)) r->flags |= RULE_dontcare; break; case 'g': if (n == 9 && !strncmp(t, "generated", n)) r->flags |= RULE_generated; break; case 'i': if (n == 6 && !strncmp(t, "ignore", n)) r->flags |= RULE_ignore; else if (n == 8 && !strncmp(t, "implicit", n)) r->flags |= RULE_implicit; break; case 'v': if (n == 7 && !strncmp(t, "virtual", n)) r->flags |= RULE_virtual; break; } } } /* * define ${mam_libX} for library reference lib */ static char* require(char* lib, int dontcare) { register int c; char* s; char* r; FILE* f; Buf_t* buf; Buf_t* tmp; struct stat st; int tofree = 0; static int dynamic = -1; if (dynamic < 0) dynamic = (s = search(state.vars, "mam_cc_L", NiL)) ? atoi(s) : 0; if (!(r = search(state.vars, lib, NiL))) { buf = buffer(); tmp = buffer(); s = 0; for (;;) { if (s) append(buf, s); if (r = search(state.vars, "mam_cc_PREFIX_ARCHIVE", NiL)) append(buf, r); append(buf, lib + 2); if (r = search(state.vars, "mam_cc_SUFFIX_ARCHIVE", NiL)) append(buf, r); r = expand(tmp, use(buf)); if (!stat(r, &st)) break; if (s) { r = lib; break; } s = "${INSTALLROOT}/lib/"; if (dynamic) { append(buf, s); if (r = search(state.vars, "mam_cc_PREFIX_SHARED", NiL)) append(buf, r); append(buf, lib + 2); if (r = search(state.vars, "mam_cc_SUFFIX_SHARED", NiL)) append(buf, r); r = expand(tmp, use(buf)); if (!stat(r, &st)) { r = lib; break; } } } if (r != lib) { tofree = 1; r = duplicate(r); } search(state.vars, lib, r); append(tmp, lib + 2); append(tmp, ".req"); if (!(f = fopen(use(tmp), "r"))) { append(tmp, "${INSTALLROOT}/lib/lib/"); append(tmp, lib + 2); f = fopen(expand(buf, use(tmp)), "r"); } if (f) { for (;;) { while ((c = fgetc(f)) == ' ' || c == '\t' || c == '\n'); if (c == EOF) break; do { add(tmp, c); } while ((c = fgetc(f)) != EOF && c != ' ' && c != '\t' && c != '\n'); s = use(tmp); if (s[0] && (s[0] != '-' || s[1])) { add(buf, ' '); append(buf, require(s, 0)); } } fclose(f); if(tofree) free(r); r = use(buf); } else if (dontcare) { append(tmp, "set -\n"); append(tmp, "cd \"${TMPDIR:-/tmp}\"\n"); append(tmp, "echo 'int main(){return 0;}' > x.${!-$$}.c\n"); append(tmp, "${CC} ${CCFLAGS} -o x.${!-$$}.x x.${!-$$}.c "); append(tmp, r); append(tmp, " >/dev/null 2>&1\n"); append(tmp, "c=$?\n"); append(tmp, "rm -f x.${!-$$}.[cox]\n"); append(tmp, "exit $c\n"); if (execute(expand(buf, use(tmp)))) { if(tofree) free(r); r = ""; } } r = duplicate(r); search(state.vars, lib, r); append(tmp, "mam_lib"); append(tmp, lib + 2); search(state.vars, use(tmp), r); drop(tmp); drop(buf); } return r; } /* * input() until `done r' */ static unsigned long make(Rule_t* r) { register char* s; register char* t; register char* u; register char* v; register Rule_t* q; unsigned long z; unsigned long x; Buf_t* buf; Buf_t* cmd; r->making++; if (r->flags & RULE_active) state.active++; if (*r->name) { z = bind(r); state.indent++; report(-1, r->name, "make", r->time); } else z = 0; buf = buffer(); cmd = 0; while (s = input()) { for (; *s == ' '; s++); for (; isdigit(*s); s++); for (; *s == ' '; s++); for (u = s; *s && *s != ' '; s++); if (*s) { for (*s++ = 0; *s == ' '; s++); for (t = s; *s && *s != ' '; s++); if (*s) for (*s++ = 0; *s == ' '; s++); v = s; } else t = v = s; switch (KEY(u[0], u[1], u[2], u[3])) { case KEY('b','i','n','d'): if ((t[0] == '-' || t[0] == '+') && t[1] == 'l' && (s = require(t, !strcmp(v, "dontcare"))) && strncmp(r->name, "FEATURE/", 8) && strcmp(r->name, "configure.h")) for (;;) { for (t = s; *s && *s != ' '; s++); if (*s) *s = 0; else s = 0; if (*t) { q = rule(expand(buf, t)); attributes(q, v); x = bind(q); if (z < x) z = x; if (q->flags & RULE_error) r->flags |= RULE_error; } if (!s) break; for (*s++ = ' '; *s == ' '; s++); } continue; case KEY('d','o','n','e'): q = rule(expand(buf, t)); if (q != r) report(2, "improper done statement", t, (unsigned long)0); attributes(r, v); if (cmd && state.active && (state.force || r->time < z || !r->time && !z)) { if (state.explain && !state.force) { if (!r->time) fprintf(stderr, "%s [not found]\n", r->name); else fprintf(stderr, "%s [%lu] older than prerequisites [%lu]\n", r->name, r->time, z); } substitute(buf, use(cmd)); x = run(r, use(buf)); if (z < x) z = x; } r->flags |= RULE_made; if (!(r->flags & (RULE_dontcare|RULE_error|RULE_exists|RULE_generated|RULE_implicit|RULE_virtual))) dont(r, 0, state.keepgoing); break; case KEY('e','x','e','c'): r->flags |= RULE_generated; if (r->path) { free(r->path); r->path = 0; r->time = 0; } if (state.active) { if (cmd) add(cmd, '\n'); else cmd = buffer(); append(cmd, v); } continue; case KEY('m','a','k','e'): q = rule(expand(buf, t)); if (!q->making) { attributes(q, v); x = make(q); if (!(q->flags & RULE_ignore) && z < x) z = x; if (q->flags & RULE_error) r->flags |= RULE_error; } continue; case KEY('p','r','e','v'): q = rule(expand(buf, t)); if (!q->making) { if (!(q->flags & RULE_ignore) && z < q->time) z = q->time; if (q->flags & RULE_error) r->flags |= RULE_error; state.indent++; report(-2, q->name, "prev", q->time); state.indent--; } continue; case KEY('s','e','t','v'): if (!search(state.vars, t, NiL)) { if (*v == '"') { s = v + strlen(v) - 1; if (*s == '"') { *s = 0; v++; } } search(state.vars, t, duplicate(expand(buf, v))); } if (!state.probed && t[0] == 'C' && t[1] == 'C' && !t[2]) { state.probed = 1; probe(); } continue; default: continue; } break; } drop(buf); if (cmd) drop(cmd); if (*r->name) { report(-1, r->name, "done", z); state.indent--; } if (r->flags & RULE_active) state.active--; r->making--; return r->time = z; } /* * verify that active targets were made */ static int verify(Dict_item_t* item, void* handle) { Rule_t* r = (Rule_t*)item->value; if ((r->flags & (RULE_active|RULE_error|RULE_made)) == RULE_active) dont(r, 0, 1); return 0; } /* * return 1 if name is an initializer */ static int initializer(char* name) { register char* s; if (s = last(name, '/')) s++; else s = name; return s[0] == 'I' && s[1] == 'N' && s[2] == 'I' && s[3] == 'T'; } /* * update recursion leaf r and its prerequisites */ static int update(register Rule_t* r) { register List_t* x; Buf_t* buf; static char cmd[] = "${MAMAKE} -C "; static char arg[] = " ${MAMAKEARGS}"; r->flags |= RULE_made; if (r->leaf) r->leaf->flags |= RULE_made; for (x = r->prereqs; x; x = x->next) if (x->rule->leaf && !(x->rule->flags & RULE_made)) update(x->rule); buf = buffer(); substitute(buf, cmd); append(buf, r->name); substitute(buf, arg); run(r, use(buf)); drop(buf); return 0; } /* * scan makefile prereqs */ static int scan(Dict_item_t* item, void* handle) { register Rule_t* r = (Rule_t*)item->value; register char* s; register char* t; register char* u; register char* w; Rule_t* q; int i; int j; int k; int p; Buf_t* buf; static char* files[] = { "Mamfile" /* ksh 93u+m no longer uses these: * "Nmakefile", * "nmakefile", * "Makefile", * "makefile" */ }; /* * drop non-leaf rules */ if (!r->leaf) return 0; /* * always make initializers */ if (initializer(r->name)) { if (!(r->flags & RULE_made)) update(r); return 0; } buf = buffer(); for (i = 0; i < elementsof(files); i++) { append(buf, r->name); add(buf, '/'); append(buf, files[i]); if (push(use(buf), (Stdio_t*)0, 0)) { while (s = input()) { j = p = 0; while (*s) { for (k = 1; (i = *s) == ' ' || i == '\t' || i == '"' || i == '\''; s++); for (t = s; (i = *s) && i != ' ' && i != '\t' && i != '"' && i != '\'' && i != '\\' && i != ':'; s++) if (i == '/') t = s + 1; else if (i == '.' && *(s + 1) != 'c' && *(s + 1) != 'C' && *(s + 1) != 'h' && *(s + 1) != 'H' && t[0] == 'l' && t[1] == 'i' && t[2] == 'b') *s = 0; if (*s) *s++ = 0; if (!t[0]) k = 0; else if ((t[0] == '-' || t[0] == '+') && t[1] == 'l' && t[2]) { append(buf, "lib"); append(buf, t + 2); t = use(buf); } else if (p) { if (t[0] == '+' && !t[1]) p = 2; else if (p == 1) { if (i != ':' || strncmp(s, "command", 7)) { append(buf, "lib"); append(buf, t); t = use(buf); } if (i == ':') while (*s && (*s == ' ' || *s == '\t')) s++; } } else if (i == ':') { if (j != ':' || !isupper(*t)) k = 0; else if (!strcmp(t, "PACKAGE")) { p = 1; k = 0; } else for (u = t; *u; u++) if (isupper(*u)) *u = tolower(*u); else if (!isalnum(*u)) { k = 0; break; } } else if (t[0] != 'l' || t[1] != 'i' || t[2] != 'b') k = 0; else for (u = t + 3; *u; u++) if (!isalnum(*u)) { k = 0; break; } if (k && ((q = (Rule_t*)search(state.leaf, t, NiL)) && q != r || *t++ == 'l' && *t++ == 'i' && *t++ == 'b' && *t && (q = (Rule_t*)search(state.leaf, t, NiL)) && q != r)) { for (t = w = r->name; *w; w++) if (*w == '/') t = w + 1; if (t[0] == 'l' && t[1] == 'i' && t[2] == 'b') t += 3; for (u = w = q->name; *w; w++) if (*w == '/') u = w + 1; if (strcmp(t, u)) cons(r, q); } j = i; } } pop(); for (s = 0, w = r->name; *w; w++) if (*w == '/') s = w; if (s) { if ((s - r->name) > 3 && *(s - 1) == 'b' && *(s - 2) == 'i' && *(s - 3) == 'l' && *(s - 4) != '/') { /* * foolib : foo : libfoo */ *(s - 3) = 0; q = (Rule_t*)search(state.leaf, r->name, NiL); if (q && q != r) cons(r, q); for (t = w = r->name; *w; w++) if (*w == '/') t = w + 1; append(buf, "lib"); append(buf, t); q = (Rule_t*)search(state.leaf, use(buf), NiL); if (q && q != r) cons(r, q); *(s - 3) = 'l'; } else if (((s - r->name) != 3 || *(s - 1) != 'b' || *(s - 2) != 'i' || *(s - 3) != 'l') && (*(s + 1) != 'l' || *(s + 2) != 'i' || *(s + 3) != 'b')) { /* * huh/foobar : lib/libfoo */ s++; t = s + strlen(s); while (--t > s) { append(buf, "lib/lib"); appendn(buf, s, t - s); q = (Rule_t*)search(state.leaf, use(buf), NiL); if (q && q != r) cons(r, q); } } } break; } } drop(buf); return 0; } /* * descend into op and its prereqs */ static int descend(Dict_item_t* item, void* handle) { Rule_t* r = (Rule_t*)item->value; if (!state.active && (!(r->flags & RULE_active) || !(r = (Rule_t*)search(state.leaf, r->name, NiL)))) return 0; return r->leaf && !(r->flags & RULE_made) ? update(r) : 0; } /* * append the non-leaf active targets to state.opt */ static int active(Dict_item_t* item, void* handle) { Rule_t* r = (Rule_t*)item->value; if (r->flags & RULE_active) { if (r->leaf || search(state.leaf, r->name, NiL)) state.active = 0; else { add(state.opt, ' '); append(state.opt, r->name); } } return 0; } /* * recurse on mamfiles in subdirs matching pattern */ static int recurse(char* pattern) { register char* s; register char* t; Rule_t* r; Buf_t* buf; Buf_t* tmp; struct stat st; /* * first determine the MAM subdirs */ tmp = buffer(); buf = buffer(); state.exec = !state.never; state.leaf = dictionary(); append(buf, "ls -d "); append(buf, pattern); s = use(buf); push("recurse", popen(s, "r"), STREAM_PIPE); while (s = input()) { append(buf, s); add(buf, '/'); append(buf, mamfile); if (find(tmp, use(buf), &st)) { r = rule(s); if (t = last(r->name, '/')) t++; else t = r->name; r->leaf = rule(t); search(state.leaf, t, r); } } pop(); drop(buf); drop(tmp); /* * grab the non-leaf active targets */ if (!state.active) { state.active = 1; walk(state.rules, active, NiL); } search(state.vars, "MAMAKEARGS", duplicate(use(state.opt) + 1)); /* * scan the makefile and descend */ walk(state.rules, scan, NiL); state.view = 0; walk(state.rules, descend, NiL); return 0; } int main(int argc, char** argv) { register char** e; register char* s; register char* t; register char* v; Buf_t* tmp; int c; /* * initialize the state */ state.id = "mamake"; state.active = 1; state.exec = 1; state.file = mamfile; state.opt = buffer(); state.rules = dictionary(); state.vars = dictionary(); search(state.vars, "MAMAKE", *argv); /* * parse the options */ #if _PACKAGE_ast error_info.id = state.id; for (;;) { switch (optget(argv, usage)) { case 'e': append(state.opt, " -e"); state.explain = 1; continue; case 'i': append(state.opt, " -i"); state.ignore = 1; continue; case 'k': append(state.opt, " -k"); state.keepgoing = 1; continue; case 'N': state.never = 1; /* FALLTHROUGH */ case 'n': append(state.opt, " -n"); state.exec = 0; continue; case 'F': append(state.opt, " -F"); state.force = 1; continue; case 'K': continue; case 'V': fprintf(stdout, "%s\n", id + 10); exit(0); case 'f': append(state.opt, " -f "); append(state.opt, opt_info.arg); state.file = opt_info.arg; continue; case 'r': state.recurse = opt_info.arg; continue; case 'C': state.directory = opt_info.arg; continue; case 'D': append(state.opt, " -D"); append(state.opt, opt_info.arg); state.debug = -opt_info.num; continue; case 'G': append(state.opt, " -G"); search(state.vars, "-debug-symbols", "1"); continue; case 'S': append(state.opt, " -S"); search(state.vars, "-strip-symbols", "1"); continue; case '?': error(ERROR_usage(2), "%s", opt_info.arg); UNREACHABLE(); case ':': error(2, "%s", opt_info.arg); continue; } break; } if (error_info.errors) { error(ERROR_usage(2), "%s", optusage(NiL)); UNREACHABLE(); } argv += opt_info.index; #else while ((s = *++argv) && *s == '-') { if (*(s + 1) == '-') { if (!*(s + 2)) { append(state.opt, " --"); argv++; break; } for (t = s += 2; *t && *t != '='; t++); if (!strncmp(s, "debug-symbols", t - s) && append(state.opt, " -G") || !strncmp(s, "strip-symbols", t - s) && append(state.opt, " -S")) { if (*t) { v = t + 1; if (t > s && *(t - 1) == '+') t--; c = *t; *t = 0; } else { c = 0; v = "1"; } search(state.vars, s - 1, v); if (c) *t = c; continue; } usage(); break; } for (;;) { switch (*++s) { case 0: break; case 'e': append(state.opt, " -e"); state.explain = 1; continue; case 'i': append(state.opt, " -i"); state.ignore = 1; continue; case 'k': append(state.opt, " -k"); state.keepgoing = 1; continue; case 'N': state.never = 1; /* FALLTHROUGH */ case 'n': append(state.opt, " -n"); state.exec = 0; continue; case 'F': append(state.opt, " -F"); state.force = 1; continue; case 'G': append(state.opt, " -G"); search(state.vars, "-debug-symbols", "1"); continue; case 'K': continue; case 'S': append(state.opt, " -S"); search(state.vars, "-strip-symbols", "1"); continue; case 'V': fprintf(stdout, "%s\n", id + 10); exit(0); case 'f': case 'r': case 'C': case 'D': t = s; if (!*++s && !(s = *++argv)) { report(2, "option value expected", t, (unsigned long)0); usage(); } else switch (*t) { case 'f': append(state.opt, " -f "); append(state.opt, s); state.file = s; break; case 'r': state.recurse = s; break; case 'C': state.directory = s; break; case 'D': append(state.opt, " -D"); append(state.opt, s); state.debug = -atoi(s); break; } break; default: report(2, "unknown option", s, (unsigned long)0); /* FALLTHROUGH */ case '?': usage(); break; } break; } } #endif /* * load the environment */ for (e = environ; s = *e; e++) for (t = s; *t; t++) if (*t == '=') { *t = 0; search(state.vars, s, t + 1); *t = '='; break; } /* * grab the command line targets and variable definitions */ while (s = *argv++) { for (t = s; *t; t++) if (*t == '=') { v = t + 1; if (t > s && *(t - 1) == '+') t--; c = *t; *t = 0; search(state.vars, s, v); tmp = buffer(); append(tmp, s); append(tmp, ".FORCE"); search(state.vars, use(tmp), v); drop(tmp); *t = c; break; } if (!*t) { /* * handle a few targets for nmake compatibility */ if (*s == 'e' && !strncmp(s, "error 0 $(MAKEVERSION:", 22)) exit(1); if (*s == 'r' && !strcmp(s, "recurse") || *s == 'c' && !strncmp(s, "cc-", 3)) continue; rule(s)->flags |= RULE_active; state.active = 0; if (state.recurse) continue; } add(state.opt, ' '); add(state.opt, '\''); append(state.opt, s); add(state.opt, '\''); } /* * initialize the views */ if (state.directory && chdir(state.directory)) report(3, "cannot change working directory", NiL, (unsigned long)0); view(); /* * recursion drops out here */ if (state.recurse) return recurse(state.recurse); /* * read the mamfile(s) and bring the targets up to date */ search(state.vars, "MAMAKEARGS", duplicate(use(state.opt) + 1)); push(state.file, (Stdio_t*)0, STREAM_MUST); make(rule("")); pop(); /* * verify that active targets were made */ if (!state.active && !state.verified) walk(state.rules, verify, NiL); /* * done */ return state.errors != 0; } ksh-1.0.0-beta.2/src/cmd/INIT/mamake.rt000066400000000000000000000024201415700074400172450ustar00rootroot00000000000000NOTE regression tests for the mamake command UNIT mamake TEST macros DATA Mamfile <<'!' info mam static 00000 1994-07-17 make (AT&T Research) 5.3 2009-05-05 setv DEFINED defined setv EMPTY make all exec - echo DEFINED ${DEFINED} exec - echo DEFINED:VALUE ${DEFINED:VALUE} exec - echo DEFINED:-VALUE ${DEFINED:-VALUE} exec - echo DEFINED=VALUE ${DEFINED=VALUE} exec - echo DEFINED[VALUE] ${DEFINED[VALUE]} exec - echo DEFINED.COMPONENT ${DEFINED.COMPONENT} exec - echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]} exec - echo EMPTY ${EMPTY} exec - echo EMPTY:VALUE ${EMPTY:VALUE} exec - echo EMPTY:-VALUE ${EMPTY:-VALUE} exec - echo EMPTY=VALUE ${EMPTY=VALUE} exec - echo EMPTY[VALUE] ${EMPTY[VALUE]} exec - echo EMPTY.COMPONENT ${EMPTY.COMPONENT} exec - echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]} exec - echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__} exec - echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE} exec - echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE} exec - echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE} exec - echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]} exec - echo __NoT_DeFiNeD__.COMPONENT ${__NoT_DeFiNeD__.COMPONENT} exec - echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VALUE]} done all generated virtual ! EXEC -n ksh-1.0.0-beta.2/src/cmd/INIT/mamake.tst000066400000000000000000000041601415700074400174350ustar00rootroot00000000000000# : : generated from mamake.rt by mktest : : # # regression tests for the mamake command UNIT mamake TEST 01 macros EXEC -n INPUT -n - INPUT Mamfile $'info mam static 00000 1994-07-17 make (AT&T Research) 5.3 2009-05-05 setv DEFINED defined setv EMPTY make all exec - echo DEFINED ${DEFINED} exec - echo DEFINED:VALUE ${DEFINED:VALUE} exec - echo DEFINED:-VALUE ${DEFINED:-VALUE} exec - echo DEFINED=VALUE ${DEFINED=VALUE} exec - echo DEFINED[VALUE] ${DEFINED[VALUE]} exec - echo DEFINED.COMPONENT ${DEFINED.COMPONENT} exec - echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]} exec - echo EMPTY ${EMPTY} exec - echo EMPTY:VALUE ${EMPTY:VALUE} exec - echo EMPTY:-VALUE ${EMPTY:-VALUE} exec - echo EMPTY=VALUE ${EMPTY=VALUE} exec - echo EMPTY[VALUE] ${EMPTY[VALUE]} exec - echo EMPTY.COMPONENT ${EMPTY.COMPONENT} exec - echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]} exec - echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__} exec - echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE} exec - echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE} exec - echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE} exec - echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]} exec - echo __NoT_DeFiNeD__.COMPONENT ${__NoT_DeFiNeD__.COMPONENT} exec - echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VAL'\ $'UE]} done all generated virtual' OUTPUT - $'echo DEFINED defined echo DEFINED:VALUE echo DEFINED:-VALUE echo DEFINED=VALUE defined echo DEFINED[VALUE] ${DEFINED[VALUE]} echo DEFINED.COMPONENT echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]} echo EMPTY echo EMPTY:VALUE ${EMPTY:VALUE} echo EMPTY:-VALUE ${EMPTY:-VALUE} echo EMPTY=VALUE echo EMPTY[VALUE] ${EMPTY[VALUE]} echo EMPTY.COMPONENT echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]} echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__} echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE} echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE} echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE} echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]} echo __NoT_DeFiNeD__.COMPONENT echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VALUE]}' ERROR -n - ksh-1.0.0-beta.2/src/cmd/INIT/mamprobe.sh000066400000000000000000000150561415700074400176120ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## ### this script contains archaic constructs that work with all sh variants ### # mamprobe - generate MAM cc probe info # Glenn Fowler (command set -o posix) 2>/dev/null && set -o posix command=mamprobe bins=` ( userPATH=$PATH PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH getconf PATH 2>/dev/null && echo "$userPATH" || echo /bin:/usr/bin:/sbin:/usr/sbin:"$userPATH" ) | sed 's/:/ /g' ` || exit # check the options opt= case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) USAGE=$' [-? @(#)$Id: mamprobe (AT&T Labs Research) 2011-02-11 $ ] [+NAME?mamprobe - generate MAM cc probe info] [+DESCRIPTION?\bmamprobe\b generates MAM (make abstract machine) \bcc\b(1) probe information for use by \bmamake\b(1). \acc-path\a is the absolute path of the probed compiler and \ainfo-file\a is where the information is placed. \ainfo-file\a is usually \b$INSTALLROOT/lib/probe/C/mam/\b\ahash\a, where \ahash\a is a hash of \acc-path\a. Any \ainfo-file\a directories are created if needed. If \ainfo-file\a is \b-\b then the probe information is written to the standard output.] [+?\bmamprobe\b and \bmamake\b are used in the bootstrap phase of \bpackage\b(1) installation before \bnmake\b(1) is built. The probed variable names are the \bnmake\b(1) names with a \bmam_\b prefix, \bCC\b converted to \bcc\b, and \b.\b converted to \b_\b. Additional variables are:]{ [+_hosttype_?the \bpackage\b(1) host type] [+mam_cc_L?\b-L\b\adir\a supported] [+STDCAT?command to execute for \bcat\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCHMOD?command to execute for \bchmod\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCMP?command to execute for \bcmp\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDCP?command to execute for \bcp\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDED?command to execute for \bed\b(1) or \bex\b(1)] [+STDEDFLAGS?flags for \bSTDED\b] [+STDLN?command to execute for \bln\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDMV?command to execute for \bmv\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] [+STDRM?command to execute for \brm\b(1); prefixed by \bexecrate\b(1) on \b.exe\b challenged systems] } [d:debug?Enable probe script debug trace.] info-file cc-path [+SEE ALSO?\bexecrate\b(1), \bpackage\b(1), \bmamake\b(1), \bnmake\b(1), \bprobe\b(1)] ' while getopts -a "$command" "$USAGE" OPT do case $OPT in d) opt=-d ;; esac done shift `expr $OPTIND - 1` ;; *) while : do case $# in 0) break ;; esac case $1 in --) shift break ;; -) break ;; -d) opt=-d ;; -*) echo $command: $1: unknown option >&2 ;; *) break ;; esac set '' break done ;; esac # check the args case $1 in -) ;; /*) ;; *) set '' ;; esac case $2 in /*) ;; *) set '' ;; esac case $# in 0|1) echo "Usage: $command info-file cc-path" >&2; exit 2 ;; esac info=$1 shift cc=$* # find the make probe script ifs=${IFS-' '} IFS=: set $PATH IFS=$ifs script=lib/probe/C/make/probe while : do case $# in 0) echo "$0: ../$script: probe script not found on PATH" >&2 exit 1 ;; esac case $1 in '') continue ;; esac makeprobe=`echo $1 | sed 's,[^/]*$,'$script,` if test -x $makeprobe then break fi shift done # create the info dir if necessary case $info in /*) i=X$info ifs=${IFS-' '} IFS=/ set $i IFS=$ifs while : do i=$1 shift case $i in X) break ;; esac done case $info in //*) path=/ ;; *) path= ;; esac while : do case $# in 0|1) break ;; esac comp=$1 shift case $comp in '') continue ;; esac path=$path/$comp if test ! -d $path then mkdir $path || exit fi done ;; esac # generate info in a tmp file and rename when finished case $info in -) ;; *) tmp=${TMPDIR:-/tmp}/mam$$ trap "exec >/dev/null; rm -f $tmp" 0 1 2 3 15 exec > $tmp echo "probing C language processor $cc for mam information" >&2 ;; esac echo "note generated by $0 for $cc" ( set '' $opt $cc shift . $makeprobe "$@" case " $CC_DIALECT " in *" -L "*) echo "CC.L = 1" ;; esac ) | sed \ -e '/^CC\./!d' \ -e 's/^CC./setv mam_cc_/' \ -e 's/^\([^=.]*\)\./\1_/' \ -e 's/^\([^=.]*\)\./\1_/' \ -e 's/ =//' \ -e 's/\$("\([^"]*\)")/\1/g' \ -e 's/\$(\([^)]*\))/${\1}/g' \ -e 's/\${CC\./${mam_cc_}/g' echo 'setv _hosttype_ ${mam_cc_HOSTTYPE}' # STD* are standard commands/flags with possible execrate(1) if ( ed < /dev/null 2>&1 then STDED=ed else STDED=ex fi STDEDFLAGS=- set STDCAT cat STDCHMOD chmod STDCMP cmp STDCP cp STDLN ln STDMV mv STDRM rm while : do case $# in 0|1) break ;; esac p=$2 for d in $bins do if test -x $d/$p then p=$d/$p break fi done eval $1=\$p shift shift done if execrate then for n in STDCAT STDCHMOD STDCMP STDCP STDLN STDMV STDRM do eval $n=\"execrate \$$n\" done fi for n in STDCAT STDCHMOD STDCMP STDCP STDED STDEDFLAGS STDLN STDMV STDRM do eval echo setv \$n \$$n done # all done case $info in -) ;; *) exec >/dev/null test -f "$info" && rm -f "$info" cp "$tmp" "$info" chmod -w "$info" ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/mkdir.sh000066400000000000000000000045041415700074400171120ustar00rootroot00000000000000#!/bin/sh ######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : mkdir for systems that do not support -p : 2002-09-01 : (command set -o posix) 2>/dev/null && set -o posix MKDIR=mkdir CHMOD=chmod mode= parents= while : do case $1 in -m) case $# in 1) echo "mkdir: -m: mode argument expected" >&2 exit 1 ;; esac shift mode=$1 ;; -m*) mode=`echo X$1 | sed 's/X-m//'` ;; -p) parents=1 ;; *) break ;; esac shift done if test "" != "$parents" then for d do if test ! -d $d then ifs=${IFS-' '} IFS=/ set '' $d IFS=$ifs shift dir=$1 shift if test -n "$dir" -a ! -d "$dir" then $MKDIR "$dir" || exit 1 if test "" != "$mode" then $CHMOD "$mode" "$dir" || exit 1 fi fi for d do dir=$dir/$d if test ! -d "$dir" then $MKDIR "$dir" || exit 1 if test "" != "$mode" then $CHMOD "$mode" "$dir" || exit 1 fi fi done fi done else $MKDIR "$@" || exit 1 if test "" != "$mode" then for d do $CHMOD "$mode" "$d" || exit 1 done fi fi exit 0 ksh-1.0.0-beta.2/src/cmd/INIT/mktest.sh000077500000000000000000000367171415700074400173310ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : mktest - generate regress or shell regression test scripts command=mktest stdin=8 stdout=9 PREFIX=test STYLE=regress WIDTH=80 eval "exec $stdout>&1" case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in 0123) ARGV0="-a $command" USAGE=$' [-? @(#)$Id: mktest (AT&T Labs Research) 2010-08-11 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 2005-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?mktest - generate a regression test scripts] [+DESCRIPTION?\bmktest\b generates regression test scripts from test template commands in the \aunit\a.\brt\b file. The generated test script writes temporary output to '$PREFIX$'\aunit\a.tmp and compares it to the expected output in '$PREFIX$'\aunit\a.out. Run the test script with the \b--accept\b option to (re)generate the '$PREFIX$'\aunit\a.out.] [s:style?The script style:]:[style:='$STYLE$'] { [+regress?\bregress\b(1) command input.] [+shell?Standalone test shell script.] } [w:width?Set the output format width to approximately \awidth\a.]:[width:='$WIDTH$'] unit.rt [ unit [ arg ... ] ] [+INPUT FILES?The regression test command file \aunit\a\b.rt\b is a \bksh\b(1) script that makes calls to the following functions:] { [+DATA \afile\a [ - | [ options ]] data]]?Create input data \afile\a that is empty (-) or contains \adata\a subject to \bprint\b(1) \aoptions\a or that is a copy of the DATA command standard input. Set \afile\a to \b-\b to name the standard input.] [+DIAGNOSTICS?Diagnostic messages of unspecified format are expected.] [+DO \acommand\a [ \aarg\a ... ]]?Execute \acommand\a if the current test is active.] [+EXEC [ \aarg\a ... ]]?Run the command under test with optional arguments. If the standard input is not specified then the standard input of the previous EXEC is used. The standard input of the first EXEC in a TEST group is an empty regular file.] [+EXPORT \aname\a=\avalue\a ...?Export list for subsequent commands in the TEST group or for all TEST groups if before the first TEST group.] [+IGNORESPACE [ 0 | 1 ] ?Ignore space differences when comparing expected output.] [+KEEP \apattern\a ...?File match patterns of files to retain between TEST groups.] [+NOTE \acomment\a?\acomment\a is added to the current test script.] [+PROG \acommand\a [ \aarg\a ... ]]?Run \acommand\a with optional arguments.] [+TEST [ \anumber\a ]] [ \adescription\a ... ]]?Define a new test group with optional \anumber\a and \adescription\a.] [+TWD [ \adir\a ... ]]?Set the temporary test dir to \adir\a. The default is \aunit\a\b.tmp\b, where \aunit\a is the test input file sans directory and suffix. If \adir\a matches \b/*\b then it is the directory name; if \adir\a is non-null then the prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is omitted then \b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is used.] [+UMASK [ \amask\a ]]?Run subsequent tests with \bumask\b(1) \amask\a. If \amask\a is omitted then the original \bumask\b is used.] [+UNIT \acommand\a [ \aarg\a ... ]]?Define the command and optional default arguments to be tested. \bUNIT\b explicitly overrides the default command name derived from the test script file name.] [+WIDTH \awidth\a?Set the output format width to approximately \awidth\a.] } [+SEE ALSO?\bregress\b(1), \bksh\b(1)] ' ;; *) ARGV0="" USAGE='s: unit.rt [ arg ... ]' ;; esac typeset ARG SCRIPT UNIT TEMP=${TMPDIR:-/tmp}/$command.$$.tmp WORK typeset IO INPUT INPUT_N OUTPUT OUTPUT_N ERROR ERROR_N KEEP typeset -C STATE typeset -A DATA STATE.RESET REMOVE FORMAT integer KEEP_UNIT=0 SCRIPT_UNIT=0 TEST=0 CODE=0 EXIT=0 ACCEPT=0 DIAGNOSTICS=0 code while getopts $ARGV0 "$USAGE" OPT do case $OPT in s) case $OPTARG in regress|shell) STYLE=$OPTARG ;; *) print -u2 -r -- $command: --style=$OPTARG: regress or shell expected exit 1 ;; esac ;; w) WIDTH=$OPTARG ;; *) OPTIND=0 getopts $ARGV0 "$USAGE" OPT '-?' exit 2 ;; esac done shift $OPTIND-1 typeset SINGLE= quote='%${SINGLE}..${WIDTH}q' if [[ $1 == - ]] then shift fi if (( ! $# )) then print -u2 -r -- $command: test command script path expected exit 1 fi SCRIPT=$1 shift if [[ ! -r $SCRIPT ]] then print -u2 -r -- $command: $SCRIPT: cannot read exit 1 fi (ulimit -c 0) >/dev/null 2>&1 && ulimit -c 0 if (( $# )) then set -A UNIT -- "$@" KEEP_UNIT=1 else ARG=${SCRIPT##*/} set -A UNIT -- "${ARG%.*}" fi WORK=${UNIT[0]}.tmp rm -rf $WORK mkdir $WORK || exit export PATH=$PWD:$PATH function LINE { if [[ $STYLE == regress ]] then print -u$stdout fi } function NOTE { case $STYLE in regress)LINE print -u$stdout -r -- '#' "$@" ;; shell) print -u$stdout -r -f ": $QUOTE"$'\n' -- "$*" ;; esac } function UNIT { (( KEEP_UNIT )) || set -A UNIT -- "$@" case $STYLE in regress)LINE print -u$stdout -r -f $'UNIT' for ARG in "$@" do print -u$stdout -r -f " $QUOTE" -- "$ARG" done print -u$stdout ;; shell) print -u$stdout -r -f $'set x' for ARG in "$@" do print -u$stdout -r -f " $QUOTE" -- "$ARG" done print -u$stdout print -u$stdout shift ;; esac } function TEST { typeset i typeset -A REM if (( ${#STATE.RESET[@]} )) then unset ${!STATE.RESET[@]} case $STYLE in shell) print -u$stdout -r -- unset ${!STATE.RESET[@]} ;; esac unset STATE.RESET typeset -A STATE.RESET fi if (( ${#REMOVE[@]} )) then rm -f -- "${!REMOVE[@]}" case $STYLE in shell) print -u$stdout -r -f $'rm -f' for i in ${!REMOVE[@]} do print -u$stdout -r -f " $QUOTE" "$i" done print -u$stdout ;; esac for i in ${!REMOVE[@]} do unset REMOVE[$i] done fi rm -rf $WORK/* if [[ $1 == +([0-9]) ]] then TEST=${1##0} shift else ((TEST++)) fi LINE case $STYLE in regress)print -u$stdout -r -f "TEST %02d $QUOTE"$'\n' -- $TEST "$*" ;; shell) print -u$stdout -r -f ": TEST %02d $QUOTE"$'\n' -- $TEST "$*" ;; esac : > $TEMP.INPUT > $TEMP.in INPUT= INPUT_N= OUTPUT= OUTPUT_N= ERROR= ERROR_N= UMASK=$UMASK_ORIG UMASK_DONE=$UMASK CODE=0 } function TWD { case $STYLE in regress)LINE print -u$stdout -r -f $'TWD' for ARG in "$@" do print -u$stdout -r -f " $QUOTE" -- "$ARG" done print -u$stdout ;; esac } function RUN { typeset i n p op unit sep output=1 error=1 exitcode=1 op=$1 shift while : do case $1 in ++NOOUTPUT) output= ;; ++NOERROR) error= ;; ++NOEXIT) exitcode= ;; ++*) print -u2 -r -- $command: $0: $1: unknown option; exit 1 ;; *) break ;; esac shift done if [[ $op == PROG ]] then unit=$1 shift elif (( ! ${#UNIT[@]} )) then print -u2 -r -- $command: $SCRIPT: UNIT statement or operand expected exit 1 fi LINE case $STYLE in regress)if [[ $op == PROG ]] then print -u$stdout -r -f $'\t'"$op"$'\t'"$unit" sep=$' ' else print -u$stdout -r -f $'\t'"$op" sep=$'\t' fi for ARG in "$@" do LC_CTYPE=C print -u$stdout -r -f "$sep$QUOTE" -- "$ARG" sep=$' ' done print -u$stdout [[ ${DATA[-]} || /dev/fd/0 -ef /dev/fd/$stdin ]] || cat > $TEMP.in IO=$(cat $TEMP.in; print :) if [[ $IO == ?*$'\n:' ]] then IO=${IO%??} n= else IO=${IO%?} n=-n fi { [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK cd $WORK if [[ $op == PROG ]] then "$unit" "$@" code=$? else "${UNIT[@]}" "$@" code=$? fi cd .. [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG } < $TEMP.in > $TEMP.out 2> $TEMP.err if [[ $IO != "$INPUT" || $n != "$INPUT_N" ]] then INPUT=$IO INPUT_N=$n if [[ ${FORMAT[-]} ]] then print -u$stdout -n -r -- $'\t\tINPUT' print -u$stdout -r -f " $QUOTE" -- "${FORMAT[-]}" print -u$stdout -r -f " $QUOTE" -- - unset FORMAT[-] else print -u$stdout -n -r -- $'\t\tINPUT' $n - [[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO" fi print -u$stdout unset DATA[-] fi for i in ${!DATA[@]} do if [[ ${FORMAT[$i]} ]] then print -u$stdout -n -r -- $'\t\tINPUT' print -u$stdout -r -f " $QUOTE" -- "${FORMAT[$i]}" print -u$stdout -r -f " $QUOTE" -- "$i" unset FORMAT[$i] else case $i in -) p=$TEMP.in ;; *) p=$WORK/$i ;; esac IO=$(cat $p; print :) if [[ $IO == ?*$'\n:' ]] then IO=${IO%??} n= else IO=${IO%?} n=-n fi print -u$stdout -n -r -- $'\t\tINPUT' $n print -u$stdout -r -f " $QUOTE" -- "$i" [[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO" fi print -u$stdout unset DATA[$i] done IO=$(cat $TEMP.out; print :) if [[ $IO == ?*$'\n:' ]] then IO=${IO%??} n= else IO=${IO%?} n=-n fi if [[ $IO != "$OUTPUT" || $n != "$OUTPUT_N" ]] then OUTPUT=$IO OUTPUT_N=$n if [[ $output ]] then if [[ ! -s $TEMP.out ]] then print -u$stdout -n -r -- $'\t\tOUTPUT' - elif cmp -s $TEMP.in $TEMP.out then OUTPUT=not-$OUTPUT print -u$stdout -n -r -- $'\t\tSAME OUTPUT INPUT' else print -u$stdout -n -r -- $'\t\tOUTPUT' $n - [[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO" fi print -u$stdout fi fi IO=$(cat $TEMP.err; print :) IO=${IO//$command\[*([0-9])\]:\ .\[*([0-9])\]:\ @(EXEC|PROG)\[*([0-9])\]:\ /} if [[ $IO == ?*$'\n:' ]] then IO=${IO%??} n= else IO=${IO%?} n=-n fi if [[ $IO != "$ERROR" || $n != "$ERROR_N" ]] then ERROR=$IO ERROR_N=$n if [[ $error ]] then print -u$stdout -n -r -- $'\t\tERROR' $n - [[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO" print -u$stdout fi fi case $output:$error in :) OUTPUT= OUTPUT_N= ERROR= ERROR_N= print -u$stdout -r -- $'\t\tIGNORE OUTPUT ERROR' ;; :1) OUTPUT= OUTPUT_N= print -u$stdout -r -- $'\t\tIGNORE OUTPUT' ;; 1:) ERROR= ERROR_N= print -u$stdout -r -- $'\t\tIGNORE ERROR' ;; esac if [[ $UMASK_DONE != $UMASK ]] then UMASK_DONE=$UMASK print -u$stdout -r -f $'\t\tUMASK %s\n' $UMASK fi if (( code != CODE )) then (( CODE=code )) if [[ $exitcode ]] then print -u$stdout -r -f $'\t\tEXIT %d\n' $CODE fi fi ;; shell) [[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "{ umask $UMASK; " if [[ $op == PROG ]] then print -u$stdout -r -f $'"'"$unit"$'"' else print -u$stdout -r -f $'"$@"' fi for ARG in "$@" do print -u$stdout -r -f " $QUOTE" -- "$ARG" done [[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "umask $UMASK_ORIG; } " if [[ ! $output ]] then print -u$stdout -r -f " >/dev/null" fi if [[ ! $error ]] then if [[ ! $output ]] then print -u$stdout -r -f " 2>&1" else print -u$stdout -r -f " 2>/dev/null" fi fi IO=$(cat) if [[ $IO ]] then print -u$stdout -r -- "<<'!TEST-INPUT!'" print -u$stdout -r -- "$IO" print -u$stdout -r -- !TEST-INPUT! else print -u$stdout fi if [[ $exitcode ]] then print -u$stdout -r -- $'CODE=$?\ncase $CODE in\n0) ;;\n*) echo exit status $CODE ;;\nesac' fi ;; esac } function DO { LINE print -r $'\t'DO "$@" } function EXEC { RUN EXEC "$@" } function DATA { typeset f p o f=$1 shift case $f in -) p=$TEMP.in ;; *) p=$WORK/$f ;; esac case $1 in '') cat ;; -) ;; *) print -r "$@" ;; esac > $p DATA[$f]=1 if (( $# == 1 )) && [[ $1 == -?* ]] then FORMAT[$f]=$1 else FORMAT[$f]= fi if [[ $f != $KEEP ]] then REMOVE[$f]=1 fi if [[ $STYLE == shell ]] then { print -r -f "cat > $QUOTE <<'!TEST-INPUT!'"$'\n' -- "$f" cat "$p" print -r -- !TEST-INPUT! } >&$stdout fi } function KEEP { typeset p for p do if [[ $KEEP ]] then KEEP=$KEEP'|' fi KEEP=$KEEP$p done } function DIAGNOSTICS { LINE case $STYLE in regress) print -u$stdout -r $'DIAGNOSTICS' ;; shell) DIAGNOSTICS=1 ;; esac } function EXPORT { typeset x n v LINE case $STYLE in regress) print -u$stdout -r -f $'EXPORT' ;; shell) print -u$stdout -r -f $'export' ;; esac for x do n=${x%%=*} v=${x#*=} export "$x" print -u$stdout -r -f " %s=$QUOTE" "$n" "$v" (( TEST )) && STATE.RESET["$n"]=1 done print -u$stdout } function PROG { RUN PROG "$@" } function WIDTH { WIDTH=${1:-80} eval QUOTE='"'$quote'"' } function IGNORESPACE { IGNORESPACE=-b LINE print -u$stdout -r IGNORESPACE } function UMASK # [ mask ] { [[ $UMASK_ORIG ]] || UMASK_ORIG=$(umask) UMASK=$1 [[ $UMASK ]] || UMASK=$UMASK_ORIG } trap 'CODE=$?; rm -rf $TEMP.* $WORK; exit $CODE' 0 1 2 3 15 typeset IGNORESPACE UMASK UMASK_ORIG UMASK_DONE UMASK_ORIG=$(umask) IFS=$IFS$'\n' print -u$stdout -r "# : : generated from $SCRIPT by $command : : #" case $STYLE in shell) cat <&2 <&2 exit 1 ;; *) break ;; esac shift done export COLUMNS=80 { ! ;; esac export COLUMNS=80 case $STYLE in shell) SINGLE='#' eval QUOTE='"'$quote'"' . $SCRIPT < /dev/null | sed -e $'s,\\\\n,\n,g' -e $'s,\\\\t,\t,g' -e $'s,\\$\',\',g' ;; *) eval QUOTE='"'$quote'"' : > $TEMP.INPUT > $TEMP.in eval "exec $stdin<$TEMP.INPUT" . $SCRIPT <&$stdin ;; esac case $STYLE in shell) cat < $PREFIX${UNIT[0]}.tmp 2>&1 < /dev/null case \$ACCEPT in 0) if grep ' $' $PREFIX${UNIT[0]}.tmp >/dev/null then mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.junk sed 's/ $//' < $PREFIX${UNIT[0]}.junk > $PREFIX${UNIT[0]}.tmp rm -f $PREFIX${UNIT[0]}.junk fi if cmp -s $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out then echo ${UNIT[0]} tests PASSED rm -f $PREFIX${UNIT[0]}.tmp else echo ${UNIT[0]} tests FAILED diff $IGNORESPACE $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out fi ;; *) mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out ;; esac ! ;; esac ksh-1.0.0-beta.2/src/cmd/INIT/mprobe.sh000066400000000000000000000030551415700074400172700ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : mam probe script opt= while : do case $1 in -d) opt=-d ;; -*) ;; *) break ;; esac shift done mamprobe $opt - "$1" ksh-1.0.0-beta.2/src/cmd/INIT/nsl.c000066400000000000000000000030421415700074400164040ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -lnsl */ extern void* gethostbyname(); int main() { return gethostbyname(0) == 0; } ksh-1.0.0-beta.2/src/cmd/INIT/p.c000066400000000000000000000030261415700074400160510ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for prototyping cc */ int main(int argc, char** argv) { return argc || argv; } ksh-1.0.0-beta.2/src/cmd/INIT/package.sh000066400000000000000000002424011415700074400173770ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2012 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## ### this sh script is POSIX compliant and compatible with shell bugs ### # KornShell 93u+m build system, main control script # # based on AST 'package' by Glenn Fowler # # simplified and rewritten by Martijn Dekker # ######################################################################## command=package # Escape from a non-POSIX shell min_posix='path=Bad && case $PATH in (Bad) exit 1;; esac && '\ 'PWD=Bad && cd -P -- / && case $PWD in (/) ;; (*) exit 1;; esac && '\ '! { ! case x in ( x ) : ${0##*/} || : $( : ) ;; esac; } && '\ 'trap "exit 0" 0 && exit 1' if (eval "$min_posix") 2>/dev/null then : good shell else "$SHELL" -c "$min_posix" 2>/dev/null && exec "$SHELL" -- "$0" ${1+"$@"} sh -c "$min_posix" 2>/dev/null && exec sh -- "$0" ${1+"$@"} DEFPATH=`getconf PATH` 2>/dev/null || DEFPATH=/usr/xpg4/bin:/bin:/usr/bin:/sbin:/usr/sbin PATH=$DEFPATH:$PATH export PATH sh -c "$min_posix" 2>/dev/null && exec sh -- "$0" ${1+"$@"} echo "$0: Can't escape from obsolete or broken shell. Run me with a POSIX shell." >&2 exit 128 fi readonly min_posix # use for checksh() # Set standards compliance mode (command set -o posix) 2>/dev/null && set -o posix # Sanitize 'cd' unset CDPATH # Make the package root the current working directory # This makes it possible to run '/my/path/package make' without cd'ing first # (for all its featuritis, the AT&T version never could manage this) case $0 in [0123456789+-]*) echo "dodgy \$0: $0" >&2 exit 128 ;; */*) me=$0 ;; *) me=$(command -v "$0") || exit 128 ;; esac me=$(dirname "$me") cd "$me" || exit unset -v me case $PWD in */arch/*/*/bin) cd .. ;; */arch/*/bin) cd ../../.. ;; */bin) cd .. ;; *) echo "this script must live in bin/" >&2 exit 1 ;; esac || exit # shell checks checksh() { "$1" -c "$min_posix" 2>/dev/null || return 1 } LC_ALL=C export LC_ALL TMPDIR=${TMPDIR:-/tmp} export TMPDIR src="cmd contrib etc lib" use="/usr/common /exp /usr/local /usr/add-on /usr/addon /usr/tools /usr /opt" usr="/home" lib="" # need /usr/local/lib /usr/local/shlib ccs="/usr/kvm /usr/ccs/bin" org="gnu GNU" makefiles="Mamfile" # ksh 93u+m no longer uses these: Nmakefile nmakefile Makefile makefile env="HOSTTYPE NPROC PACKAGEROOT INSTALLROOT PATH" package_use='=$HOSTTYPE=$PACKAGEROOT=$INSTALLROOT=$EXECROOT=$CC=' CROSS=0 MAKESKIP=${MAKESKIP:-"*[-.]*"} SED= TR= all_types='*.*|sun4' # all but sun4 match *.* case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in 0123) USAGE=$' [-? @(#)$Id: '$command$' (ksh 93u+m) 2021-12-15 $ ] [-author?Glenn Fowler ] [-author?Contributors to https://github.com/ksh93/ksh] [-copyright?(c) 1994-2012 AT&T Intellectual Property] [-copyright?(c) 2020-2021 Contributors to https://github.com/ksh93/ksh] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?'$command$' - build, test and install ksh 93u+m] [+DESCRIPTION?The \b'$command$'\b command is the main control script for building and installing KornShell 93u+m. It is a POSIX \bsh\b(1) script coded for maximal portability. A POSIX shell and C compiler installation are the only requirements. All package files are in the \b$PACKAGEROOT\b directory tree. Binary package files are in the \b$INSTALLROOT\b (\b$PACKAGEROOT/arch/\b\ahosttype\a) tree, where \ahosttpe\a=$(\bbin/package host type\b). See \bDETAILS\b for more information.] [+?Note that no environment variables need be set by the user; \b'$command$'\b determines the environment based on the current working directory. The \buse\b action starts a \bsh\b(1) with the environment initialized. \bCC\b, \bCCFLAGS\b, \bHOSTTYPE\b and \bSHELL\b may be set by explicit command argument assignments to override the defaults.] [+?The command arguments are composed of a sequence of words: zero or more \aqualifiers\a, one \aaction\a, and zero or more action-specific \aarguments\a, and zero or more \aname=value\a definitions. \boptget\b(3) documentation options such as \b--man\b, \b--html\b and \b--nroff\b are also supported. The default with no arguments is \bhost type\b.] [+?The qualifiers are:] { [+debug|environment?Show environment and actions but do not execute.] [+force?Force the action to override saved state.] [+never?Run make -N and show other actions.] [+only?Only operate on the specified packages.] [+quiet?Do not list captured action output.] [+show?Run make -n and show other actions.] [+verbose?Provide detailed action output.] [+DEBUG?Trace the package script actions in detail.] } [+?The actions are:] { [+clean | clobber?Delete the \barch/\b\aHOSTTYPE\a hierarchy; this deletes all generated files and directories for \aHOSTTYPE\a. The hierarchy can be rebuilt by \b'$command$' make\b.] [+export\b [ \avariable\a ...]]?List \aname\a=\avalue\a for \avariable\a, one per line. If the \bonly\b attribute is specified then only the variable values are listed. If no variables are specified then \b'$env$'\b are assumed.] [+help\b [ \aaction\a ]]?Display help text on the standard error (standard output for \aaction\a).] [+host\b [ \aattribute\a ... ]]?List architecture/implementation dependent host information on the standard output. \btype\b is listed if no attributes are specified. Information is listed on a single line in \aattribute\a order. The attributes are:] { [+canon \aname\a?An external host type name to be converted to \b'$command$'\b syntax.] [+cpu?The number of CPUs; 1 if the host is not a multiprocessor.] [+name?The host name.] [+rating?The CPU rating in pseudo mips; the value is useful useful only in comparisons with rating values of other hosts. Other than a vax rating (mercifully) fixed at 1, ratings can vary wildly but consistently from vendor mips ratings. \bcc\b(1) may be required to determine the rating.] [+type?The host type, usually in the form \avendor\a.\aarchitecture\a, with an optional trailing -\aversion\a. The main theme is that type names within a family of architectures are named in a similar, predictable style. OS point release information is avoided as much as possible, but vendor resistance to release incompatibilities has for the most part been futile.] } [+install\b To be reimplemented.] [+make\b [ \apackage\a ]] [ \aoption\a ... ]] [ \atarget\a ... ]]?Build and install. The default \atarget\a is \binstall\b, which makes and installs \apackage\a. If the standard output is a terminal then the output is also captured in \b$INSTALLROOT/lib/package/gen/make.out\b. The build is done in the \b$INSTALLROOT\b directory tree viewpathed on top of the \b$PACKAGEROOT\b directory tree. Leaf directory names matching the \b|\b-separated shell pattern \b$MAKESKIP\b are ignored. The \bview\b action is done before making. \aoption\a operands are passed to the underlying make command.] [+results\b [ \bfailed\b ]] [ \bpath\b ]] [ \bold\b ]] [\bmake\b | \btest\b | \bwrite\b ]]?List results and interesting messages captured by the most recent \bmake\b (default), \btest\b or \bwrite\b action. \bold\b specifies the previous results, if any (current and previous results are retained). \b$HOME/.pkgresults\b, if it exists, must contain an \begrep\b(1) expression of result lines to be ignored. \bfailed\b lists failures only and \bpath\b lists the results file path name only.] [+test\b [ \aargument\a ... ]]?Run the regression tests for \bksh\b. If the standard output is a terminal then the output is also captured in \b$INSTALLROOT/lib/package/gen/test.out\b. \bksh\b must be made before it can be tested. All \aargument\as following \atest\a are passed to \bbin/shtests\b. See \bbin/shtests --man\b for more information.] [+use\b [ \auid\a | \apackage\a | . [ 32 | 64 ]] | 32 | 64 | - ]] [ command ...]]?Run \acommand\a, or an interactive shell if \acommand\a is omitted, with the environment initialized for using the package (can you say \ashared\a \alibrary\a or \adll\a without cussing?) If \auid\a or \apackage\a or \a.\a is specified then it is used to determine a \b$PACKAGEROOT\b, possibly different from the current directory. For example, to try out bozo'\'$'s package: \bpackage use bozo\b. The \buse\b action may be run from any directory. If the file \b$INSTALLROOT/lib/package/profile\b is readable then it is sourced to initialize the environment. 32 or 64 implies \b$PACKAGEROOT\b of . and specifies the target architecture word size (which may be silently ignored).] [+view\b?Initialize the architecture specific viewpath hierarchy. The \bmake\b action implicitly calls this action.] } [+DETAILS?The package directory hierarchy is rooted at \b$PACKAGEROOT\b. All source and binaries reside under this tree. A two level viewpath is used to separate source and binaries. The top view is architecture specific, the bottom view is shared source. All building is done in the architecture specific view; no source view files are intentionally changed. This means that many different binary architectures can be made from a single copy of the source.] [+?Independent \b$PACKAGEROOT\b hierarchies can be combined by appending \b$INSTALLROOT:$PACKAGEROOT\b pairs to \bVPATH\b. The \bVPATH\b viewing order is from left to right.] [+?\b$HOSTYPE\b names the current binary architecture and is determined by the output of \b'$command$'\b (no arguments). The \b$HOSTTYPE\b naming scheme is used to separate incompatible executable and object formats. All architecture specific binaries are placed under \b$INSTALLROOT\b (\b$PACKAGEROOT/arch/$HOSTTYPE\b). There are a few places that match against \b$HOSTTYPE\b when making binaries; these are limited to makefile compiler workarounds, e.g., if \b$HOSTTYPE\b matches \bhp.*\b then turn off the optimizer for these objects. All other architecture dependent logic is handled either by the \bAST\b \biffe\b(1) command or by component specific configure scripts. Explicit \b$HOSTYPE\b values matching *,*cc*[,-*,...]] optionally set the default \bCC\b and \bCCFLAGS\b. This is handy for build farms that support different compilers on the same architecture.] [+?Each component contains a \bMAM\b (make abstract machine) file (\bMamfile\b). A Mamfile contains a portable makefile description written in a simple dependency tree language using indented \bmake\b...\bdone\b blocks.] [+?Most component C source is prototyped. If \b$CC\b (default value \bcc\b) is not a prototyping C compiler then \b'$command$' make\b runs \bproto\b(1) on portions of the \b$PACKAGEROOT/src\b tree and places the converted output files in the \b$PACKAGEROOT/proto/src\b tree. Converted files are then viewpathed over the original source. \bproto\b(1) converts an ANSI C subset to code that is compatible with K&R, ANSI, and C++ dialects.] [+?All scripts and commands under \b$PACKAGEROOT\b use \b$PATH\b relative pathnames (via the \bAST\b \bpathpath\b(3) function); there are no embedded absolute pathnames. This means that binaries generated under \b$PACKAGEROOT\b may be copied to a different root; users need only change their \b$PATH\b variable to reference the new installation root \bbin\b directory. \b'$command$' install\b installs binary packages in a new \b$INSTALLROOT\b.] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ] [+SEE ALSO?\bautoconfig\b(1), \bcksum\b(1), \bexecrate\b(1), \bexpmake\b(1), \bgzip\b(1), \bmake\b(1), \bmamake\b(1), \bpax\b(1), \bpkgadd\b(1), \bpkgmk\b(1), \bproto\b(1), \bratz\b(1), \brpm\b(1), \bsh\b(1), \btar\b(1), \boptget\b(3)] ' case $* in help) set -- --man ;; esac while getopts -a "$command" "$USAGE" OPT do : done shift $((OPTIND-1)) ;; esac # check the args case $AR in '') AR=ar ;; esac case $CC in '') CC=cc ;; esac case $LD in '') LD=ld ;; esac case $NM in '') NM=nm ;; esac action= bit= exec= force=0 global= hi= ifs=${IFS-' '} lo= make= makeflags='-K' nl=" " noexec= only=0 output= quiet=0 show=: tab=" " verbose=0 AUTHORIZE= DEBUG= PROTOROOT=- SHELLMAGIC=- unset FIGNORE BINDIR DLLDIR ETCDIR FUNDIR INCLUDEDIR LIBDIR LOCALEDIR MANDIR SHAREDIR 2>/dev/null || true while : do case $# in 0) set host type ;; esac case $1 in clean|clobber|export|host|install|make|remove|results|test|use|view) action=$1 shift break ;; debug|environment) exec=echo make=echo show=echo ;; force) force=1 ;; never) exec=echo noexec=-N ;; only) only=1 ;; quiet) quiet=1 ;; show) exec=echo noexec=-n ;; verbose)verbose=1 ;; DEBUG) DEBUG=1 PS4='+$LINENO:$SECONDS+ ' set -x ;; help|HELP|html|man|--[?m]*) case $1 in help) code=0 case $2 in '') exec 1>&2 ;; esac ;; html) code=0 html=1 echo "$command help

$command help

"
			;;
		*)	code=2
			exec 1>&2
			;;
		esac
		echo 'NAME
  package - build, test and install ksh 93u+m

SYNOPSIS
  package [ options ] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ]

DESCRIPTION
  The package command is the main control script for building and installing
  KornShell 93u+m. It is a POSIX sh(1) script coded for maximal portability. A
  POSIX shell and C compiler installation are the only requirements. All
  package files are in the $PACKAGEROOT directory tree. Binary package files
  are in the $INSTALLROOT ($PACKAGEROOT/arch/hosttype) tree, where
  hosttpe=$(bin/package host type). See DETAILS for more information.

  Note that no environment variables need be set by the user; package
  determines the environment based on the current working directory. The use
  action starts a sh(1) with the environment initialized. CC, CCFLAGS, HOSTTYPE
  and SHELL may be set by explicit command argument assignments to override the
  defaults.

  The command arguments are composed of a sequence of words: zero or more
  qualifiers, one action, and zero or more action-specific arguments, and zero
  or more name=value definitions. optget(3) documentation options such as
  --man, --html and --nroff are also supported. The default with no arguments
  is host type.

  The qualifiers are:
    debug|environment
          Show environment and actions but do not execute.
    force Force the action to override saved state.
    never Run make -N and show other actions.
    only  Only operate on the specified packages.
    quiet Do not list captured action output.
    show  Run make -n and show other actions.
    verbose
          Provide detailed action output.
    DEBUG Trace the package script actions in detail.

  The actions are:
    clean | clobber
          Delete the arch/HOSTTYPE hierarchy; this deletes all generated files
          and directories for HOSTTYPE. The hierarchy can be rebuilt by package
          make.
    export [ variable ...]
          List name=value for variable, one per line. If the only attribute is
          specified then only the variable values are listed. If no variables
          are specified then HOSTTYPE NPROC PACKAGEROOT INSTALLROOT PATH are
          assumed.
    help [ action ]
          Display help text on the standard error (standard output for action).
    host [ attribute ... ]
          List architecture/implementation dependent host information on the
          standard output. type is listed if no attributes are specified.
          Information is listed on a single line in attribute order. The
          attributes are:
            canon name
                  An external host type name to be converted to package syntax.
            cpu   The number of CPUs; 1 if the host is not a multiprocessor.
            name  The host name.
            rating
                  The CPU rating in pseudo mips; the value is useful useful
                  only in comparisons with rating values of other hosts. Other
                  than a vax rating (mercifully) fixed at 1, ratings can vary
                  wildly but consistently from vendor mips ratings. cc(1) may
                  be required to determine the rating.
            type  The host type, usually in the form vendor.architecture, with
                  an optional trailing -version. The main theme is that type
                  names within a family of architectures are named in a
                  similar, predictable style. OS point release information is
                  avoided as much as possible, but vendor resistance to release
                  incompatibilities has for the most part been futile.
    install To be reimplemented.
    make [ package ] [ option ... ] [ target ... ]
          Build and install. The default target is install, which makes and
          installs package. If the standard output is a terminal then the
          output is also captured in $INSTALLROOT/lib/package/gen/make.out. The
          build is done in the $INSTALLROOT directory tree viewpathed on top of
          the $PACKAGEROOT directory tree. Leaf directory names matching the
          |-separated shell pattern $MAKESKIP are ignored. The view action is
          done before making. option operands are passed to the underlying make
          command.
    results [ failed ] [ path ] [ old ] [make | test | write ]
          List results and interesting messages captured by the most recent
          make (default), test or write action. old specifies the previous
          results, if any (current and previous results are retained).
          $HOME/.pkgresults, if it exists, must contain an egrep(1) expression
          of result lines to be ignored. failed lists failures only and path
          lists the results file path name only.
    test [ argument ... ]
          Run the regression tests for ksh. If the standard output is a
          terminal then the output is also captured in
          $INSTALLROOT/lib/package/gen/test.out. ksh must be made before it can
          be tested. All arguments following test are passed to bin/shtests.
          See bin/shtests --man for more information.
    use [ uid | package | . [ 32 | 64 ] | 32 | 64 | - ] [ command ...]
          Run command, or an interactive shell if command is omitted, with the
          environment initialized for using the package (can you say shared
          library or dll without cussing?) If uid or package or . is specified
          then it is used to determine a $PACKAGEROOT, possibly different from
          the current directory. For example, to try out bozo'\''s package:
          package use bozo. The use action may be run from any directory. If
          the file $INSTALLROOT/lib/package/profile is readable then it is
          sourced to initialize the environment. 32 or 64 implies $PACKAGEROOT
          of . and specifies the target architecture word size (which may be
          silently ignored).
    view  Initialize the architecture specific viewpath hierarchy. The make
          action implicitly calls this action.

DETAILS
  The package directory hierarchy is rooted at $PACKAGEROOT. All source and
  binaries reside under this tree. A two level viewpath is used to separate
  source and binaries. The top view is architecture specific, the bottom view
  is shared source. All building is done in the architecture specific view; no
  source view files are intentionally changed. This means that many different
  binary architectures can be made from a single copy of the source.

  Independent $PACKAGEROOT hierarchies can be combined by appending
  $INSTALLROOT:$PACKAGEROOT pairs to VPATH. The VPATH viewing order is from
  left to right.

  $HOSTYPE names the current binary architecture and is determined by the
  output of package (no arguments). The $HOSTTYPE naming scheme is used to
  separate incompatible executable and object formats. All architecture
  specific binaries are placed under $INSTALLROOT
  ($PACKAGEROOT/arch/$HOSTTYPE). There are a few places that match against
  $HOSTTYPE when making binaries; these are limited to makefile compiler
  workarounds, e.g., if $HOSTTYPE matches hp.* then turn off the optimizer for
  these objects. All other architecture dependent logic is handled either by
  the AST iffe(1) command or by component specific configure scripts. Explicit
  $HOSTYPE values matching *,*cc*[,-*,...] optionally set the default CC and
  CCFLAGS. This is handy for build farms that support different compilers on
  the same architecture.

  Each component contains a MAM (make abstract machine) file (Mamfile). A
  Mamfile contains a portable makefile description written in a simple
  dependency tree language using indented make...done blocks.

  Most component C source is prototyped. If $CC (default value cc) is not a
  prototyping C compiler then package make runs proto(1) on portions of the
  $PACKAGEROOT/src tree and places the converted output files in the
  $PACKAGEROOT/proto/src tree. Converted files are then viewpathed over the
  original source. proto(1) converts an ANSI C subset to code that is
  compatible with K&R, ANSI, and C++ dialects.

  All scripts and commands under $PACKAGEROOT use $PATH relative pathnames (via
  the AST pathpath(3) function); there are no embedded absolute pathnames. This
  means that binaries generated under $PACKAGEROOT may be copied to a different
  root; users need only change their $PATH variable to reference the new
  installation root bin directory. package install installs binary packages in
  a new $INSTALLROOT.

SEE ALSO
  autoconfig(1), cksum(1), execrate(1), expmake(1), gzip(1), make(1),
  mamake(1), pax(1), pkgadd(1), pkgmk(1), proto(1), ratz(1), rpm(1), sh(1),
  tar(1), optget(3)

IMPLEMENTATION
  version         package (ksh 93u+m) 2021-12-15
  author          Glenn Fowler 
  author          Contributors to https://github.com/ksh93/ksh
  copyright       (c) 1994-2012 AT&T Intellectual Property
  copyright       (c) 2020-2021 Contributors to https://github.com/ksh93/ksh
  license         http://www.eclipse.org/org/documents/epl-v10.html'
		case $1 in
		html)	echo "
" ;; esac exit $code ;; *=*) set DEFAULT host type "$@" ;; *) # simulate AST getopt(3) usage output echo "Usage: $command [ options ] [ qualifier ... ] [ action ] [ arg ... ] [ n=v ... ]" >&2 echo " Help: $command [ --help | --man ] 2>&1" >&2 exit 2 ;; esac global="$global $1" shift done # gather HOSTTYPE *,* options # ,*cc*,-*,... set CC and CCFLAGS hostopts() { _ifs_=$IFS IFS=, set '' $HOSTTYPE IFS=$_ifs_ shift while : do case $# in 0|1) break ;; esac shift case $1 in *cc*) CC=$1 while : do case $# in 0|1) break ;; esac case $2 in -*) case $assign_CCFLAGS in ?*) assign_CCFLAGS="$assign_CCFLAGS " ;; esac assign_CCFLAGS="$assign_CCFLAGS$2" shift ;; *) break ;; esac done ;; esac done } # collect command line targets and definitions case $_PACKAGE_HOSTTYPE_ in ?*) HOSTTYPE=$_PACKAGE_HOSTTYPE_ KEEP_HOSTTYPE=1 ;; *) KEEP_HOSTTYPE=0 ;; esac KEEP_PACKAGEROOT=0 KEEP_SHELL=0 USER_VPATH= args= assign= assign_CCFLAGS= for i do case $i in *:*=*) args="$args $i" continue ;; *=*) eval $(echo ' ' "$i" | sed 's,^[ ]*\([^=]*\)=\(.*\),n=\1 v='\''\2'\'',') ;; esac case $i in AR=*|LD=*|NM=*) assign="$assign $n='$v'" eval $n='$'v ;; CC=*) eval $n='$'v ;; CCFLAGS=*) eval $n='$'v assign_CCFLAGS="CCFLAGS=\"\$CCFLAGS\"" ;; HOSTTYPE=*) eval $n='$'v case $HOSTTYPE in ?*) KEEP_HOSTTYPE=1 ;; esac ;; PACKAGEROOT=*) eval $n='$'v case $PACKAGEROOT in ?*) KEEP_PACKAGEROOT=1 ;; esac ;; SHELL=*)eval $n='$'v case $SHELL in ?*) KEEP_SHELL=1 ;; esac ;; VPATH=*)eval USER_$n='$'v ;; 'debug=1') makeflags="$makeflags --debug-symbols" ;; 'strip=1') makeflags="$makeflags --strip-symbols" ;; *=*) assign="$assign $n='$v'" ;; *) args="$args $i" ;; esac done case $HOSTTYPE in *,*) hostopts $HOSTTYPE ;; esac case $assign_CCFLAGS in ?*) assign="$assign $assign_CCFLAGS" esac case $CC in ''|cc) ;; *) export CC ;; esac # Add build type flags via KSH_RELFLAGS, which is used in src/cmd/ksh93/Mamfile. # (Avoid using CCFLAGS; setting it would overwrite autodetected optimization flags.) ksh_relflags= case $(git branch 2>/dev/null) in '' | *\*\ [0-9]*.[0-9]*) # If we're not on a git branch (tarball) or on a branch that starts # with a number (release branch), then compile as a release version ksh_relflags="${ksh_relflags:+$ksh_relflags }-D_AST_ksh_release" ;; *) # Otherwise, add 8-character git commit hash if available, and if the working dir is clean git_commit=$(git status >/dev/null 2>&1 && git diff-index --quiet HEAD && git rev-parse --short=8 HEAD) case $git_commit in ????????) ksh_relflags="${ksh_relflags:+$ksh_relflags }-D_AST_git_commit=\\\"$git_commit\\\"" ;; esac unset git_commit ;; esac case $ksh_relflags in ?*) # add the extra flags as an argument to mamake assign="${assign:+$assign }KSH_RELFLAGS=\"\$ksh_relflags\"" ;; esac # Add ksh compile-options via KSH_SHOPTFLAGS. SHOPT() { case $1 in *=?*) ksh_shoptflags="${ksh_shoptflags:+$ksh_shoptflags }-DSHOPT_$1" ;; esac } ksh_shoptflags= shopt_sh='src/cmd/ksh93/SHOPT.sh' # this script calls SHOPT() to set options if test -f "$shopt_sh" then . "$shopt_sh" else echo "WARNING: $shopt_sh is missing" >&2 fi case $ksh_shoptflags in ?*) # add the extra flags as an argument to mamake assign="${assign:+$assign }KSH_SHOPTFLAGS=\"\$ksh_shoptflags\"" ;; esac # grab action specific args case $action in use) case $1 in .|32|64)case $1 in 32|64) bit=$1 ;; esac shift # HOSTTYPE specific setup case $HOSTTYPE in win32.*)sys=uwin wow=$(uname -i) case $bit in 32) case $HOSTTYPE in *-64) HOSTTYPE=${HOSTTYPE%-64} ;; esac ;; 64) case $HOSTTYPE in *-64) ;; *) HOSTTYPE=$HOSTTYPE-64 ;; esac case $wow in */32) echo $command: cannot build $bit-bit on $wow $sys >&2; exit 2 ;; esac ;; esac case $bit in '') PS1="($sys) " ;; *) PS1="($sys-$bit) " ;; esac $exec umask 002 $exec unset MAKESKIP $exec export P=$PWD $exec export A=$P/arch/$HOSTTYPE $exec export CDPATH=:..:$A/src/cmd:$A/src/lib:$A/src/uwin:$P/lib/package $exec export INSTALLROOT=$A $exec export PACKAGEROOT=$P $exec export PATH=$A/bin:$P/bin:$PATH $exec export PS1="$PS1" $exec export VPATH=$A:$P $exec export nativepp=/usr/lib if test '' != "$INSTALLROOT" -a -d $INSTALLROOT/include/ast then $exec export PACKAGE_ast=$INSTALLROOT elif test -d ${PWD%/*}/ast/arch/$HOSTTYPE then $exec export PACKAGE_ast=${PWD%/*}/ast/arch/$HOSTTYPE fi # run the command case $# in 0) case $show in ':') $exec exec $SHELL ;; esac ;; *) $exec exec $SHELL -c "$@" ;; esac exit ;; esac PACKAGEROOT=$PWD $show export PACKAGEROOT esac ;; esac # true if arg is a valid PACKAGEROOT packageroot() # dir { test -d $1/lib/$command -o -x $1/bin/$command } # true if arg is executable executable() # [!] command { case $1 in '!') test ! -x "$2" -a ! -x "$2.exe"; return ;; *) test -x "$1" -o -x "$1.exe"; return ;; esac } # initialize SHELLMAGIC # tangible proof of Cygwin's disdain for Unix (well, this and execrate) shellmagic() { case $SHELLMAGIC in '') ;; -) if test -f /emx/bin/sh.exe then SHELLMAGIC='#!/emx/bin/sh.exe'$nl elif test -f /bin/env.exe then SHELLMAGIC='#!/bin/env sh'$nl else SHELLMAGIC= fi ;; esac } # true if arg is executable command on $PATH onpath() # command { _onpath_b=$1 case $_onpath_b in /*) if executable $_onpath_b then _onpath_=$_onpath_b return 0 fi return 1 ;; esac IFS=':' set '' $PATH IFS=$ifs shift for _onpath_d do case $_onpath_d in '') _onpath_d=. ;; esac if executable "$_onpath_d/$_onpath_b" then _onpath_=$_onpath_d/$_onpath_b return 0 fi done return 1 } # determine local host attributes hostinfo() # attribute ... { case $DEBUG in 1) set -x ;; esac map= something= path=$PATH for i in $ccs do PATH=$PATH:$i done for i in $use do for j in $org do PATH=$PATH:$i/$j/bin done PATH=$PATH:$i/bin done # LD_LIBRARY_PATH may be out of sync with PATH here case $SED in '') SED=sed $SED 1d < /dev/null > /dev/null 2>&1 || for dir in /bin /usr/bin do if test -x $dir/$SED then SED=$dir/$SED break fi done TR=tr $TR < /dev/null > /dev/null 2>&1 || for dir in /bin /usr/bin do if test -x $dir/$TR then TR=$dir/$TR break fi done ;; esac case $PACKAGE_PATH in ?*) for i in $(echo "$PACKAGE_PATH" | "$SED" 's,:, ,g') do PATH=$PATH:$i/bin done ;; esac # validate the args canon= cc=$CC for info do case $canon in -) canon=$info ;; *) case $info in */*|*[cC][cC]) cc=$info ;; canon) canon=- something=1 ;; cpu|name|rating|type) something=1 ;; *) echo "$command: $action: $info: unknown attribute" >&2 exit 1 ;; esac ;; esac done case $canon in -) echo "$command: $action: canon: host type name expected" >&2 exit 1 ;; esac case $something in "") set "$@" type ;; esac case $DEBUG in '') exec 9>&2 exec 2>/dev/null ;; esac # compute the info _hostinfo_= for info do case $info in cpu) case $NPROC in [123456789]*) _hostinfo_="$_hostinfo_ $NPROC" continue ;; esac cpu=$(sysctl -n hw.ncpu) case $cpu in [123456789]*) _hostinfo_="$_hostinfo_ $cpu" continue ;; esac cpu=$(grep -ic '^processor[ ][ ]*:[ ]*[0123456789]' /proc/cpuinfo) case $cpu in [123456789]*) _hostinfo_="$_hostinfo_ $cpu" continue ;; esac cpu=1 # exact match set \ hinv '^Processor [0123456789]' \ psrinfo 'on-line' \ 'cat /reg/LOCAL_MACHINE/Hardware/Description/System/CentralProcessor' '.' \ 'cat /proc/registry/HKEY_LOCAL_MACHINE/Hardware/Description/System/CentralProcessor' '.' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | grep -c "$2") case $i in [123456789]*) cpu=$i break ;; esac shift;shift done case $cpu in 0|1) set \ /bin/mpstat while : do case $# in 0) break ;; esac if executable $1 then case $($1 | grep -ic '^cpu ') in 1) cpu=$($1 | grep -ic '^ *[0123456789][0123456789]* ') break ;; esac fi shift done ;; esac case $cpu in 0|1) # token match set \ /usr/kvm/mpstat 'cpu[0123456789]' \ /usr/etc/cpustatus 'enable' \ /usr/alliant/showsched 'CE' \ 'ls /config/hw/system/cpu' 'cpu' \ prtconf 'cpu-unit' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | $TR ' ' ' ' | grep -c "^$2") case $i in [123456789]*) cpu=$i break ;; esac shift;shift done ;; esac case $cpu in 0|1) # special match set \ \ hinv \ '/^[0123456789][0123456789]* .* Processors*$/' \ '/[ ].*//' \ \ /usr/bin/hostinfo \ '/^[0123456789][0123456789]* .* physically available\.*$/' \ '/[ ].*//' \ while : do case $# in 0) break ;; esac i=$($1 2>/dev/null | $SED -e "${2}!d" -e "s${3}") case $i in [123456789]*) cpu=$i break ;; esac shift;shift;shift done ;; esac case $cpu in 0|1) cpu=$( cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.c < #include int main() { printf("%d\n", pthread_num_processors_np()); return 0; } ! for o in -lpthread '' do if $CC $o -O -o $tmp.exe $tmp.c $o >/dev/null 2>&1 || gcc $o -O -o $tmp.exe $tmp.c $o >/dev/null 2>&1 then ./$tmp.exe break fi done ) case $cpu in [0123456789]*) ;; *) cpu=1 ;; esac ;; esac _hostinfo_="$_hostinfo_ $cpu" ;; name) _name_=$(hostname || uname -n || cat /etc/whoami || echo local) _hostinfo_="$_hostinfo_ $_name_" ;; rating) for rating in $(grep -i ^bogomips /proc/cpuinfo 2>/dev/null | $SED -e 's,.*:[ ]*,,' -e 's,\(...*\)\..*,\1,' -e 's,\(\..\).*,\1,') do case $rating in [0123456789]*) break ;; esac done case $rating in [0123456789]*) ;; *) cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.c < #include #if TD || TZ #include #else extern time_t time(); #endif int main() { register unsigned long i; register unsigned long j; register unsigned long k; unsigned long l; unsigned long m; unsigned long t; int x; #if TD || TZ struct timeval b; struct timeval e; #if TZ struct timezone z; #endif #endif l = 500; m = 890; x = 0; for (;;) { #if TD || TZ #if TZ gettimeofday(&b, &z); #else gettimeofday(&b); #endif #else t = (unsigned long)time((time_t*)0); #endif k = 0; for (i = 0; i < l; i++) for (j = 0; j < 50000; j++) k += j; #if TD || TZ #if TZ gettimeofday(&e, &z); #else gettimeofday(&e); #endif t = (e.tv_sec - b.tv_sec) * 1000 + (e.tv_usec - b.tv_usec) / 1000; if (!x++ && t < 1000) { t = 10000 / t; l = (l * t) / 10; continue; } #else t = ((unsigned long)time((time_t*)0) - t) * 1000; if (!x++ && t < 20000) { t = 200000l / t; l = (l * t) / 10; continue; } #endif #if PR printf("[ k=%lu l=%lu m=%lu t=%lu ] ", k, l, m, t); #endif if (t == 0) t = 1; break; } printf("%lu\n", ((l * m) / 10) / t); return k == 0; } ! rating= for o in -DTZ -DTD '' do if $CC $o -O -o $tmp.exe $tmp.c >/dev/null 2>&1 || gcc $o -O -o $tmp.exe $tmp.c >/dev/null 2>&1 then rating=$(./$tmp.exe) break fi done case $rating in [0123456789]*) ;; *) rating=1 ;; esac ;; esac _hostinfo_="$_hostinfo_ $rating" ;; type|canon) case $CROSS:$canon in 0:) case $cc in cc) case $KEEP_HOSTTYPE:$HOSTTYPE in 0:?*) if test -d ${PACKAGEROOT:-.}/arch/$HOSTTYPE then KEEP_HOSTTYPE=1 fi ;; esac ;; esac case $KEEP_HOSTTYPE in 1) _hostinfo_="$_hostinfo_ $HOSTTYPE" continue ;; esac ;; esac case $cc in /*) a=$($cc -dumpmachine $CCFLAGS 2>/dev/null) case $a in '') case $CCFLAGS in ?*) a=$($cc -dumpmachine 2>/dev/null) ;; esac ;; esac case $a in ''|*' '*|*/*:*) ;; *.*-*) _hostinfo_="$_hostinfo_ $a" continue ;; *-*-*) case $canon in '') canon=$a ;; esac ;; *) _hostinfo_="$_hostinfo_ $a" continue ;; esac ;; esac IFS=: set /$IFS$PATH IFS=$ifs shift f=../lib/hostinfo/typemap for i do case $i in "") i=. ;; esac case $canon in '') case $cc in /*|cc) ;; *) if executable $i/$cc then a=$($i/$cc -dumpmachine $CCFLAGS 2>/dev/null) case $a in '') case $CCFLAGS in ?*) a=$($cc -dumpmachine 2>/dev/null) ;; esac ;; esac case $a in ''|*' '*|*/*:*) ;; *-*) canon=$a ;; *) _hostinfo_="$_hostinfo_ $a" continue 2 ;; esac fi ;; esac ;; esac if test -f "$i/$f" then map="$(grep -v '^#' $i/$f) $map" fi done # inconsistent -dumpmachine filtered here case -${canon}- in --|*-powerpc-*) h=$(hostname || uname -n || cat /etc/whoami) case $h in '') h=local ;; esac a=$(arch || uname -m || att uname -m || uname -s || att uname -s) case $a in *[\ \ ]*) a=$(echo $a | $SED "s/[ ]/-/g") ;; esac case $a in '') a=unknown ;; esac m=$(mach || machine || uname -p || att uname -p) case $m in *[\ \ ]*) m=$(echo $m | $SED "s/[ ]/-/g") ;; esac case $m in '') m=unknown ;; esac x=$(uname -a || att uname -a) case $x in '') x="unknown $host unknown unknown unknown unknown unknown" ;; esac set "" $h $a $m $x expected=$1 host=$2 arch=$3 mach=$4 os=$5 sys=$6 rel=$7 ver=$8 ;; *) case $canon in *-*) IFS=- set "" $canon shift IFS=$ifs case $# in 2) host= mach= arch=$1 os=$2 sys= rel= ;; *) host= mach=$2 arch=$1 os=$3 sys= rel= ;; esac case $os in [abcdefghijklmnopqrstuvwxyz]*[0123456789]) eval $(echo $os | $SED -e 's/^\([^0123456789.]*\)\.*\(.*\)/os=\1 rel=\2/') ;; esac ;; *) arch=$canon mach= os= sys= rel= ;; esac ;; esac type=unknown case $host in *.*) host=$(echo $host | $SED -e 's/\..*//') ;; esac case $mach in unknown) mach= ;; [Rr][0123][0123456789][0123456789][0123456789]) mach=mips1 ;; [Rr][4][0123456789][0123456789][0123456789]) mach=mips2 ;; [Rr][56789][0123456789][0123456789][0123456789]|[Rr][123456789][0123456789][0123456789][0123456789][0123456789]) mach=mips4 ;; pc) arch=i386 mach= ;; [Pp][Oo][Ww][Ee][Rr][Pp][Cc]) arch=ppc mach= ;; *) case $arch in 34[0123456789][0123456789]) os=ncr arch=i386 ;; esac ;; esac case $canon in '') set \ \ /NextDeveloper -d next - \ /config/hw/system/cpu -d tandem mach \ while : do case $# in 0) break ;; esac if test $2 $1 then os=$3 case $4 in arch) mach=$arch ;; mach) arch=$mach ;; esac break fi shift;shift;shift;shift done ;; esac case $os in AIX*|aix*) type=ibm.risc ;; HP-UX) case $arch in 9000/[78]*) type=hp.pa ;; */*) type=hp.$(echo $arch | $SED 's,/,_,g') ;; *) type=hp.$arch ;; esac ;; [Ii][Rr][Ii][Xx]*) set xx $(hinv | $SED -e '/^CPU:/!d' -e 's/CPU:[ ]*\([^ ]*\)[ ]*\([^ ]*\).*/\1 \2/' -e q | $TR ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) shift type=$1 n= case $2 in r[0123][0123456789][0123456789][0123456789]) n=1 ;; r[4][0123][0123456789][0123456789]) n=2 ;; r[4][456789][0123456789][0123456789]|r[5][0123456789][0123456789][0123456789]) n=3 ;; r[6789][0123456789][0123456789][0123456789]|r[123456789][0123456789][0123456789][0123456789][0123456789]) n=4 ;; esac case $rel in [01234].*|5.[012]|5.[012].*) case $n in 1) ;; *) n=2 ;; esac ;; 5.*) case $n in 2) n=3 ;; esac ;; esac if executable $cc then a=$cc else IFS=: set /$IFS$PATH IFS=$ifs shift for i do a=$i/$cc if executable $a then break fi done fi split=' ' a=$(strings $a < /dev/null | $SED -e 's/[^abcdefghijklmnopqrstuvwxyz0123456789]/ /g' -e 's/[ ][ ]*/\'"$split"'/g' | $SED -e "/^${type}[0123456789]$/!d" -e "s/^${type}//" -e q) case $a in [0123456789]) n=$a ;; esac case $n in 4) a=$($cc -${type}3 2>&1) case $a in *unknown*|*install*|*conflict*) ;; *) n=3 ;; esac ;; esac a=$($cc -show F0oB@r.c 2>&1) case $n:$a in [!2]:*mips2*) n=2 ;; [!23]:*mips3*) n=3 ;; [!234]:*mips4*) n=4 ;; esac case $n:$a in [!2]:*[Oo]32*) abi=-o32 ;; [!3]:*[Nn]32*) abi=-n32 ;; esac mach=${type}$n type=sgi.$mach ;; OSx*|SMP*|pyramid) type=pyr ;; OS/390) type=mvs.390 ;; [Ss][Cc][Oo]*) type=sco ;; [Ss]ol*) v=$(echo $rel | $SED -e 's/^[25]\.//' -e 's/\.[^.]*$//') case $v in [6789]|[1-9][0-9]) ;; *) v= ;; esac case $arch in '') case $mach in '') arch=sun4 ;; *) arch=$mach ;; esac ;; esac case $arch in sparc) arch=sun4 ;; esac type=sol$v.$arch ;; [Ss]un*)type=$(echo $arch | $SED -e 's/\(sun.\).*/\1/') case $type in sparc) type=sun4 ;; esac case $rel in [01234]*) ;; '') case $os in *[Oo][Ss]) ;; *) type=sol.$type ;; esac ;; *) case $type in '') case $mach in sparc*) type=sun4 ;; *) type=$mach ;; esac ;; esac v=$(echo $rel | $SED -e 's/^[25]\.//' -e 's/\.[^.]*$//') case $v in [6789]|[1-9][0-9]) ;; *) v= ;; esac type=sol$v.$type ;; esac case $type in sun*|*.*) ;; *) type=sun.$type ;; esac ;; [Uu][Nn][Ii][Xx]_[Ss][Vv]) type=unixware ;; UTS*|uts*) if test -x /bin/u370 -o -x /bin/u390 then type=uts.390 else case $arch in '') arch=$mach ;; esac type=uts.$arch fi ;; $host) type=$arch case $type in *.*|*[0123456789]*86|*68*) ;; *) case $mach in *[0123456789]*86|*68*|mips) type=$type.$mach ;; esac ;; esac ;; unknown) case $arch in ?*) case $arch in sun*) mach= ;; esac type=$arch case $mach in ?*) type=$type.$mach ;; esac ;; esac ;; *) case $ver in FTX*|ftx*) case $mach in *[0123456789][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*) mach=$(echo $mach | $SED -e 's/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*$//') ;; esac type=stratus.$mach ;; *) case $arch in [Oo][Ss][-/.]2) type=os2 arch=$rel ;; *) type=$(echo $os | $SED -e 's/[0123456789].*//' -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789.].*//') ;; esac case $type in [Cc][Yy][Gg][Ww][Ii][Nn]_*) type=cygwin ;; [Uu][Ww][Ii][Nn]*|[Ww]indows_[0123456789][0123456789]|[Ww]indows_[Nn][Tt]) type=win32 arch=$(echo $arch | $SED -e 's/_[^_]*$//') ;; esac case $arch in '') case $mach in ?*) type=$type.$mach ;; esac ;; *) type=$type.$arch ;; esac ;; esac esac case $type in [0123456789]*) case $mach in ?*) type=$mach ;; esac case $type in */MC) type=ncr.$type ;; esac ;; *.*) ;; *[0123456789]*86|*68*) case $rel in [34].[0123456789]*) type=att.$type ;; esac ;; [abcdefghijklmnopqrstuvwxyz]*[0123456789]) ;; [abcdefghijklmnopqrstuvwxyz]*) case $mach in $type) case $ver in Fault*|fault*|FAULT*) type=ft.$type ;; esac ;; ?*) case $arch in '') type=$type.$mach ;; *) type=$type.$arch ;; esac ;; esac ;; esac case $type in *[-_]32|*[-_]64|*[-_]128) bits=$(echo $type | $SED 's,.*[-_],,') type=$(echo $type | $SED 's,[-_][0-9]*$,,') ;; *) bits= ;; esac type=$(echo $type | $SED -e 's%[-+/].*%%' | $TR ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) case $type in *.*) lhs=$(echo $type | $SED -e 's/\..*//') rhs=$(echo $type | $SED -e 's/.*\.//') case $rhs in [x0123456789]*86) rhs=i$rhs ;; 68*) rhs=m$rhs ;; esac case $rhs in i[x23456789]86|i?[x23456789]86|*86pc) rhs=i386 ;; powerpc) rhs=ppc ;; s[0123456789]*[0123456789]x) rhs=$(echo $rhs | $SED -e 's/x$/-64/') ;; esac case $rhs in arm[abcdefghijklmnopqrstuvwxyz_][0123456789]*) rhs=arm ;; hppa) rhs=pa ;; esac case $lhs in ?*coff|?*dwarf|?*elf) case $lhs in ?*coff) x=coff ;; ?*dwarf)x=coff ;; ?*elf) x=elf ;; esac lhs=$(echo ${lhs}XXX | $SED -e "s/${x}XXX//") ;; esac case $lhs in bsdi) lhs=bsd ;; darwin) case $(/usr/bin/cc --version) in *'(GCC)'*) case $rel in [0-9].*|10.*) lhs=darwin07 ;; *) lhs=darwin11 ;; esac ;; esac ;; freebsd) case $rel in [01234].*) lhs=${lhs}4 ;; [123456789]*.*) lhs=${lhs}$(echo $rel | $SED -e 's/\..*//') ;; esac ;; hpux) lhs=hp ;; mvs) rhs=390 ;; esac case $lhs in '') type=$rhs ;; $rhs) type=$lhs ;; *) type=$lhs.$rhs ;; esac ;; esac case $type in sgi.mips*) case $mach in mips2) type=sgi.$mach abi=-o32 ;; mips3) type=sgi.$mach abi=-n32 ;; mips[456789]) type=sgi.$mach case $abi in *-n32) ;; *) abi=-64 ;; esac ;; *) pwd=$PWD cd "$TMPDIR" tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 cat > $tmp.a.c < $tmp.b.c </dev/null 2>&1 rm -f $tmp.* trap - 0 1 2 cd $pwd ;; esac case $type$abi in sgi.mips2-o32) ;; sgi.mips3) type=$type-o32 ;; sgi.mips3-n32) ;; sgi.mips4) type=$type-o32 ;; sgi.mips[456789]-64) ;; *) type=$type$abi ;; esac ;; *) case $bits in '') bits=$( cd "$TMPDIR" LC_ALL=C export LC_ALL tmp=hi$$ trap 'rm -f $tmp.*' 0 1 2 echo 'int main() { return 0; }' > $tmp.a.c $cc $CCFLAGS -o $tmp.a.exe $tmp.a.c /dev/null 2>&1 file $tmp.a.exe 2>/dev/null | sed "s/$tmp\.a\.exe//g" ) case $bits in *\ 64-bit* | *\ 64\ bit* | *\ 64bit*) bits=64 ;; *) bits= ;; esac ;; esac ;; esac case $bits in 32) case $type in *.i386) bits= ;; esac ;; esac case $bits in ?*) type=$type-$bits ;; esac # last chance mapping set "" "" $map while : do case $# in [012]) break ;; esac shift;shift eval " case \$type in $1) type=\$2; break ;; esac" done _hostinfo_="$_hostinfo_ $type" ;; esac done set '' $_hostinfo_ shift _hostinfo_=$* # restore the global state PATH=$path case $DEBUG in '') exec 2>&9 exec 9>&- ;; esac } # info message note() # message ... { echo $command: "$@" >&2 } # cc checks # # CC: compiler base name name # cc: full path, empty if not found checkcc() { cc= if onpath $CC then cc=$_onpath_ else case $CC in cc) if onpath gcc then CC=gcc cc=$_onpath_ fi ;; esac fi case $cc in '') case $action in make|test) note "$CC: not found"; exit 1 ;; *) note "warning: $CC: not found" ;; esac ;; esac } # some actions have their own PACKAGEROOT or kick out early case $action in host) eval u=$package_use case $u in $PACKAGE_USE) ;; *) if onpath $0 then case $_onpath_ in */arch/$HOSTTYPE/bin/package) KEEP_HOSTTYPE=1 ;; *) KEEP_HOSTTYPE=0 ;; esac else KEEP_HOSTTYPE=0 fi ;; esac hostinfo $args echo $_hostinfo_ exit 0 ;; export|setup|use) x= ;; *) x= eval u=$package_use case $u in $PACKAGE_USE) case :$PATH: in *:$INSTALLROOT/bin:*) case $LIBPATH: in $INSTALLROOT/bin:$INSTALLROOT/lib:*) case $SHLIB_PATH: in $INSTALLROOT/lib:*) x=1 ;; esac ;; esac ;; esac ;; esac ;; esac run=- case $x in 1) : accept the current package use environment OK=ok KSH=$EXECROOT/bin/ksh MAKE=mamake SUM=$EXECROOT/bin/sum TEE=$EXECROOT/bin/tee INITROOT=$PACKAGEROOT/src/cmd/INIT checkcc ;; *) hosttype= case $KEEP_PACKAGEROOT in 0) case $action in use) PACKAGEROOT= case $show in echo) exec=echo make=echo show=echo ;; esac set '' $args shift case $# in 0) ;; *) case $1 in -|.) ;; /*) PACKAGEROOT=$1 ;; *) i=$(echo ~$1) if packageroot $i then PACKAGEROOT=$i else for i in $(echo $HOME | sed -e 's,/[^/]*$,,') $usr $use do if packageroot $i/$1 then PACKAGEROOT=$i/$1 break fi done case $PACKAGEROOT in '') hosttype=$1 ;; esac fi ;; esac shift ;; esac run="$@" ;; esac case $PACKAGEROOT in '') PACKAGEROOT=$PWD ;; esac # . must be within the PACKAGEROOT tree i=X$PACKAGEROOT IFS=/ set $i IFS=$ifs while : do i=$1 shift case $i in X) break ;; esac done case $PACKAGEROOT in //*) d=/ ;; *) d= ;; esac case $1 in home) k=1 ;; *) k=0 ;; esac for i do case $i in '') continue ;; esac d=$d/$i case $k in 2) k=1 ;; 1) k=0 ;; 0) case $i in arch) k=2 ;; *) if packageroot $d then PACKAGEROOT=$d fi ;; esac ;; esac done ;; esac INITROOT=$PACKAGEROOT/src/cmd/INIT $show PACKAGEROOT=$PACKAGEROOT $show export PACKAGEROOT export PACKAGEROOT # initialize the architecture environment case $KEEP_HOSTTYPE in 0) hostinfo type HOSTTYPE=$_hostinfo_ ;; 1) _PACKAGE_HOSTTYPE_=$HOSTTYPE export _PACKAGE_HOSTTYPE_ ;; esac $show HOSTTYPE=$HOSTTYPE $show export HOSTTYPE export HOSTTYPE INSTALLROOT=$PACKAGEROOT/arch/$HOSTTYPE case $action in install|make|remove|test|view) ;; *) if test ! -d $INSTALLROOT then INSTALLROOT=$PACKAGEROOT fi ;; esac $show INSTALLROOT=$INSTALLROOT $show export INSTALLROOT export INSTALLROOT # check the basic package hierarchy case $action in export|use) packageroot $PACKAGEROOT || { echo "$command: $PACKAGEROOT: invalid package root directory" >&2 exit 1 } case $KEEP_HOSTTYPE:$hosttype in 0:?*) if test -d ${PACKAGEROOT:-.}/arch/$hosttype then KEEP_HOSTTYPE=1 HOSTTYPE=$hosttype else echo "$command: $hosttype: package root not found" >&2 exit 1 fi ;; esac ;; *) packageroot $PACKAGEROOT || { case $KEEP_PACKAGEROOT in 1) ;; *) echo "$command: $PACKAGEROOT: must be in the package root directory tree" >&2 exit 1 ;; esac } for i in arch arch/$HOSTTYPE do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || exit done for i in lib do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done # no $INITROOT means INIT already installed elsewhere if test -d $INITROOT then # update the basic package commands for i in execrate ignore mamprobe silent do test -h $PACKAGEROOT/bin/$i 2>/dev/null || case $(ls -t $INITROOT/$i.sh $PACKAGEROOT/bin/$i 2>/dev/null) in "$INITROOT/$i.sh"*) note update $PACKAGEROOT/bin/$i shellmagic case $SHELLMAGIC in '') $exec cp $INITROOT/$i.sh $PACKAGEROOT/bin/$i || exit ;; *) case $exec in '') { echo "$SHELLMAGIC" cat $INITROOT/$i.sh } > $PACKAGEROOT/bin/$i || exit ;; *) echo "{ echo \"$SHELLMAGIC\" cat $INITROOT/$i.sh } > $PACKAGEROOT/bin/$i" ;; esac ;; esac $exec chmod +x $PACKAGEROOT/bin/$i || exit ;; esac done fi ;; esac path=$PATH PATH=$INSTALLROOT/bin:$PACKAGEROOT/bin:$PATH checkcc PATH=$path case $cc in ?*) if test -f $INITROOT/hello.c then # check if $CC (full path $cc) is a cross compiler ( cd "$TMPDIR" || exit 3 cp $INITROOT/hello.c pkg$$.c || exit 3 $cc -o pkg$$.exe pkg$$.c > pkg$$.e 2>&1 || { if $cc -Dnew=old -o pkg$$.exe pkg$$.c > /dev/null 2>&1 then echo "$command: ${warn}$CC: must be a C compiler (not C++)" >&2 else cat pkg$$.e echo "$command: ${warn}$CC: failed to compile and link $INITROOT/hello.c -- is it a C compiler?" >&2 fi exit 2 } if ./pkg$$.exe >/dev/null 2>&1 then code=0 else code=1 fi rm -f pkg$$.* exit $code ) code=$? case $code in 1) CROSS=1 ;; esac fi ;; esac EXECTYPE=$HOSTTYPE EXECROOT=$INSTALLROOT case $CROSS in 0) # dll hackery -- why is this so complicated? abi= case $HOSTTYPE in sgi.mips[0123456789]*) x=rld if executable /lib32/$x || executable /lib64/$x then case $INSTALLROOT in */sgi.mips[0123456789]*) u=$(echo $INSTALLROOT | sed -e 's,-[^-/]*$,,' -e 's,.$,,') ;; *) u= ;; esac for a in "n=2 v= l=" "n=3 v=N32 l=lib32" "n=4-n32 v=N32 l=lib32" "n=4 v=64 l=lib64" do eval $a case $v in N32) case $n:$HOSTTYPE in *-n32:*-n32) ;; *-n32:*) continue ;; *:*-n32) continue ;; esac ;; esac case $l in ?*) if executable ! /$l/$x then continue fi ;; esac case $u in '') case $HOSTTYPE in sgi.mips$n|sgi.mips$n-*) abi="$abi 'd=$INSTALLROOT v=$v'" ;; *) continue ;; esac ;; *) if test -d $u$n then abi="$abi 'd=$u$n v=$v'" fi ;; esac done fi ;; esac case $abi in '') abi="'d=$INSTALLROOT v='" ;; esac p=0 eval " for a in $abi do eval \$a eval \" case \\\$LD_LIBRARY\${v}_PATH: in \\\$d/lib:*) ;; *) x=\\\$LD_LIBRARY\${v}_PATH case \\\$x in ''|:*) ;; *) x=:\\\$x ;; esac LD_LIBRARY\${v}_PATH=\$d/lib\\\$x export LD_LIBRARY\${v}_PATH p=1 ;; esac \" done " case $LD_LIBRARY_PATH in '') ;; *) for d in $lib do case $HOSTTYPE in *64) if test -d ${d}64 then d=${d}64 fi ;; esac case :$LD_LIBRARY_PATH: in *:$d:*) ;; *) if test -d $d then LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$d p=1 fi ;; esac done ;; esac case $p in 1) $show LD_LIBRARY_PATH=$LD_LIBRARY_PATH $show export LD_LIBRARY_PATH export LD_LIBRARY_PATH ;; esac case $LIBPATH: in $INSTALLROOT/bin:$INSTALLROOT/lib:*) ;; *) case $LIBPATH in '') LIBPATH=/usr/lib:/lib ;; esac LIBPATH=$INSTALLROOT/bin:$INSTALLROOT/lib:$LIBPATH $show LIBPATH=$LIBPATH $show export LIBPATH export LIBPATH ;; esac case $SHLIB_PATH: in $INSTALLROOT/lib:*) ;; *) SHLIB_PATH=$INSTALLROOT/lib${SHLIB_PATH:+:$SHLIB_PATH} $show SHLIB_PATH=$SHLIB_PATH $show export SHLIB_PATH export SHLIB_PATH ;; esac case $DYLD_LIBRARY_PATH: in $INSTALLROOT/lib:*) ;; *) DYLD_LIBRARY_PATH=$INSTALLROOT/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH} $show DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH $show export DYLD_LIBRARY_PATH export DYLD_LIBRARY_PATH ;; esac case $_RLD_ROOT in $INSTALLROOT/arch*) ;; ':') _RLD_ROOT=$INSTALLROOT/arch:/ ;; /|*:/) _RLD_ROOT=$INSTALLROOT/arch:$_RLD_ROOT ;; *) _RLD_ROOT=$INSTALLROOT/arch:$_RLD_ROOT:/ ;; esac $show _RLD_ROOT=$_RLD_ROOT $show export _RLD_ROOT export _RLD_ROOT # now set up PATH # # NOTE: PACKAGEROOT==INSTALLROOT is possible for binary installations case $PATH: in $PACKAGEROOT/bin:*) ;; *) PATH=$PACKAGEROOT/bin:$PATH ;; esac case $PATH: in $INSTALLROOT/bin:*) ;; *) PATH=$INSTALLROOT/bin:$PATH ;; esac $show PATH=$PATH $show export PATH export PATH ;; *) for i in package proto do if onpath $i then EXECROOT=$(echo $_onpath_ | sed -e 's,//*[^/]*//*[^/]*$,,') EXECTYPE=$(echo $EXECROOT | sed -e 's,.*/,,') break fi done case $HOSTTYPE in $EXECTYPE) OCC=$CC CC=cc hostinfo type EXECTYPE=$_hostinfo_ case $HOSTTYPE in $EXECTYPE) echo "$command: $CC: seems to be a cross-compiler" >&2 echo "$command: set HOSTTYPE to something other than the native $EXECTYPE" >&2 echo "$command: If not, your $TMPDIR directory may be mounted without execute permission." >&2 echo "$command: Try exporting TMPDIR as a directory where you can execute binary files." >&2 exit 1 ;; esac ;; esac $show EXECTYPE=$EXECTYPE $show export EXECTYPE export EXECTYPE ;; esac $show EXECROOT=$EXECROOT $show export EXECROOT export EXECROOT # use these if possible OK=ok KSH=$EXECROOT/bin/ksh MAKE=mamake SUM=$EXECROOT/bin/sum TEE=$EXECROOT/bin/tee # grab a decent default shell checksh "$SHELL" || KEEP_SHELL=0 case $KEEP_SHELL in 0) save_PATH=$PATH if PATH=$(getconf PATH 2>/dev/null) then PATH=$PATH:$path else PATH=/bin:/usr/bin:/sbin:/usr/sbin:$path fi for i in ksh ksh93 mksh yash bash sh do if onpath "$i" && checksh "$_onpath_" then SHELL=$_onpath_ KEEP_SHELL=1 break fi done PATH=$save_PATH unset save_PATH case $KEEP_SHELL in 0) echo "Cannot find good default shell, please supply SHELL=/path/to/shell" >&2 exit 1 ;; esac ;; esac export SHELL $show SHELL=$SHELL $show export SHELL # tame the environment case $action in use) ;; *) ENV= ERROR_OPTIONS= export ENV ERROR_OPTIONS ;; esac # finalize the views case $USER_VPATH in '') case $VPATH in ?*) IFS=':' set '' $VPATH shift IFS=$ifs USER_VPATH= for i do case $i in */arch/$HOSTTYPE) ;; */arch/*/*) ;; */arch/*) continue ;; esac if packageroot $i then case $USER_VPATH in '') USER_VPATH=$i ;; ?*) USER_VPATH=$USER_VPATH:$i ;; esac fi done esac ;; esac case $USER_VPATH in ?*) IFS=':' set '' $USER_VPATH shift IFS=$ifs USER_VPATH= USER_VPATH_CHAIN= p=$PACKAGEROOT for i do case $i in ''|$PACKAGEROOT|$INSTALLROOT) ;; ?*) USER_VPATH=$USER_VPATH:$i USER_VPATH_CHAIN="$USER_VPATH_CHAIN $p $i" p=$i case $PROTOROOT in -) executable $i/bin/mamake && PROTOROOT= ;; esac ;; esac done ;; esac ;; esac PACKAGEBIN=$INSTALLROOT/lib/package case $action:$run in use:-) set '' $args shift case $# in 0) ;; *) shift ;; esac run="$@" ;; esac # HOSTTYPE specific package profile if test -r $INSTALLROOT/lib/package/profile then . $INSTALLROOT/lib/package/profile fi # more Cygwin hassles case $HOSTTYPE in cygwin.*) lose= case $CYGWIN in *nontsec*) lose=ntsec ;; *ntsec*);; *) exe=$TMPDIR/pkg$$.exe rm -f "$exe" : > "$exe" if test -x "$exe" then lose=ntsec fi ;; esac case $CYGWIN in *nobinmode*) case $lose in '') lose=binmode ;; *) lose="$lose binmode" ;; esac ;; esac case $lose in ?*) echo "$command: $HOSTTYPE: export '$lose' in CYGWIN or languish in Windows" >&2 exit 1 ;; esac ;; esac # set up the view state VIEW_bin=$INSTALLROOT VIEW_src=$PACKAGEROOT VIEW_all="$INSTALLROOT $PACKAGEROOT" VPATH=$INSTALLROOT:$PACKAGEROOT$USER_VPATH $show VPATH=$VPATH $show export VPATH export VPATH IFS=':' set '' $VPATH shift IFS=$ifs for i do case $i in */arch/*/*) VIEW_src="$VIEW_src $i" ;; */arch/*) VIEW_bin="$VIEW_bin $i" ;; *) VIEW_src="$VIEW_src $i" ;; esac VIEW_all="$VIEW_all $i" done # return 0 if arg in src|bin|all view view() # [test] [-|type] [src|bin|all] file { case $1 in -[dfsx])_view_T_=$1; shift ;; *) _view_T_=-f ;; esac case $1 in -) _view_t_= ;; *) _view_t_=$1 ;; esac shift case $1 in all) shift; _view_v_=$VIEW_all ;; bin) shift; _view_v_=$VIEW_bin ;; src) shift; _view_v_=$VIEW_src ;; *) _view_v_=$VIEW_all ;; esac case $1 in /*) if test $_view_T_ $1 then _view_=$1 return 0 fi ;; *) for _view_d_ in $_view_v_ do if test $_view_T_ $_view_d_/$1 then _view_=$_view_d_/$1 return 0 fi done ;; esac _view_= case $_view_t_ in ?*) echo $command: $1: $_view_t_ not found >&2 ;; esac return 1 } # determine the package and targets case $action in *) package= target= set '' $args while : do shift case $# in 0) break ;; esac case $1 in ''|-) target="$target $package" package= ;; *) if view - src "lib/package/$1.pkg" then package="$package $1" else target="$target $package $1" package= fi ;; esac done ;; esac # check that cmd args are up to date a.out's checkaout() # cmd ... { case $PROTOROOT in -) PROTOROOT= case $* in ratz) if test -f $INITROOT/ratz.c -a -w $PACKAGEROOT then test -f $INITROOT/hello.c || { cat > $INITROOT/hello.c <<'!' #ifndef printf #include #endif int main() { int new = 0; printf("hello world\n"); return new;} ! } test -f $INITROOT/p.c || { cat > $INITROOT/p.c <<'!' /* * small test for prototyping cc */ int main(int argc, char** argv) { return argc || argv; } ! } fi ;; esac test -f $INITROOT/hello.c -a -f $INITROOT/p.c -a -w $PACKAGEROOT || { for i do onpath $i || { echo "$command: $i: command not found" >&2 return 1 } done return 0 } case $cc in '') _PACKAGE_cc=0 ;; *) _PACKAGE_cc=1 test -f $INITROOT/hello.c -a -f $INITROOT/p.c || { echo "$command: $INITROOT: INIT package source not found" >&2 return 1 } # check for prototyping cc # NOTE: proto.c must be K&R compatible $CC -c $INITROOT/p.c >/dev/null 2>&1 c=$? rm -f p.* test 0 != "$c" && { checkaout proto || return PROTOROOT=$PACKAGEROOT/proto $show PROTOROOT=$PACKAGEROOT/proto export PROTOROOT INITPROTO=$PROTOROOT/src/cmd/INIT note proto convert $PACKAGEROOT/src into $PROTOROOT/src dirs="src" ( if test -f $PROTOROOT/UPDATE then newer="-newer $PROTOROOT/UPDATE" else newer="" fi case $exec in '') cd $PACKAGEROOT find $dirs -name '*.[CcHh]' $newer -print | proto -v -L - -C proto ;; *) $exec cd $PACKAGEROOT $exec "find $dirs -name '*.[CcHh]' $newer -print | proto -L - -C proto" ;; esac $exec touch $PROTOROOT/UPDATE ) VPATH=$INSTALLROOT:$PROTOROOT:$PACKAGEROOT$USER_VPATH $show VPATH=$VPATH export VPATH } for i in arch arch/$HOSTTYPE arch/$HOSTTYPE/bin do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || return done ;; esac ;; esac case $_PACKAGE_cc in '') case $cc in '') _PACKAGE_cc=0 ;; *) _PACKAGE_cc=1 ;; esac ;; esac for i do eval j=\$_PACKAGE_AOUT_$i case $j in '') eval _PACKAGE_AOUT_$i=1 ;; *) continue ;; esac k=$_PACKAGE_cc if test -f $INITROOT/$i.c then k=${k}1 else k=${k}0 fi if executable $EXECROOT/bin/$i then k=${k}1 else k=${k}0 fi : $k : compiler : source : binary : case $k in *00) view - bin/$i && continue ;; esac case $k in 000) echo "$command: $i: not found: download the INIT package $HOSTTYPE binary to continue" >&2 return 1 ;; 010) echo "$command: $i: not found: set CC=C-compiler or download the INIT package $HOSTTYPE binary to continue" >&2 return 1 ;; 100) echo "$command: $i: not found: download the INIT package source or $HOSTTYPE binary to continue" >&2 return 1 ;; 110) case $CROSS in 1) echo "$command: $i: not found: make the local $EXECTYPE binary package before $HOSTTYPE" >&2 return 1 ;; esac ;; ?01) : accept binary continue ;; 011) : accept binary continue ;; ??1) case $CROSS in 1) continue ;; esac ;; esac case $(ls -t $INITROOT/$i.c $INSTALLROOT/bin/$i 2>/dev/null) in "$INITROOT/$i.c"*) note update $INSTALLROOT/bin/$i if test proto != "$i" && executable $INSTALLROOT/bin/proto then case $exec in '') $INSTALLROOT/bin/proto -p $INITROOT/$i.c > $i.c || return ;; *) $exec "$INSTALLROOT/bin/proto -p $INITROOT/$i.c > $i.c" ;; esac $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $i.c || return $exec rm -f $i.c else if test ! -d $INSTALLROOT/bin then for j in arch arch/$HOSTTYPE arch/$HOSTTYPE/bin do test -d $PACKAGEROOT/$j || $exec mkdir $PACKAGEROOT/$j || return done fi if test '' != "$PROTOROOT" -a -f $INITPROTO/$i.c then $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $INITPROTO/$i.c || return else $exec $CC $CCFLAGS -o $INSTALLROOT/bin/$i $INITROOT/$i.c || return fi case $i:$exec in proto:) test -d $INSTALLROOT/include || mkdir $INSTALLROOT/include $INSTALLROOT/bin/proto -f /dev/null > $i.c cmp -s $i.c $INSTALLROOT/include/prototyped.h 2>/dev/null || cp $i.c $INSTALLROOT/include/prototyped.h rm $i.c ;; esac fi test -f $i.o && $exec rm -f $i.o i=$PATH PATH=/bin PATH=$i ;; esac done return 0 } # list main environment values showenv() { case $1 in ''|make)for __i__ in CC SHELL $env do eval echo $__i__='$'$__i__ done ;; esac } # capture command output capture() # file command ... { tee_pid= case $make:$noexec in :) case $action in install|make|view) o=$action ;; *) case $package in ''|*' '*) o=$action ;; *) o=$package ;; esac ;; esac d=$PACKAGEBIN/gen test -d $d || $exec mkdir $d o=$d/$o case $o in $output)o=$o.out s= ;; *) output=$o if test -f $o.old then mv $o.old $o.out.1 if test -f $o.out then mv $o.out $o.out.2 fi elif test -f $o.out then for i in $(ls -t $o.out.? 2>/dev/null) do break done case $i in *.1) i=2 ;; *.2) i=3 ;; *.3) i=4 ;; *.4) i=5 ;; *.5) i=6 ;; *.6) i=7 ;; *.7) i=8 ;; *.8) i=9 ;; *) i=1 ;; esac mv $o.out $o.out.$i fi o=$o.out : > $o note $action output captured in $o s="$command: $action start at $(date) in $INSTALLROOT" case $quiet in 0) cmd="echo \"$command: $action done at \$(date)\" in $INSTALLROOT 2>&1 | \$TEE -a $o" ;; *) cmd="echo \"$command: $action done at \$(date)\" in $INSTALLROOT >> $o" ;; esac trap "$cmd" 0 trap "$cmd; trap 1 0; kill -1 $$" 1 trap "$cmd; trap 2 0; kill -2 $$" 2 ;; esac case $quiet in 0) if executable ! $TEE then TEE=tee fi # Connect 'tee' to a FIFO instead of a pipe, so that we can obtain # the build's exit status and use it for $error_status rm -f $o.fifo mkfifo -m 600 $o.fifo || exit ( sleep 1 # unlink early exec rm $o.fifo ) & $TEE -a $o < $o.fifo & tee_pid=$! o=$o.fifo ;; esac { case $s in ?*) echo "$s" ;; esac showenv $action "$@" } < /dev/null > $o 2>&1 ;; *) $make "$@" ;; esac exit_status=$? if test "$exit_status" -gt "$error_status" then error_status=$exit_status fi case $tee_pid in ?*) # allow 'tee' to catch up before returning to prompt wait "$tee_pid" ;; esac } make_recurse() # dir { for _make_recurse_j in $makefiles do if view - $1/$_make_recurse_j then return fi done } # check for native ASCII 0:yes 1:no __isascii__= isascii() { case $__isascii__ in '') case $(echo A | od -o | sed -e 's/[ ]*$//' -e '/[ ]/!d' -e 's/.*[ ]//') in 005101|040412) __isascii__=0 ;; *) __isascii__=1 ;; esac esac return $__isascii__ } error_status=0 case $action in clean|clobber) cd $PACKAGEROOT $exec rm -rf arch/$HOSTTYPE exit ;; export) case $INSTALLROOT in $PACKAGEROOT) INSTALLROOT=$INSTALLROOT/arch/$HOSTTYPE ;; esac case $only in 0) v='$i=' ;; *) v= ;; esac set '' $target $package case $# in 1) set '' $env ;; esac while : do case $# in 1) break ;; esac shift i=$1 eval echo ${v}'$'${i} done ;; install)cd $PACKAGEROOT echo "A proper installation command is coming back soon, sorry." >&2 echo "Meanwhile, copy ksh and shcomp from: $INSTALLROOT/arch/$HOSTTYPE/bin" >&2 exit 1 ;; make|view) cd $PACKAGEROOT # check for some required commands must="$AR" warn="$NM yacc bison" test="$must $warn" have= IFS=: set /$IFS$PATH IFS=$ifs shift for t in $test do if executable $t then have="$have $t" fi done for d do for t in $test do case " $have " in *" $t "*) ;; *) if executable $d/$t then have="$have $t" fi ;; esac done done case " $have " in *" bison "*) ;; *" yacc "*) have="$have bison" ;; esac case " $have " in *" yacc "*) ;; *" bison "*) have="$have yacc" ;; esac for t in $test do case " $have " in *" $t "*) ;; *) case " $must " in *" $t "*) echo "$command: $t: not found -- must be on PATH to $action" >&2 exit 1 ;; *) echo "$command: warning: $t: not found -- some $action actions may fail" >&2 ;; esac ;; esac done # verify the top view if test ! -d $PACKAGEROOT/src then note no source packages to make exit 0 elif test ! -d $INSTALLROOT/src then note initialize the $INSTALLROOT view fi for i in arch arch/$HOSTTYPE do test -d $PACKAGEROOT/$i || $exec mkdir $PACKAGEROOT/$i || exit done for i in bin bin/$OK bin/$OK/lib fun include lib lib/package lib/package/gen src man man/man1 man/man3 man/man8 do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done make_recurse src o= k= for i in $makefiles do case $o in ?*) o="$o -o" k="$k|" ;; esac o="$o -name $i" k="$k$i" done o="( $o ) -print" for d in $src do i=src/$d if test -d $i then test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit make_recurse $i for j in $(cd $i; find . $o 2>/dev/null | sed -e 's,^\./,,' -e '/\//!d' -e 's,/[^/]*$,,' | sort -u) do case $j in $k|$MAKESKIP) continue ;; esac test -d $INSTALLROOT/$i/$j || $exec mkdir -p $INSTALLROOT/$i/$j || exit done fi done # check $CC and { ar cc ld ldd } intercepts h="${HOSTTYPE} ${HOSTTYPE}.*" case $HOSTTYPE in *.*) t=$(echo $HOSTTYPE | sed 's/[.][^.]*//') h="$h $t" ;; *) t=$HOSTTYPE ;; esac case $t in *[0123456789]) t=$(echo $t | sed 's/[0123456789]*$//') h="$h $t" ;; esac case $CC in cc) c=cc b=$INSTALLROOT/bin/$c t=$INSTALLROOT/lib/package/gen/$c.tim intercept=0 for k in $h do for s in $INITROOT/$c.$k do test -x "$s" || continue if cmp -s "$s" "$b" >/dev/null 2>&1 then intercept=1 break 2 fi case $(ls -t "$t" "$b" "$s" 2>/dev/null) in $t*) ;; $b*) cc=$b ;; $s*) $exec cd $INSTALLROOT/lib/package/gen tmp=pkg$$ $exec eval "echo 'int main(){return 0;}' > $tmp.c" if $exec $s -o $tmp.exe $tmp.c >/dev/null 2>&1 && test -x $tmp.exe then case $HOSTTYPE in *.mips*)$s -version >/dev/null 2>&1 || s= ;; esac case $s in ?*) $exec sed "s/^HOSTTYPE=.*/HOSTTYPE=$HOSTTYPE/" < "$s" > "$b" || exit $exec chmod +x "$b" || exit cc=$b intercept=1 note update $b ;; esac fi $exec rm -f $tmp.* $exec touch "$t" cd $PACKAGEROOT ;; esac break 2 done done case $intercept in 1) c=ld b=$INSTALLROOT/bin/$c for k in $h do for s in $INITROOT/$c.$k do test -x "$s" || continue case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done done ;; esac ;; esac c=ldd b=$INSTALLROOT/bin/$c for t in $h do s=$INITROOT/$c.$t test -x "$s" || continue onpath $c || case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done c=ar b=$INSTALLROOT/bin/$c for t in $h do s=$INITROOT/$c.$t test -x "$s" || continue case $(ls -t "$b" "$s" 2>/dev/null) in $b*) ;; $s*) $exec cp "$s" "$b" note update $b ;; esac done case $cc in /*) ;; *) echo "$command: $CC: not found -- set CC=C-compiler" >&2 exit 1 ;; esac case $exec in '') cd $INSTALLROOT/lib/package/gen tmp=pkg$$ echo 'int main(){return 0;}' > $tmp.c if $CC -o $tmp.exe $tmp.c > /dev/null 2> $tmp.err && test -x $tmp.exe then : ok else echo "$command: $CC: failed to compile this program:" >&2 cat $tmp.c >&2 if test -s $tmp.err then cat $tmp.err >&2 else echo "$command: $CC: not a C compiler" >&2 fi rm -f $tmp.* exit 1 fi rm -f $tmp.* cd $PACKAGEROOT ;; esac # remember the default $CC case $CC in cc) ;; *) if test -x $INSTALLROOT/bin/cc then case $(sed 1q $INSTALLROOT/bin/cc) in ": $CC :") CC=cc export CC ;; *) assign="$assign CC=\"\$CC\"" ;; esac else case $CROSS in 1) assign="$assign CC=\"\$CC\"" ;; *) case $exec in '') { echo ": $CC :" echo "$CC \"\$@\"" } > $INSTALLROOT/bin/cc chmod +x $INSTALLROOT/bin/cc ;; *) note generate a $INSTALLROOT/bin/cc wrapper for $CC ;; esac CC=cc export CC ;; esac fi ;; esac # no $INITROOT means INIT already installed elsewhere if test -d $INITROOT then # update probe scripts for i in lib/probe lib/probe/C lib/probe/C/make do test -d $INSTALLROOT/$i || $exec mkdir $INSTALLROOT/$i || exit done i=$INSTALLROOT/lib/probe/C/make/probe j=$INITROOT/C+probe k=$INITROOT/make.probe case $(ls -t $i $j $k 2>/dev/null) in $i*) ;; *) if test -f $j -a -f $k then note update $i shellmagic case $exec in '') { case $SHELLMAGIC in ?*) echo "$SHELLMAGIC" ;; esac cat $j $k } > $i || exit ;; *) echo "{ echo $SHELLMAGIC cat $j $k } > $i" ;; esac $exec chmod +x $i || exit fi ;; esac fi # initialize a few mamake related commands checkaout mamake proto ratz || exit # execrate if necessary if (execrate) >/dev/null 2>&1 then execrate=execrate $make cd $INSTALLROOT/bin for i in chmod chgrp cmp cp ln mv rm do if test ! -x $OK/$i -a -x /bin/$i.exe then shellmagic case $exec in '') echo "$SHELLMAGIC"'execrate /bin/'$i' "$@"' > $OK/$i chmod +x $OK/$i ;; *) $exec echo \'"$SHELLMAGIC"'execrate /bin/'$i' "$@"'\'' >' $OK/$i $exec chmod +x $OK/$i ;; esac fi done PATH=$INSTALLROOT/bin/$OK:$PATH export PATH else execrate= fi case $action in view) exit 0 ;; esac # check against previous compiler and flags err= for var in CC CCFLAGS CCLDFLAGS LDFLAGS KSH_RELFLAGS do store=$INSTALLROOT/lib/package/gen/$var eval "new=\$$var" if test -f $store then old=$(cat $store) case $old in "$new") ;; *) case $old in '') old="(none)" ;; *) old="'$old'" ;; esac case $new in '') new="(none)" ;; *) new="'$new'" ;; esac echo "$command: $var changed from $old to $new" >&2 err=y ;; esac else test -d $INSTALLROOT/lib/package/gen && case $new in '') ;; *) echo "$new" ;; esac > $store fi done case $err,${FORCE_FLAGS+f} in y,) echo "$command: This would likely break the build. Restore the flag(s)," >&2 echo "$command: or delete the build directory and rebuild from scratch." >&2 exit 1 ;; esac unset err var store old new # all work under $INSTALLROOT/src $make cd $INSTALLROOT/src # record the build host name case $exec in '') hostinfo name echo "$_hostinfo_" | sed 's,\..*,,' > $PACKAGEBIN/gen/host ;; esac # make in parallel if possible case $NPROC in '') hostinfo cpu case $_hostinfo_ in 0|1) ;; *) NPROC=$_hostinfo_ $show NPROC=$NPROC $show export NPROC export NPROC ;; esac ;; esac # separate flags from target list case $target in *-*) a= for t in $target do case $t in -*) makeflags="$makeflags $t" ;; *) a="$a $t" ;; esac done target=$a ;; esac # mamprobe data should have been generated by this point case $exec in '') if test ! -f $INSTALLROOT/bin/.paths -o -w $INSTALLROOT/bin/.paths then N=' ' b= f= h= n= p= u= B= L= if test -f $INSTALLROOT/bin/.paths then exec < $INSTALLROOT/bin/.paths while read x do case $x in '#'?*) case $h in '') h=$x ;; esac ;; *BUILTIN_LIB=*) b=$x ;; *FPATH=*) f=$x ;; *PLUGIN_LIB=*) p=$x ;; *) case $u in ?*) u=$u$N ;; esac u=$u$x ;; esac done fi ifs=$IFS m= case $p in ?*) b= ;; esac case $b in ?*) IFS='=' set $b IFS=$ifs shift p="PLUGIN_LIB=$*" case $b in [Nn][Oo]*) p=no$p ;; esac m=1 ;; esac case $f in '') f="FPATH=../fun" m=1 ;; esac case $h in '') h='# use { no NO } prefix to permanently disable #' ;; esac case $p in '') p="PLUGIN_LIB=cmd" if grep '^setv mam_cc_DIALECT .* EXPORT=[AD]LL' $INSTALLROOT/lib/probe/C/mam/* >/dev/null 2>&1 then p=no$p fi m=1 ;; esac case $m in 1) case $u in ?*) u=$N$u ;; esac echo "$h$N$p$N$f$N$u" > $INSTALLROOT/bin/.paths ;; esac fi ;; esac # run from separate copies since ksh may be rebuilt case $EXECROOT in $INSTALLROOT) $make cd $INSTALLROOT/bin if executable /bin/cp then cp=/bin/cp else cp=cp fi if executable /bin/mv then mv=/bin/mv else mv=mv fi if executable /bin/rm then rm=/bin/rm else rm=rm fi for i in \ ksh tee cp ln mv rm \ *ast*.dll *cmd*.dll *dll*.dll *shell*.dll do executable $i && { cmp -s $i $OK/$i 2>/dev/null || { test -f $OK/$i && $exec $execrate $rm $OK/$i &2 exit 1 ;; esac $exec $execrate $cp $i $OK/$i } } done if executable $OK/tee then TEE=$INSTALLROOT/bin/$OK/tee fi if test "$KEEP_SHELL" != 1 && executable $OK/ksh then SHELL=$INSTALLROOT/bin/$OK/ksh export SHELL fi case :$PATH: in *:$INSTALLROOT/bin/$OK:*) ;; *) PATH=$INSTALLROOT/bin/$OK:$PATH export PATH ;; esac $make cd $INSTALLROOT/src ;; esac # build with mamake note make with mamake case $target in '') target="install" ;; esac eval capture mamake \$makeflags \$noexec \$target $assign ;; remove) echo "$command: $action: not implemented yet" >&2 exit 1 ;; results)set '' $target shift def=make dir=$PACKAGEBIN/gen case $verbose in 0) filter=yes ;; *) filter=cat ;; esac path=0 suf=out on= while : do case $# in 0) break ;; esac case $1 in --) shift break ;; error*|fail*) filter=errors ;; make|test|view) def=$1 case $filter:$1:$SHELL in errors:*:*) ;; *:test:*/ksh*) filter=rt ;; esac ;; old) suf=old ;; on) case $# in 1) echo $command: $action: $1: host pattern argument expected >&2 exit 1 ;; esac shift case $on in ?*) on="$on|" ;; esac on="$on$1" ;; path) path=1 ;; test) def=test filter=rt ;; *) break ;; esac shift done case $dir in */admin)case $on in '') on="*" ;; *) on="@($on)" ;; esac def=$def.log/$on ;; esac case $# in 0) set "$def" ;; esac m= t= for i do k=0 eval set '""' $i - $i.$suf - $dir/$i - $dir/$i.$suf - shift for j do case $j in -) case $k in 1) continue 2 ;; esac ;; *) if test -f $j then k=1 case /$j in */test.*) t="$t $j" ;; *) m="$m $j" ;; esac fi ;; esac done echo "$command: $i action output not found" >&2 exit 1 done sep= case $t in ?*) case $path in 0) for j in $t do echo "$sep==> $j <==" sep=$nl case $filter in cat) $exec cat $j ;; errors) $exec egrep -i '\*\*\*|FAIL[ES]|^TEST.* [123456789][0123456789]* error|core.*dump' $j | sed -e '/^TEST.\//s,/[^ ]*/,,' ;; rt) $exec $KSH rt - $j ;; *) $exec egrep -i '^TEST|FAIL' $j ;; esac done ;; 1) echo $t ;; esac ;; esac case $m in ?*) case $path in 0) case $filter in cat) cat $m ;; *) if test -f $HOME/.pkgresults then i=$(cat $HOME/.pkgresults) case $i in '|'*) ;; *) i="|$i" ;; esac else i= fi for j in $m do echo "$sep==> $j <==" sep=$nl case $filter in errors) $exeg egrep '^pax:|\*\*\*' $j ;; *) $exec egrep -iv '^($||[\+\[]|cc[^-:]|kill |make.*(file system time|has been replaced)|so|[0123456789]+ error|uncrate |[0123456789]+ block|ar: creat|iffe: test: |conf: (check|generate|test)|[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_][abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*=|gsf@research|ar:.*warning|cpio:|ld:.*(duplicate symbol|to obtain more information)|[0123456789]*$|(checking|creating|touch) [/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789])| obsolete predefined symbol | is (almost always misused|dangerous|deprecated|not implemented)| trigraph| assigned to | cast .* different size| integer overflow .*<<| optimization may be attained | passed as |::__builtin|pragma.*prototyped|^creating.*\.a$|warning.*not optimized|exceeds size thresh|ld:.*preempts|is unchanged|with value >=|(-l|lib)\*|/(ast|sys)/(dir|limits|param|stropts)\.h.*redefined|usage|base registers|`\.\.\.` obsolete'"$i" $j | $exec grep : ;; esac done ;; esac ;; 1) echo $m ;; esac esac ;; test) # pass control to ksh 93u+m test script capture "$PACKAGEROOT/bin/shtests" $args ;; use) # finalize the environment x=:.. for d in $( cd $PACKAGEROOT; ls src/*/Mamfile 2>/dev/null | sed 's,/[^/]*$,,' | sort -u ) do x=$x:$INSTALLROOT/$d done x=$x:$INSTALLROOT case $CDPATH: in $x:*) ;; *) CDPATH=$x:$CDPATH $show CDPATH=$CDPATH $show export CDPATH export CDPATH ;; esac P=$PACKAGEROOT $show P=$P $show export P export P A=$INSTALLROOT $show A=$A $show export A export A case $NPROC in '') hostinfo cpu case $_hostinfo_ in 0|1) ;; *) NPROC=$_hostinfo_ $show NPROC=$NPROC $show export NPROC export NPROC ;; esac ;; esac eval PACKAGE_USE=$package_use export PACKAGE_USE # run the command case $run in '') case $show in ':') $exec exec $SHELL ;; esac ;; *) $exec exec $SHELL -c "$run" ;; esac ;; *) echo "$command: $action: internal error" >&2 exit 1 ;; esac exit "$error_status" ksh-1.0.0-beta.2/src/cmd/INIT/probe.win32000066400000000000000000000122501415700074400174400ustar00rootroot00000000000000: # @(#)probe.win32 (AT&T Research) 2010-01-01 # # Win32 specific make C probe initialization # wrapped cc's are easy on UWIN # # 2> easy.err to avoid mysterious hang with bcc # begin preamble shared with the pp probe.ini IFS=$'\n' chmod 777 . # cl.exe setuid workaround typeset -A header version # we are probing on behalf of libpp and nmake # so the native preprocessor must be forced in # order to bootstrap libpp and nmake nativepp=-1 export nativepp probe_header=" stddef.h " for inc in syslimits.h winerror.h ostream bits/ctype_base.h stream.h do echo "#include <$inc>" > easy.c if $cc -E easy.c > /dev/null 2> easy.err then probe_header="$probe_header $inc " fi done { for i in $probe_header do echo "#include <$i>" done echo '#ifdef __cplusplus' echo "int _Pr0b3_cplus=__cplusplus;" echo '#endif' echo '#ifdef _UWIN' echo "int _Pr0b3_uwin=_UWIN;" echo '#endif' echo '#ifdef __BORLANDC__' echo "int _Pr0b3_version_BORLAND=__BORLANDC__;" echo '#endif' echo '#ifdef __DMC__' echo "int _Pr0b3_version_DM=__DMC__;" echo '#endif' echo '#ifdef _MSC_VER' echo "int _Pr0b3_version_MS=_MSC_VER;" echo '#endif' echo '#ifdef __ICL' echo "int _Pr0b3_version_ICL=__ICL;" echo '#endif' echo '#ifdef __LCC__' echo "int _Pr0b3_version_LCC=0+__LCC__;" echo '#endif' echo '#ifdef __MINGW32__' echo "int _Pr0b3_version_MINGW=__MINGW32__;" echo '#endif' echo '#ifdef __INTERIX' echo "int _Pr0b3_version_INTERIX=__INTERIX;" echo '#endif' echo '#ifdef __WATCOMC__' echo "int _Pr0b3_version_WATCOM=__WATCOMC__;" echo '#endif' } > easy.c include= uwin= cplus= $cc -E easy.c 2>&1 | egrep -i '^(#(line)? 1 .*\.[hH]| *int +_Pr0b3_[a-zA-Z_]* *= *[0-9])' | sed -e 's,_Pr0b3_,,' \ -e 's/.*"\(.*\)".*/\1/' \ -e 's,^ *,,' \ -e 's, *$,,' \ -e 's, *= *,=,' \ -e 's,^\(.\):[\\/]*,/\1/,' \ -e 's,[\\/][\\/]*,/,g' \ -e 's,^\(/.*\)/\(.*\)$,header[\2]="\1",' \ -e 's, *int *\(.*\);.*,\1,' \ -e 's,^version_\(.*\)=,version[\1]=,' \ > easy.sh . ./easy.sh include= for i in $probe_header do d=${header[$i]} if [[ $d ]] then include="$include $d" elif [[ $i == */* ]] then d=${header[${i##*/}]} if [[ $d == */${i%/*} ]] then include="$include ${d%/${i%/*}}" fi fi done i=$($cc -V 2> easy.err) if test "" != "$i" -a -d "$i/include" then include="$i/include $include" fi stdinclude= for inc in $include do if [[ ${inc%/*} -ef /msdev/platformsdk ]] then inc=/msdev/platformsdk/${inc##*/} elif [[ ${inc%/*} -ef /platformsdk ]] then inc=/platformsdk/${inc##*/} fi for dup in $stdinclude do [[ $inc -ef $dup ]] && continue 2 done stdinclude="$stdinclude $inc" done # end preamble shared with the pp probe.ini if [[ ${version[@]} == [0-9]* && $stdinclude ]] then : the payoff set -- $cc cmd=$1 shift set -- $(whence $cmd) "$@" typ=$(package) dialect="ANSI CLOSURE DYNAMIC EXPORT=DLL LIBPP -I-" case ${cc##*/} in *CC*) dialect="$dialect C++" cplus=1 ;; esac ld=${cc%cc}ld if [[ ! -x $ld ]] then ld=${cc%/*}/ld if [[ ! -x $ld ]] then case $cc in */ncc) ld=/usr/bin/nld ;; *) ld=/usr/bin/ld ;; esac fi fi { if $cc -v >/dev/null 2>&1 then v=$($cc -v 2>/dev/null) if [[ $v ]] then print "# ;VERSION;-v;$v;PATH;$cc" fi else v= fi cat <&3 exit 0 fi ksh-1.0.0-beta.2/src/cmd/INIT/proto.c000066400000000000000000002300761415700074400167640ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1990-2012 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #pragma clang diagnostic ignored "-Wdeprecated-register" #pragma clang diagnostic ignored "-Wparentheses" #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wstring-plus-int" /* * ksh 93u+m distribution note: * * AT&T used proto for two purposes: * * 1. To convert ANSI C code to a form compatible with ancient (pre-ANSI) K&R * C compilers using extremely complex macro voodo. It was similarly * capable of translating to C++. Theoretically, this entire code base * should compile on anything from a 1980s K&R C compiler to a modern C++ * compiler. In practice, given the massive amount of bit rot we * inherited, I am 99.9% sure that this has been broken for many years. * * 2. To automagically insert license comments into source files based on an * extremely complicated license database system. (In all-too-typical AT&T * fashion, this second function of proto is completely unrelated to the * first.) * * Function 2 has now been removed because, unlike the AT&T legal department, * I don't think it's worth going to unspeakably extreme lengths to avoid * maintaining license information in source code files by hand. * * In the process, the code below was cleaned up, but it's still generated * code; most macros have been expanded to their numeric value, etc. So don't * expect to understand the code below. The actual source code is in various * places in these two directories in the ast-open-history repo: * * https://github.com/ksh93/ast-open-history/tree/master/src/cmd/proto * https://github.com/ksh93/ast-open-history/tree/master/src/lib/libpp * * Meanwhile, nobody wants to compile ksh with a pre-ANSI K&R C compiler in * 2021 -- and there's no good reason to be compatible with C++ as standard C * compilers are universally available. So, proto will go away when I manage to * figure out how to pry it loose from the innards of this build system. */ /* : : generated by proto : : */ #if !defined(__PROTO__) # if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus) # if defined(__cplusplus) # define __LINKAGE__ "C" # else # define __LINKAGE__ # endif # define __STDARG__ # define __PROTO__(x) x # define __OTORP__(x) # define __PARAM__(n,o) n # if !defined(__STDC__) && !defined(__cplusplus) # if !defined(c_plusplus) # define const # endif # define signed # define void int # define volatile # define __V_ char # else # define __V_ void # endif # else # define __PROTO__(x) () # define __OTORP__(x) x # define __PARAM__(n,o) o # define __LINKAGE__ # define __V_ char # define const # define signed # define void int # define volatile # endif # define __MANGLE__ __LINKAGE__ # if defined(__cplusplus) || defined(c_plusplus) # define __VARARG__ ... # else # define __VARARG__ # endif # if defined(__STDARG__) # define __VA_START__(p,a) va_start(p,a) # else # define __VA_START__(p,a) va_start(p) # endif # if !defined(__INLINE__) # if defined(__cplusplus) # define __INLINE__ extern __MANGLE__ inline # else # if defined(_WIN32) && !defined(__GNUC__) # define __INLINE__ __inline # endif # endif # endif #endif #if !defined(__LINKAGE__) #define __LINKAGE__ /* 2004-08-11 transition */ #endif # ifndef __STDC__ # ifndef creat # define creat _huh_creat # endif # ifndef access # define access _huh_access # endif # ifndef ctime # define ctime _huh_ctime # endif # ifndef mkdir # define mkdir _huh_mkdir # endif # endif # include # include # include # include # ifndef __STDC__ # undef access # undef ctime # undef creat # undef mkdir # endif # ifndef O_RDONLY # define O_RDONLY 0 # endif # ifndef S_IRUSR # define S_IRUSR 0400 # endif # ifndef S_IWUSR # define S_IWUSR 0200 # endif # ifndef S_IXUSR # define S_IXUSR 0100 # endif # ifndef S_IRGRP # define S_IRGRP 0040 # endif # ifndef S_IWGRP # define S_IWGRP 0020 # endif # ifndef S_IXGRP # define S_IXGRP 0010 # endif # ifndef S_IROTH # define S_IROTH 0004 # endif # ifndef S_IWOTH # define S_IWOTH 0002 # endif # ifndef S_IXOTH # define S_IXOTH 0001 # endif # ifndef __STDC__ # if !_WIN32 && !_WINIX # define remove(x) unlink(x) # define rename(x,y) ((link(x,y)||remove(x))?-1:0) # endif extern __MANGLE__ int access __PROTO__((const char*, int)); extern __MANGLE__ int mkdir __PROTO__((const char*, int)); # endif extern __MANGLE__ int utime __PROTO__((const char*, time_t*)); int replace __PARAM__((const char* newfile, const char* oldfile, int preserve), (newfile, oldfile, preserve)) __OTORP__(const char* newfile; const char* oldfile; int preserve;) { struct stat st; time_t ut[2]; if (stat(oldfile, &st)) { if (preserve) return -1; st.st_mode = 0; } if (remove(oldfile) || rename(newfile, oldfile)) return -1; if (st.st_mode &= (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH)) chmod(oldfile, st.st_mode); if (preserve) { ut[0] = st.st_atime; ut[1] = st.st_mtime; preserve = utime(oldfile, ut); } return preserve; } # undef utime # define utime ______utime static const char id[] = "\n@(#)$Id: proto (AT&T Research) 2012-04-14 $\000\n"; struct ppsymbol; struct ppindex; typedef char* (*PPBUILTIN) __PROTO__((char*, const char*, const char*)); typedef void (*PPCOMMENT) __PROTO__((const char*, const char*, const char*, int)); typedef void (*PPINCREF) __PROTO__((const char*, const char*, int, int)); typedef void (*PPLINESYNC) __PROTO__((int, const char*)); typedef void (*PPMACREF) __PROTO__((struct ppsymbol*, const char*, int, int, unsigned long)); typedef int (*PPOPTARG) __PROTO__((int, int, const char*)); typedef void (*PPPRAGMA) __PROTO__((const char*, const char*, const char*, const char*, int)); struct ppinstk { char* nextchr; struct ppinstk* next; struct ppinstk* prev; long* control; char* buffer; char* file; char* prefix; struct ppsymbol* symbol; struct ppindex* index; int buflen; int line; int vendor; short fd; short hide; short flags; char type; }; struct pplist { char* value; struct pplist* next; }; struct oplist { int op; char* value; struct oplist* next; }; struct pphide { struct ppmacro* macro; unsigned long flags; int level; }; struct ppmacstk { struct ppmacstk* next; struct ppmacstk* prev; int line; char* arg[1]; }; struct ppmember { struct ppdirs* archive; unsigned long offset; unsigned long size; }; struct counter { int candidate; int function; int macro; int pplex; int push; int terminal; int token; }; struct pptuple { struct pptuple* nomatch; struct pptuple* match; char token[1]; }; struct ppfileid { unsigned long st_dev; unsigned long st_ino; }; struct pathid { char* path; struct ppfileid id; }; struct ppdirs { char* name; struct ppdirs* next; unsigned char c; unsigned char index; unsigned char type; union { char* buffer; char* sp; struct ppdirs* subdir; } info; struct ppfileid id; }; struct ppkeyword { char* name; int value; }; struct ppmacro { int arity; char* value; struct pptuple* tuple; char* formals; int size; }; struct ppsymbol { int hash_header; unsigned long flags; struct ppmacro* macro; __V_* value; struct pphide* hidden; }; struct ppglobals { const char* version; char* lineid; char* outfile; char* pass; char* token; struct ppsymbol* symbol; char* outb; char* outbuf; char* outp; char* oute; unsigned long offset; struct ppdirs* lcldirs; struct ppdirs* stddirs; int flags; char* symtab; struct ppcontext* context; long state; long mode; long option; long test; struct { char* sp; long flags; } filedeps; struct ppdirs* firstdir; struct ppdirs* lastdir; int hide; int column; int pending; char* firstfile; char* lastfile; char* ignore; char* probe; char* filtab; char* prdtab; char* date; char* time; char* maps; long ro_state; long ro_mode; long ro_option; long ro_op[2]; struct pathid cdir; struct pathid hostdir; char* ppdefault; struct ppindex* firstindex; struct ppindex* lastindex; struct oplist* firstop; struct oplist* lastop; struct oplist* firsttx; struct oplist* lasttx; unsigned char arg_file; unsigned char arg_mode; unsigned char arg_style; unsigned char c; unsigned char hosted; unsigned char ignoresrc; unsigned char initialized; unsigned char standalone; unsigned char spare_1; char* checkpoint; int constack; struct ppinstk* in; char* addp; char* args; char* addbuf; char* catbuf; char* hdrbuf; char* hidebuf; char* path; char* tmpbuf; char* valbuf; char* optflags; int lastout; char* include; char* prefix; struct ppmember* member; int hidden; int hiding; int level; struct { int input; int output; } pool; struct { long ro_state; long ro_mode; long ro_option; long ro_op[2]; int on; char* symtab; } reset; int truncate; struct ppmacstk* macp; char* maxmac; char* mactop; char* toknxt; long* control; long* maxcon; struct oplist* chop; struct ppfile* insert; struct ppfile* original; struct ppdirs* found; int vendor; char* dirtab; char* strtab; PPBUILTIN builtin; PPCOMMENT comment; PPINCREF incref; PPLINESYNC linesync; PPLINESYNC olinesync; PPMACREF macref; PPOPTARG optarg; PPPRAGMA pragma; struct counter counter; char funbuf[256]; }; extern __MANGLE__ struct ppglobals pp; extern __MANGLE__ char _pp_ctype[]; extern __MANGLE__ int ppargs __PROTO__((char**, int)); extern __MANGLE__ void ppcpp __PROTO__((void)); extern __MANGLE__ void ppcomment __PROTO__((char*, char*, char*, int)); extern __MANGLE__ __V_* ppcontext __PROTO__((__V_*, int)); extern __MANGLE__ void pperror __PROTO__((int, ...)); extern __MANGLE__ void ppincref __PROTO__((char*, char*, int, int)); extern __MANGLE__ void ppinput __PROTO__((char*, char*, int)); extern __MANGLE__ int pplex __PROTO__((void)); extern __MANGLE__ void ppline __PROTO__((int, char*)); extern __MANGLE__ void ppmacref __PROTO__((struct ppsymbol*, char*, int, int, unsigned long)); extern __MANGLE__ void ppop __PROTO__((int, ...)); extern __MANGLE__ void pppragma __PROTO__((char*, char*, char*, char*, int)); extern __MANGLE__ int ppprintf __PROTO__((char*, ...)); extern __MANGLE__ int ppsync __PROTO__((void)); extern __MANGLE__ struct ppkeyword ppkey[]; struct ppcontext { struct ppdirs* lcldirs; struct ppdirs* stddirs; int flags; char* symtab; struct ppcontext* context; long state; long mode; long option; long test; struct { char* sp; long flags; } filedeps; struct ppdirs* firstdir; struct ppdirs* lastdir; int hide; int column; int pending; char* firstfile; char* lastfile; char* ignore; char* probe; char* filtab; char* prdtab; char* date; char* time; char* maps; long ro_state; long ro_mode; long ro_option; long ro_op[2]; struct pathid cdir; struct pathid hostdir; char* ppdefault; struct ppindex* firstindex; struct ppindex* lastindex; struct oplist* firstop; struct oplist* lastop; struct oplist* firsttx; struct oplist* lasttx; unsigned char arg_file; unsigned char arg_mode; unsigned char arg_style; unsigned char c; unsigned char hosted; unsigned char ignoresrc; unsigned char initialized; unsigned char standalone; unsigned char spare_1; }; struct ppfile { int hash_header; struct ppsymbol* guard; struct ppfile* bound[4]; int flags; }; struct ppindex { struct ppindex* next; struct ppfile* file; unsigned long begin; unsigned long end; }; struct ppsymkey { struct ppsymbol sym; int lex; }; # ifdef __STDC__ # include # include # include # include # else # define size_t int extern __MANGLE__ __V_* realloc __PROTO__((__V_*, size_t)); extern __MANGLE__ __V_* calloc __PROTO__((size_t, size_t)); extern __MANGLE__ char* ctime __PROTO__((time_t*)); extern __MANGLE__ void free __PROTO__((__V_*)); # ifndef O_RDONLY extern __MANGLE__ int access __PROTO__((const char*, int)); extern __MANGLE__ int close __PROTO__((int)); extern __MANGLE__ int creat __PROTO__((const char*, int)); extern __MANGLE__ void exit __PROTO__((int)); extern __MANGLE__ int link __PROTO__((const char*, const char*)); extern __MANGLE__ int open __PROTO__((const char*, int, ...)); extern __MANGLE__ int read __PROTO__((int, __V_*, int)); extern __MANGLE__ time_t time __PROTO__((time_t*)); extern __MANGLE__ int unlink __PROTO__((const char*)); extern __MANGLE__ int write __PROTO__((int, const __V_*, int)); # endif # endif struct fsminit { int state; unsigned char ch[4]; int nextstate; }; static struct fsminit fsminit[] = { { 0, { 023 }, ((0+28)+11), }, { 0, { 002 }, (0), }, { 0, { 001 }, (0+23), }, { 0, { '.' }, (0+25), }, { 0, { 021 }, (0+19), }, { 0, { 'L' }, (0+20), }, { 0, { 'd', 'e', 'f', 'i' }, (0+1), }, { 0, { 'r', 's', 't', 'v' }, (0+1), }, { 0, { 'w', 'N' }, (0+1), }, { 0, { '"', '\'' }, ((0+28)+3), }, { 0, { '/' }, (0+12), }, { 0, { '\n' }, ((0+28)+7), }, { 0, { ' ','\t','\f','\013' }, (0+27), }, { (0+1), { 023 }, ((0+28)+6), }, { (0+1), { 021, 001 }, (0+19), }, { (0+1), { 'a' }, (0+2), }, { (0+1), { 'e' }, (0+3), }, { (0+1), { 'f' }, (0+4), }, { (0+1), { 'h' }, (0+5), }, { (0+1), { 'l' }, (0+6), }, { (0+1), { 'n' }, (0+7), }, { (0+1), { 'o' }, (0+8), }, { (0+1), { 't' }, (0+9), }, { (0+1), { 'x' }, (0+10), }, { (0+1), { 'y' }, (0+11), }, { (0+2), { 023 }, (((0+28)+12)), }, { (0+2), { 021, 001 }, (0+19), }, { (0+2), { '_','s','t','a' }, (0+2), }, { (0+2), { 'r' }, (0+2), }, { (0+3), { 023 }, (((0+28)+12)), }, { (0+3), { 021, 001 }, (0+19), }, { (0+3), { 't','u','r','n' }, (0+3), }, { (0+4), { 023 }, (((0+28)+12)), }, { (0+4), { 021, 001 }, (0+19), }, { (0+5), { 023 }, (((0+28)+12)), }, { (0+5), { 021, 001 }, (0+19), }, { (0+5), { 'i','l','e' }, (0+5), }, { (0+6), { 023 }, (((0+28)+12)), }, { (0+6), { 021, 001 }, (0+19), }, { (0+6), { 's','e' }, (0+6), }, { (0+7), { 023 }, (((0+28)+12)), }, { (0+7), { 021, 001 }, (0+19), }, { (0+7), { 'l','i','n','e' }, (0+7), }, { (0+8), { 023 }, (((0+28)+12)), }, { (0+8), { 021, 001 }, (0+19), }, { (0+8), { 'r','i','d','N' }, (0+8), }, { (0+9), { 023 }, (((0+28)+12)), }, { (0+9), { 021, 001 }, (0+19), }, { (0+9), { 'a','t','i','c' }, (0+9), }, { (0+10), { 023 }, (((0+28)+12)), }, { (0+10), { 021, 001 }, (0+19), }, { (0+10), { 't','e','r','n' }, (0+10), }, { (0+11), { 023 }, (((0+28)+12)), }, { (0+11), { 021, 001 }, (0+19), }, { (0+11), { 'p','e','d','f' }, (0+11), }, { (0+12), { 023 }, ((0+28)+0), }, { (0+12), { '*' }, (0+13), }, { (0+12), { '/' }, (0+16), }, { (0+13), { 023 }, (0+13), }, { (0+13), { '\n', 002 }, ((0+28)+1), }, { (0+13), { '/' }, (0+15), }, { (0+13), { '*' }, (0+14), }, { (0+13), { '#', ';', ')' }, ((( (0+13))<<(7+1))|(((0+28)+8))), }, { (0+14), { 023 }, (0+13), }, { (0+14), { '\n', 002 }, ((0+28)+1), }, { (0+14), { '#', ';', ')' }, ((( (0+13))<<(7+1))|(((0+28)+8))), }, { (0+14), { '*' }, (0+14), }, { (0+14), { '/' }, ((0+28)+1), }, { (0+15), { 023 }, (0+13), }, { (0+15), { '*', '\n', 002 }, ((0+28)+1), }, { (0+15), { '/' }, (0+15), }, { (0+16), { 023 }, (0+16), }, { (0+16), { '\n', 002 }, ((0+28)+1), }, { (0+16), { '/' }, (0+17), }, { (0+16), { '*' }, (0+18), }, { (0+17), { 023 }, (0+16), }, { (0+17), { '*', '\n', 002 }, ((0+28)+1), }, { (0+17), { '/' }, (0+17), }, { (0+18), { 023 }, (0+16), }, { (0+18), { '\n', 002 }, ((0+28)+1), }, { (0+18), { '*' }, (0+18), }, { (0+18), { '/' }, ((0+28)+1), }, { (0+19), { 023 }, ((0+28)+6), }, { (0+19), { 021, 001 }, (0+19), }, { (0+25), { 023 }, ((0+28)+0), }, { (0+25), { '.' }, (0+26), }, { (0+25), { 001 }, (0+23), }, { (0+26), { 023 }, (((( (0401+1))-0401)<<(7+1))|( ((0+28)+14))), }, { (0+26), { '.' }, (((( (0401+29))-0401)<<(7+1))|( ((0+28)+13))), }, { (0+20), { 023 }, ((0+28)+6), }, { (0+20), { 021, 001 }, (0+19), }, { (0+20), { '"', '\'' }, ((( (0+21))<<(7+1))|(((0+28)+8))), }, { (0+21), { 023 }, (0+21), }, { (0+21), { '"', '\'' }, ((0+28)+4), }, { (0+21), { '\n', 002 }, ((0+28)+4), }, { (0+21), { '\\' }, (0+22), }, { (0+22), { 023 }, ((0+28)+5), }, { (0+22), { '\n', 002 }, ((0+28)+4), }, { (0+23), { 023 }, (((( (0401+1))-0401)<<(7+1))|( ((0+28)+14))), }, { (0+23), { 021, 001, '.' }, (0+23), }, { (0+23), { 'e', 'E' }, (0+24), }, { (0+24), { 023 }, (((( (0401+1))-0401)<<(7+1))|( ((0+28)+14))), }, { (0+24), { 021, 001, '.' }, (0+23), }, { (0+24), { '+', '-' }, (0+23), }, { (0+27), { 023 }, ((0+28)+15), }, { (0+27), { ' ', '\t' }, (0+27), }, { (0+27), { '\f', '\013' }, ((0+28)+10), }, { (-1), { 0 }, 0, } }; short _pp_fsmtab[(0+28)+1][255+1]; char _pp_trigraph[255+1]; static char spl[] = { '\\', '\r', 0 }; static char aln[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$@"; static char* let = &aln[10]; static char hex[] = "fedcbaFEDCBA9876543210"; static char* dec = &hex[12]; static char* oct = &hex[14]; void ppfsm __PARAM__((int op, register char* s), (op, s)) __OTORP__(int op; register char* s;) { register int c; register int n; register int i; register short* rp; register struct fsminit* fp; switch (op) { case 4: for (fp = fsminit;; fp++) { if ((n = fp->nextstate) >= (0+28)) n = ~n; if (fp->state == (-1)) break; rp = _pp_fsmtab[fp->state]; for (i = 0; i < sizeof(fp->ch) && (c = fp->ch[i]); i++) { switch (c) { case 023: for (c = 0; c <= 255; c++) rp[c] = n; /* FALLTHROUGH */ case 002: _pp_fsmtab[(0+28)][fp->state+1] = n < 0 ? ~n : n; continue; case 021: s = let; break; case 003: s = hex; break; case 001: s = dec; break; case 022: s = oct; break; default: rp[c] = n; continue; } while (c = *s++) rp[c] = n; } } for (i = 0; i < (0+28); i++) { rp = _pp_fsmtab[i]; s = spl; while (c = *s++) if (c != '@' || !(( rp)>=_pp_fsmtab[(0+13)]&&( rp)<=_pp_fsmtab[(0+18)])) { if (rp[c] >= 0) rp[c] = ~rp[c]; rp[c] &= ~(1<<7); } rp[0] = ~((0+28)+2); for (c = 0; c <= 255; c++) if (rp[c] == i) rp[c] = 0; } _pp_fsmtab[(0+28)][0] = ~((0+28)+2); break; } } extern __MANGLE__ long strkey __PROTO__((const char*)); typedef struct Key_s { const char* name; size_t size; int hit; int val; } Key_t; typedef struct Proto_s { int brace; int call; int fd; char* file; long flags; long options; char* package; int line; int test; char* tp; int iz; char* ib; char* ip; int oz; char* ob; char* op; char* ox; char cc[3]; char pushback[4]; char variadic[256]; } Proto_t; static const Key_t pragmas[] = { { "prototyped",sizeof( "prototyped")-1, 0x01, 1}, { "noprototyped",sizeof( "noprototyped")-1, 0x01, 0}, { "noticed",sizeof( "noticed")-1, 0x02, 1}, { "nonoticed",sizeof( "nonoticed")-1, 0x02, 0}, }; static const Key_t notices[] = { { "Copyright",sizeof( "Copyright")-1, 0x02, 1}, { "COPYRIGHT",sizeof( "COPYRIGHT")-1, 0x02, 1}, { "copyright",sizeof( "copyright")-1, 0x02, 1}, { "Public Domain",sizeof( "Public Domain")-1, 0x02, 0}, { "PUBLIC DOMAIN",sizeof( "PUBLIC DOMAIN")-1, 0x02, 0}, }; static char* number __PARAM__((register char* p, register long n), (p, n)) __OTORP__(register char* p; register long n;) { register long d; for (d = 1000000; d > 1; d /= 10) if (n >= d) *p++ = '0' + (n / d) % 10; *p++ = '0' + n % 10; return p; } static int errors; static int sstrlen __PARAM__((register const char* s), (s)) __OTORP__(register const char* s;) { register const char* b; for (b = s; *s; s++); return s - b; } static int sstrncmp __PARAM__((register const char* s, register const char* t, register int n), (s, t, n)) __OTORP__(register const char* s; register const char* t; register int n;) { register const char* e = s + n; while (s < e) { if (*s != *t || !*s) return *s - *t; s++; t++; } return 0; } static char* strcopy __PARAM__((register char* s, register const char* t), (s, t)) __OTORP__(register char* s; register const char* t;) { while (*s++ = *t++); return s - 1; } static void proto_error __PARAM__((char* iob, int level, char* msg, char* arg), (iob, level, msg, arg)) __OTORP__(char* iob; int level; char* msg; char* arg;) { register char* p; char buf[1024]; p = strcopy(buf, "proto: "); if (iob) { register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t)); if (proto->line) { if (proto->file) { *p++ = '"'; p = strcopy(p, proto->file); *p++ = '"'; *p++ = ','; *p++ = ' '; } p = strcopy(p, "line "); p = number(p, proto->line); } else if (proto->file) p = strcopy(p, proto->file); } else { p = strcopy(p, msg); msg = arg; arg = 0; } if (*(p - 1) != ' ') { *p++ = ':'; *p++ = ' '; } if (level == 1) p = strcopy(p, "warning: "); p = strcopy(p, msg); if (arg) { *p++ = ' '; p = strcopy(p, arg); } *p++ = '\n'; write(2, buf, p - buf); if (level >= 3) exit(level - 2); if (level >= 2) errors++; } static char* memcopy __PARAM__((register char* s, register char* t, int n), (s, t, n)) __OTORP__(register char* s; register char* t; int n;) { register char* e = t + n; while (t < e) *s++ = *t++; return s; } static char* linesync __PARAM__((register Proto_t* proto, register char* p, register long n), (proto, p, n)) __OTORP__(register Proto_t* proto; register char* p; register long n;) { if (proto->flags & (1L<<13)) { p = strcopy(p, "\n#line "); p = number(p, n); *p++ = '\n'; } return p; } static char* init __PARAM__((Proto_t* proto, char* op, int flags), (proto, op, flags)) __OTORP__(Proto_t* proto; char* op; int flags;) { register char* s; if (flags & (1L<<10)) { op = strcopy(op, "\ \n\ #if !defined(__PROTO__)\n\ # if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\ # if defined(__cplusplus)\n\ # define __LINKAGE__ \"C\"\n\ # else\n\ # define __LINKAGE__\n\ # endif\n\ # define __STDARG__\n\ # define __PROTO__(x) x\n\ # define __OTORP__(x)\n\ # define __PARAM__(n,o) n\n\ # if !defined(__STDC__) && !defined(__cplusplus)\n\ # if !defined(c_plusplus)\n\ # define const\n\ # endif\n\ # define signed\n\ # define void int\n\ # define volatile\n\ # define __V_ char\n\ # else\n\ # define __V_ void\n\ # endif\n\ # else\n\ # define __PROTO__(x) ()\n\ # define __OTORP__(x) x\n\ # define __PARAM__(n,o) o\n\ # define __LINKAGE__\n\ # define __V_ char\n\ # define const\n\ # define signed\n\ # define void int\n\ # define volatile\n\ # endif\n\ # define __MANGLE__ __LINKAGE__\n\ # if defined(__cplusplus) || defined(c_plusplus)\n\ # define __VARARG__ ...\n\ # else\n\ # define __VARARG__\n\ # endif\n\ # if defined(__STDARG__)\n\ # define __VA_START__(p,a) va_start(p,a)\n\ # else\n\ # define __VA_START__(p,a) va_start(p)\n\ # endif\n\ # if !defined(__INLINE__)\n\ # if defined(__cplusplus)\n\ # define __INLINE__ extern __MANGLE__ inline\n\ # else\n\ # if defined(_WIN32) && !defined(__GNUC__)\n\ # define __INLINE__ __inline\n\ # endif\n\ # endif\n\ # endif\n\ #endif\n\ #if !defined(__LINKAGE__)\n\ #define __LINKAGE__ /* 2004-08-11 transition */\n\ #endif\n\ "); } else op = strcopy(op, "\ \n\ #if !defined(__PROTO__)\n\ #include \n\ #endif\n\ #if !defined(__LINKAGE__)\n\ #define __LINKAGE__ /* 2004-08-11 transition */\n\ #endif\n\ "); if (proto->package) { s = "\ #ifndef __MANGLE_%_DATA__\n\ # ifdef _BLD_%\n\ # ifdef __EXPORT__\n\ # define __MANGLE_%_DATA__ __MANGLE__ __EXPORT__\n\ # else\n\ # define __MANGLE_%_DATA__ __MANGLE__\n\ # endif\n\ # define __MANGLE_%_FUNC__ __MANGLE__\n\ # else\n\ # ifdef __IMPORT__\n\ # define __MANGLE_%_DATA__ __MANGLE__ __IMPORT__\n\ # else\n\ # define __MANGLE_%_DATA__ __MANGLE__\n\ # endif\n\ # define __MANGLE_%_FUNC__ __MANGLE__\n\ # endif\n\ #endif\n\ "; for (;;) { switch (*op++ = *s++) { case 0: op--; break; case '%': op = strcopy(op - 1, proto->package); continue; default: continue; } break; } } return op; } static char* nns __PARAM__((register char* s), (s)) __OTORP__(register char* s;) { while (*s == ' ' || *s == '\t' || *s == '\n') s++; return s; } static int directive __PARAM__((register char* s, int dir), (s, dir)) __OTORP__(register char* s; int dir;) { switch (*(s = nns(s))) { case 'e': case 'i': dir <<= 2; switch (*++s) { case 'f': dir |= 01; break; case 'l': dir |= 02; break; case 'n': dir |= 03; break; } break; } return dir; } static int lex __PARAM__((register Proto_t* proto, register long flags), (proto, flags)) __OTORP__(register Proto_t* proto; register long flags;) { register char* ip; register char* op; register int c; register int state; register short* rp; char* m; char* e; char* t; char* bp; char* v; char* im; char* ko; char* aom; int n; int line; int quot; int brack; int sub; int x; int vc; char* ie = 0; char* om = 0; char* aim = 0; char* aie = 0; char* func = 0; int call = 0; int dir = 0; int group = 0; int last = 0; int paren = 0; char* qe = 0; int qn = 0; int args = 0; do{(ip=proto->ip);(op=proto->op);call=proto->call;}while(0); if (flags & (1L<<5)) (ko=op); fsm_start: proto->tp = ip; state = 0; bp = ip; do { rp = _pp_fsmtab[state]; fsm_get: while (!(state = rp[c = (*(unsigned char*)ip++)])); fsm_next: ; } while (state > 0); if ((n = ip - bp - 1) > 0) { ip = bp; do switch(n) { default: memcopy(op, ip, n); op += n; ip += n; break; case 7: *op++ = *ip++; /*FALLTHROUGH */ case 6: *op++ = *ip++; /*FALLTHROUGH */ case 5: *op++ = *ip++; /*FALLTHROUGH */ case 4: *op++ = *ip++; /*FALLTHROUGH */ case 3: *op++ = *ip++; /*FALLTHROUGH */ case 2: *op++ = *ip++; /*FALLTHROUGH */ case 1: *op++ = *ip++; /*FALLTHROUGH */ case 0: break; } while (0); ip++; } state = ~state; fsm_terminal: switch ((( state)&((1<<(7+1))-1))) { case ((0+28)+11): if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c) { case '+': case '-': case '*': case '&': (*op++=( ' ')); break; } (*op++=( c)); break; case ((0+28)+0): (ip--); c = (*(op-1)); break; case ((0+28)+1): switch (c) { case '\n': if ((( rp)>=_pp_fsmtab[(0+16)]&&( rp)<=_pp_fsmtab[(0+18)])) goto fsm_newline; (*op++=( c)); proto->line++; rp = _pp_fsmtab[(0+13)]; break; case '/': if ((flags & ((1L<<5)|(1L<<15))) == (1L<<5)) (op=ko); else (*op++=( c)); if ((( rp)>=_pp_fsmtab[(0+16)]&&( rp)<=_pp_fsmtab[(0+18)])) { rp = _pp_fsmtab[(0+16)]; break; } goto fsm_start; case (255+1): break; default: if ((flags & ((1L<<5)|(1L<<15))) == (1L<<5)) (op=ko); else (*op++=( c)); rp = _pp_fsmtab[(( rp)>=_pp_fsmtab[(0+16)]&&( rp)<=_pp_fsmtab[(0+18)]) ? (0+16) : (0+14)]; break; } bp = ip; goto fsm_get; case ((0+28)+2): if (c) { if (state = _pp_fsmtab[(0+28)][((( rp)-_pp_fsmtab[0])/(255+1))+1]) goto fsm_terminal; do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return 0; } (ip--); fsm_eob: if ((flags & ((1L<<1)|((1L<<16))|(1L<<21))) == ((1L<<16)) && (proto->flags & (1L<<16))) { if (!(flags & (1L<<5))) flags |= (1L<<24); c = ip - proto->ib; if (!(flags & (1L<<15))) im = proto->tp; if (ip > proto->ib) { n = ip - im; if (ip - n < proto->ib) proto->flags |= (1L<<4); memcopy(proto->ib - n, ip - n, n); ip = proto->ib; } proto->tp -= c; if (flags & (1L<<15)) { im -= c; ie -= c; } if (aim) aim -= c; if (aie) aie -= c; if ((n = read(proto->fd, ip, proto->iz)) > 0) { if ((proto->options & (1L<<0)) && n < proto->iz) { proto->flags &= ~(1L<<16); close(proto->fd); } *(ip + n) = 0; if (state & (1<<7)) goto fsm_splice; bp = ip; goto fsm_get; } *ip = 0; proto->flags &= ~(1L<<16); close(proto->fd); } if (state & (1<<7)) goto fsm_splice; if (!(flags & (1L<<21)) && (state = rp[c = (255+1)])) { bp = ip; goto fsm_next; } do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return 0; case ((0+28)+3): quot = c; if (c == '"' && qe) { for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++); if (t == op) { op = qe; qe = 0; qn = n; } else (*op++=( c)); } else (*op++=( c)); rp = _pp_fsmtab[(0+21)]; bp = ip; goto fsm_get; case ((0+28)+4): if (c == quot) { if (!(flags & (1L<<3))) qe = (c == '"') ? op : (char*)0; (*op++=( c)); while (qn > 0) { qn--; (*op++=( '\n')); } } else if (c != '\n' && c != (255+1)) { (*op++=( c)); bp = ip; goto fsm_get; } else { while (qn > 0) { qn--; (*op++=( '\n')); } (ip--); } c = (0401+1); break; case ((0+28)+5): if (flags & (1L<<0)) (*op++=( c)); else switch (c) { case 'a': n = (('A'==0301)?0057:0007); goto fsm_oct; case 'E': n = (('A'==0301)?0047:0033); goto fsm_oct; case 'v': n = 0013; goto fsm_oct; case 'x': do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); lex(proto, (flags & ((1L<<16))) | (1L<<21)); for (n = x = 0; (c = (*(unsigned char*)ip++)), x < 3; x++) switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = (n << 4) + c - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': n = (n << 4) + c - 'a' + 10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': n = (n << 4) + c - 'A' + 10; break; default: goto fsm_hex; } fsm_hex: (ip--); fsm_oct: (*op++=( ((n >> 6) & 07) + '0')); (*op++=( ((n >> 3) & 07) + '0')); (*op++=( (n & 07) + '0')); break; default: (*op++=( c)); break; } rp = _pp_fsmtab[(0+21)]; bp = ip; goto fsm_get; case ((0+28)+6): (ip--); if ((flags & (1L<<5)) && *proto->tp == 's' && !sstrncmp( proto->tp, "static", 6)) { c = ((0500+4)+9); break; } if (*proto->tp == '_' && !sstrncmp( proto->tp, "__STDPP__directive", 6)) c = '#'; else c = (0401+0); break; case ((0+28)+7): fsm_newline: proto->line++; if (flags & (1L<<5)) { if (op != proto->ob && (*(op-1)) != ' ' && (*(op-1)) != '\n') (*op++=( ' ')); } else (*op++=( c)); if (flags & (1L<<3)) { if (flags & (1L<<0)) { if (flags & (1L<<5)) (op=ko); if (flags & (1L<<12)) { *(ip - 1) = 0; op = strcopy(om, "/* "); op = strcopy(op, im); op = strcopy(op, " */\n"); } flags &= ~((1L<<2)|(1L<<3)|(1L<<7)|(1L<<8)|(1L<<12)|(1L<<15)|(1L<<22)|(1L<<26)); } else { if ((flags & ((1L<<2)|(1L<<22))) == ((1L<<2)|(1L<<22))) { *(ip - 1) = 0; op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n"); op = strcopy(op, im); op = strcopy(op, "\n#else\n"); bp = ip; ip = im; *op++ = *ip++; while (*op = *ip++) if (*op++ == '#' && *ip != '(') { op--; while (*--op == ' ' || *op == '\t'); if (*ip == '#') { op = strcopy(op + 1, "/**/"); while (*++ip == ' ' || *ip == '\t'); } else { if (*op != '"') *++op = '"'; op++; while (*ip == ' ' || *ip == '\t') ip++; while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++; while (*ip == ' ' || *ip == '\t') ip++; if (*ip == '"') ip++; else *op++ = '"'; } } ip = bp; op = strcopy(op, "\n#endif\n"); op = linesync(proto, op, proto->line); } flags &= ~((1L<<2)|(1L<<3)|(1L<<7)|(1L<<8)|(1L<<15)|(1L<<17)|(1L<<22)|(1L<<23)|(1L<<25)|(1L<<26)); } call = 0; group = 0; paren = 0; last = '\n'; } if (paren == 0 && (flags & ((1L<<15)|(1L<<21)|(1L<<23)|(1L<<24))) == (1L<<24)) { if (flags & (1L<<5)) (op=ko); do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return 0; } goto fsm_start; case ((0+28)+8): (*op++=( c)); rp = _pp_fsmtab[((( state)>>(7+1))&((1<<7)-1))]; bp = ip; goto fsm_get; case ((0+28)+13): (*op++=( c)); c = (((( state)>>(7+1))&((1<<7)-1))+0401); break; case ((0+28)+14): (ip--); c = (((( state)>>(7+1))&((1<<7)-1))+0401); break; case (((0+28)+12)): (ip--); c = (0401+0); if (!(flags & (1L<<1))) switch (((((long)( *proto->tp))<<16)|(((long)( *(ip - 1)))<<8)|((long)( ip - proto->tp)))) { case ((((long)( 'N'))<<16)|(((long)( 'N'))<<8)|((long)( 3))): if (proto->tp[1] == 'o') c = ((0500+4)+6); break; case ((((long)( 'd'))<<16)|(((long)( 'o'))<<8)|((long)( 2))): c = ((0500+4)+6); break; case ((((long)( 'e'))<<16)|(((long)( 'e'))<<8)|((long)( 4))): if (!(flags & (1L<<21)) && (flags & ((1L<<3)|(1L<<25))) != (1L<<3) && !sstrncmp( proto->tp, "else", 4)) { c = ((0500+4)+8); goto fsm_id; } break; case ((((long)( 'e'))<<16)|(((long)( 'n'))<<8)|((long)( 6))): if (!sstrncmp( proto->tp, "extern", 6)) c = ((0500+4)+9); break; case ((((long)( 'f'))<<16)|(((long)( 'r'))<<8)|((long)( 3))): if (!(flags & (1L<<21)) && !sstrncmp( proto->tp, "for", 3)) { c = ((0500+4)+11); goto fsm_id; } break; case ((((long)( 'i'))<<16)|(((long)( 'f'))<<8)|((long)( 2))): c = ((0500+4)+13); break; case ((((long)( 'i'))<<16)|(((long)( 'e'))<<8)|((long)( 6))): if (!sstrncmp( proto->tp, "inline", 6) && !(flags & ((1L<<15)|(1L<<23)|(1L<<25)|(1L<<26))) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0)) { flags |= (1L<<23); do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); line = proto->line; op = strcopy(op - 6, "__INLINE__"); do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); } break; case ((((long)( 'r'))<<16)|(((long)( 'n'))<<8)|((long)( 6))): if (!(flags & (1L<<21)) && !sstrncmp( proto->tp, "return", 6)) { c = ((0500+4)+17); goto fsm_id; } break; case ((((long)( 's'))<<16)|(((long)( 'c'))<<8)|((long)( 6))): if ((proto->options & (1L<<6)) && !sstrncmp( proto->tp, "static", 6)) { proto->ox = op - 6; flags |= (1L<<6); } break; case ((((long)( 't'))<<16)|(((long)( 'f'))<<8)|((long)( 7))): if (!(flags & (1L<<21)) && !sstrncmp( proto->tp, "typedef", 7)) { flags |= (1L<<26); c = ((0500+4)+9); } break; case ((((long)( 'v'))<<16)|(((long)( 't'))<<8)|((long)( 8))): if (*ip == '(' && !sstrncmp( proto->tp, "va_start", 8)) c = (0500+1); break; case ((((long)( 'v'))<<16)|(((long)( 'd'))<<8)|((long)( 4))): if (!sstrncmp( proto->tp, "void", 4)) { if (flags & ((1L<<0)|(1L<<19)|(1L<<10)|(1L<<11))) c = ((0500+4)+30); else { do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); line = proto->line; if (lex(proto, (flags & ((1L<<16))) | (1L<<21)) == '*') { memcopy(op - 4, "__V_", 4); memcopy(ip - 4, "__V_", 4); } else c = ((0500+4)+30); proto->line = line; do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); bp = ip; } } break; case ((((long)( 'w'))<<16)|(((long)( 'e'))<<8)|((long)( 5))): if (!(flags & (1L<<21)) && !sstrncmp( proto->tp, "while", 5)) { c = ((0500+4)+26); goto fsm_id; } break; } if ((flags & (1L<<0)) && c != ((0500+4)+9)) c = (0401+0); break; case ((0+28)+10): goto fsm_start; case ((0+28)+15): (ip--); if ((flags & ((1L<<5)|(1L<<15))) == (1L<<5)) { while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t')) op--; if (op > proto->ob && *(op - 1) != '\n') *op++ = ' '; } goto fsm_start; default: if (state & (1<<7)) { if (c == '\\') { if (!(n = (*(unsigned char*)ip++))) { goto fsm_eob; fsm_splice: c = '\\'; n = (*(unsigned char*)ip++); } if (n == '\n') { proto->line++; (*op++=( '\\')); (*op++=( '\n')); bp = ip; goto fsm_get; } (ip--); } state &= ~(1<<7); if (state >= (0+28)) goto fsm_terminal; rp = _pp_fsmtab[state]; } (*op++=( c)); bp = ip; goto fsm_get; } if (!(flags & ((1L<<10)|(1L<<11)|(1L<<21)))) { if (!(flags & (1L<<3))) switch (c) { case '(': if (!(flags & (1L<<0)) || proto->brace == 0) { if (paren++ == 0) { if (!(flags & (1L<<0)) || group <= 1) { args = 0; if (group++ == 0) group++; else if (flags & (1L<<8)) call++; flags |= (1L<<15); im = ip - 1; om = op - 1; } sub = 0; } else if (paren == 2 && !aim) { sub++; if (last == '(') { flags &= ~(1L<<15); om = 0; } else if (flags & (1L<<8)) { aim = ip - 1; aom = op - 1; } else if ((flags & ((1L<<15)|(1L<<25))) == (1L<<15)) { for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--); if (m != im && sub == 1) { m = im + (*nns(ip) == '*'); } if (m == im) { flags &= ~(1L<<15); om = 0; } } else if ((flags & (1L<<15)) && sub == 1 && *nns(ip) != '*') { flags &= ~(1L<<15); om = 0; } } flags &= ~(1L<<25); } break; case ')': if (!(flags & (1L<<0)) || proto->brace == 0) if (--paren == 0) { if (flags & (1L<<0)) { if (group != 2) { c = (0401+0); break; } group++; } ie = ip; } else if (paren == 1 && (flags & (1L<<8)) && !aie) aie = ip; break; case '*': if (last == '(' && group == 2) { group--; if (paren == 1) { flags |= (1L<<8); aim = aie = 0; } } break; case '#': dir = directive(ip, dir); if (proto->brace == 0 && paren == 0 && last != '=' && (flags & ((1L<<0)|(1L<<1)|(1L<<3)|(1L<<15)|(1L<<19)|(1L<<23)|(1L<<25))) == ((1L<<15)|(1L<<25)) && ((dir & 03) != 03 || ((dir>>2) & 03) != 01)) flags |= (1L<<3); else if (!(flags & ((1L<<1)|(1L<<3)))) { flags |= (1L<<3); if (!(flags & (1L<<19))) { bp = ip; while (*ip == ' ' || *ip == '\t') ip++; if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e') { if (*++ip == ' ' || *ip == '\t') { proto->line = 0; while (*++ip >= '0' && *ip <= '9') proto->line = proto->line * 10 + *ip - '0'; proto->line--; } } else if ((flags & ((1L<<0)|(1L<<5))) == (1L<<0)) { n = 0; t = ip + 6; while (ip < t && *ip >= 'a' && *ip <= 'z') n = ((( n)<<5)+(( *ip++)-('a'-1))); switch (n) { case ((( ((( ((( (( 'e')-('a'-1)))<<5)+(( 'l')-('a'-1))))<<5)+(( 's')-('a'-1))))<<5)+(( 'e')-('a'-1))): case ((( ((( ((( ((( (( 'e')-('a'-1)))<<5)+(( 'n')-('a'-1))))<<5)+(( 'd')-('a'-1))))<<5)+(( 'i')-('a'-1))))<<5)+(( 'f')-('a'-1))): while (*ip == ' ' || *ip == '\t') ip++; if (*ip != '\n' && *ip != '/' && *(ip + 1) != '*') { flags |= (1L<<12)|(1L<<15); im = ip; om = op + (ip - bp); } break; case ((( ((( ((( (( 'e')-('a'-1)))<<5)+(( 'l')-('a'-1))))<<5)+(( 'i')-('a'-1))))<<5)+(( 'f')-('a'-1))): case ((( ((( ((( ((( (( 'e')-('a'-1)))<<5)+(( 'r')-('a'-1))))<<5)+(( 'r')-('a'-1))))<<5)+(( 'o')-('a'-1))))<<5)+(( 'r')-('a'-1))): case ((( (( 'i')-('a'-1)))<<5)+(( 'f')-('a'-1))): case ((( ((( ((( ((( (( 'i')-('a'-1)))<<5)+(( 'f')-('a'-1))))<<5)+(( 'd')-('a'-1))))<<5)+(( 'e')-('a'-1))))<<5)+(( 'f')-('a'-1))): case ((( ((( ((( ((( ((( (( 'i')-('a'-1)))<<5)+(( 'f')-('a'-1))))<<5)+(( 'n')-('a'-1))))<<5)+(( 'd')-('a'-1))))<<5)+(( 'e')-('a'-1))))<<5)+(( 'f')-('a'-1))): case ((( ((( ((( ((( (( 'u')-('a'-1)))<<5)+(( 'n')-('a'-1))))<<5)+(( 'd')-('a'-1))))<<5)+(( 'e')-('a'-1))))<<5)+(( 'f')-('a'-1))): break; case ((( ((( ((( ((( ((( (( 'i')-('a'-1)))<<5)+(( 'n')-('a'-1))))<<5)+(( 'c')-('a'-1))))<<5)+(( 'l')-('a'-1))))<<5)+(( 'u')-('a'-1))))<<5)+(( 'd')-('a'-1))): if (*ip == 'e') ip++; /* FALLTHROUGH */ case ((( ((( ((( ((( ((( (( 'd')-('a'-1)))<<5)+(( 'e')-('a'-1))))<<5)+(( 'f')-('a'-1))))<<5)+(( 'i')-('a'-1))))<<5)+(( 'n')-('a'-1))))<<5)+(( 'e')-('a'-1))): case ((( ((( ((( ((( ((( (( 'p')-('a'-1)))<<5)+(( 'r')-('a'-1))))<<5)+(( 'a')-('a'-1))))<<5)+(( 'g')-('a'-1))))<<5)+(( 'm')-('a'-1))))<<5)+(( 'a')-('a'-1))): if (*ip < 'a' || *ip > 'z') break; /* FALLTHROUGH */ default: flags |= (1L<<12)|(1L<<15); im = bp - 1; om = op - 1; break; } } else { if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e') { while (*++ip == ' ' || *ip == '\t'); if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>') { op = strcopy(op, "\ if !defined(va_start)\n\ #if defined(__STDARG__)\n\ #include \n\ #else\n\ #include \n\ #endif\n\ #endif\n\ "); op = linesync(proto, op, proto->line); break; } } else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t')) { while (*++ip == ' ' || *ip == '\t'); if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t')) { t = ip; while (*++t == ' ' || *t == '\t'); if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r')) ip = t; t = ip; while (*++t == ' ' || *t == '\t'); if (*t == '_' && *(t + 1) == '_') { op = strcopy(op, "undef __MANGLE__\n"); op = linesync(proto, op, proto->line); op = strcopy(op, "#define __MANGLE__ __LINKAGE__"); break; } } flags |= (1L<<2)|(1L<<15); im = bp - 1; om = op - 1; } else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t')) { while (*++ip == ' ' || *ip == '\t'); if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r')) { op = strcopy(op, "undef __MANGLE__\n"); op = linesync(proto, op, proto->line); op = strcopy(op, "#define __MANGLE__ __LINKAGE__"); break; } flags |= (1L<<2)|(1L<<15); im = bp - 1; om = op - 1; } } ip = bp; } break; } else break; case '{': if (proto->brace++ == 0 && paren == 0) { if (last == '=') flags |= (1L<<9); else if (flags & (1L<<0)) { if ((flags & ((1L<<15)|(1L<<17)|(1L<<23))) == (1L<<15)) { if (args) { v = number(op, args < 0 ? -args : args); v = strcopy(v, " argument actual/formal mismatch"); *v++ = ' '; v = memcopy(v, im, ie - im); *v = 0; proto_error((char*)proto + sizeof(Proto_t), 2, op, ((char*)0)); } ip--; v = ie; while (ie < ip) if (*ie++ == '/' && *ie == '*') { e = ie - 1; while (++ie < ip) { if (*ie == '*') { while (ie < ip && *ie == '*') ie++; if (ie < ip && *ie == '/') { while (++ie < ip && (*ie == ' ' || *ie == '\t')); while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--; if (e > v && *e != '\n') *e++ = ' '; t = ie; while (--e >= v) *--t = *e; v = t; break; } } } } ie = v; op = om++; if (flags & (1L<<5)) { v = op; while (v > ko && *--v != ' '); if (*v != ' ') { om = (v = (op += 4)) + 1; while (v >= ko + 4) { *v = *(v - 4); v--; } memcopy(ko, "int ", 4); } if (*v == ' ') { while (*(v + 1) == '*') *v++ = '*'; *v = '\t'; if ((v - ko) <= 8) { om = (e = ++op) + 1; while (e > v) { *e = *(e - 1); e--; } } } om = (v = (op += 7)) + 1; while (v >= ko + 7) { *v = *(v - 7); v--; } memcopy(ko, "extern ", 7); } (*op++=( '(')); t = op; e = 0; while (ie < ip) { if ((c = *ie) == ' ' || c == '\t' || c == '\n') { while ((c = *++ie) == ' ' || c == '\t' || c == '\n'); if (ie >= ip) break; if (c != '*' && op > om) (*op++=( ' ')); } if ((n = ((c = *ie) == ',')) || c == ';') { if (flags & (1L<<5)) { m = op; while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']')) op--; v = op; while (op > om && (c = *(op - 1)) != ' ' && c != '*') op--; while (*(op - 1) == ' ') op--; if (!e) { e = op; while (e > om && *(e - 1) == '*') e--; } if (op <= om) op = strcopy(op, "int"); else if (*(op - 1) == ',') op = strcopy(op, " int"); while (v < m) (*op++=( *v++)); } (*op++=( ',')); if (n) { if (x = !e) e = op - 1; (*op++=( ' ')); m = t; while (m < e) (*op++=( *m++)); if (x) { m = e; while (*--e != ' '); while (*(e - 1) == '*') e--; op -= m - e; } } while ((c = *++ie) == ' ' || c == '\t' || c == '\n'); if (ie >= ip) (op--); else (*op++=( ' ')); if (!n) { t = op; e = 0; } } else if (*ie == '*') { if (op > om && (c = *(op - 1)) == ' ') op--; while (*ie == '*') (*op++=( *ie++)); while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; if (c != '(') (*op++=( ' ')); } else if (*ie == '(') { if (op > om && *(op - 1) == ' ') op--; (*op++=( *ie++)); while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; } else if (*ie == ')') { if (op > om && *(op - 1) == '(') proto_error((char*)proto + sizeof(Proto_t), 1, "function pointer argument prototype omitted", ((char*)0)); (*op++=( *ie++)); while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++; } else if ((flags & (1L<<5)) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !sstrncmp( ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n')) { ie += 8; if (op > om) (op--); } else (*op++=( *ie++)); } if (op <= om) op = strcopy(op, "void"); (*op++=( ')')); if (flags & (1L<<5)) { (*op++=( ';')); (*op++=( '\n')); (proto->op=op); (ko=op); } else { (*op++=( '\n')); (*op++=( *ip)); } ip++; flags &= ~((1L<<15)|(1L<<23)); } } else if ((flags & ((1L<<15)|(1L<<19)|(1L<<23)|(1L<<25))) == ((1L<<15)|(1L<<25))) { line = proto->line; op = strcopy(om, " __PARAM__("); op = memcopy(op, im, ie - im); (*op++=( ',')); (*op++=( ' ')); (*op++=( '(')); flags &= ~((1L<<15)|(1L<<23)); if (flags & (1L<<27)) { if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic); memcopy(proto->variadic, im, vc); op = strcopy(op, "va_alist)) __OTORP__(va_dcl)\n{"); } else { flags |= (1L<<23); proto->ip = im; proto->op = op; group = 0; brack = 0; for (;;) { switch (lex(proto, (flags & ((1L<<16))) | (1L<<21))) { case '[': brack++; continue; case ']': brack--; continue; case '(': if (paren++) group++; continue; case ')': if (--paren == 0) { group = 0; if (flags & (1L<<15)) { flags &= ~((1L<<15)|(1L<<23)); op = memcopy(op, m, e - m); } break; } continue; case ',': if (paren == 1) { group = 0; if (flags & (1L<<15)) { flags &= ~((1L<<15)|(1L<<23)); op = memcopy(op, m, e - m); } (*op++=( ',')); (*op++=( ' ')); proto->op = op; } continue; case (0401+0): if (group <= 1 && !brack) { flags |= (1L<<15); m = proto->tp; e = proto->ip; } continue; default: continue; } break; } (*op++=( ')')); (*op++=( ')')); } if (!(flags & (1L<<23))) { flags |= (1L<<23); proto->op = strcopy(op, " __OTORP__("); proto->ip = im + 1; n = *(ie - 1); *(ie - 1) = ';'; c = *ie; *ie = 0; lex(proto, (flags & ((1L<<16))) | (1L<<1)); *(ie - 1) = n; *ie = c; proto->ip = ie; op = proto->op; (*op++=( ')')); } if (flags & (1L<<6)) memcopy( proto->ox, "extern", 6); op = linesync(proto, op, proto->line = line); if (flags & (1L<<3)) { proto->brace = 0; (*op++=( '\n')); (*op++=( '#')); } else if (!(flags & (1L<<27))) (*op++=( '{')); } } flags &= ~((1L<<7)|(1L<<8)|(1L<<15)|(1L<<17)|(1L<<23)); call = 0; group = 0; break; case '}': flags &= ~((1L<<7)|(1L<<8)|(1L<<15)|(1L<<17)|(1L<<23)|(1L<<25)); if (--proto->brace == 0) { flags &= ~((1L<<9)|(1L<<27)|(1L<<28)); if (flags & (1L<<5)) (op=ko); } call = 0; group = 0; paren = 0; break; case '=': if (last == '?') flags |= (1L<<3); else if (paren == 0 && (flags & ((1L<<9)|(1L<<15)|(1L<<23))) == (1L<<15)) { if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= (1L<<23); else goto fsm_statement; } goto fsm_other; case ',': if (flags & (1L<<0)) { if (paren == 1) args++; else { args--; flags &= ~(1L<<15); } break; } if (paren == 0 && (flags & (1L<<1))) *(op - 1) = c = ';'; case ';': fsm_statement: if (flags & (1L<<9)) ; else if (flags & (1L<<0)) { if (paren == 0) { if ((flags & (1L<<15)) && last == ')') flags &= ~(1L<<15); if (!(flags & (1L<<15))) { call = 0; group = 0; flags &= ~(1L<<23); if (flags & (1L<<5)) (op=ko); if (flags & (1L<<24)) { do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return 0; } } else { args--; if ((flags & ((1L<<5)|(1L<<23))) == ((1L<<5)|(1L<<23))) (op=ko); } } } else if (paren == 0) { if ((flags & ((1L<<15)|(1L<<17)|(1L<<23))) == (1L<<15) && call > 1) { if ((flags & (1L<<14)) && func) { func[0] = 'F'; func[1] = 'U'; func[2] = 'N'; func[3] = 'C'; func = 0; } if ((flags & ((1L<<1)|(1L<<8))) == (1L<<8) && aim && aie < im) { while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++; v = aim; while (v < aie) if (*v++ == ')') break; while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++; if (v == aie || !(flags & (1L<<20))) { if (flags & (1L<<20)) n = 3; else if (v == aie && *v == '(') n = 10; else n = 11; ko = op; om += n; v = op += n; while (v >= ko + n) { *v = *(v - n); v--; } if (flags & (1L<<20)) memcopy(aom, "(...))", 6); else if (n == 10) memcopy(aom, "(__VARARG__))", 13); else { ko = strcopy(aom, " __PROTO__("); ko = memcopy(ko, aim, aie - aim); *ko = ')'; if (++ko >= om) { *ko++ = ')'; om = ko; } } } } else if (flags & (1L<<26)) { op = om; while (*--op == ' ' || *op == '\t' || *op == '\n'); if (*op != ')') { op = om += 14; *--op = ')'; while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_') *--op = x; memcopy(op - 13, "(__OTORP__(*)", 13); } } if (flags & (1L<<17)) ; else if (flags & (1L<<20)) { op = om; if (!(flags & (1L<<25))) op = strcopy(op, "(...)"); else op = memcopy(op, im, ie - im); (*op++=( c)); } else { if (flags & (1L<<1)) op = strcopy(om, "()"); else if (!(flags & (1L<<25))) op = strcopy(om, "(__VARARG__)"); else { op = strcopy(om, " __PROTO__("); op = memcopy(op, im, ie - im); (*op++=( ')')); } if (flags & (1L<<6)) memcopy( proto->ox, "extern", 6); (*op++=( c)); } flags &= ~((1L<<15)|(1L<<27)|(1L<<28)); if (c == ',' && !(flags & (1L<<8))) { call = 1; group = 0; break; } } else if (flags & ((1L<<17)|(1L<<23))) call = 0; if (c == ';') { flags &= ~((1L<<6)|(1L<<14)|(1L<<25)|(1L<<26)); call = 0; if (flags & (1L<<24)) { do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return 0; } } else call = call > 1 && c == ','; group = 0; flags &= ~((1L<<7)|(1L<<8)|(1L<<15)|(1L<<17)|(1L<<23)); } else if (paren == 1 && group == 1 && !(flags & ((1L<<7)|(1L<<14)))) flags |= (1L<<25)|(1L<<17); break; case ((0500+4)+6): case ((0500+4)+13): flags |= (1L<<25)|(1L<<23); break; case ((0500+4)+9): if (flags & (1L<<0)) { if (proto->brace == 0) flags |= (1L<<23); } else if (paren == 0 && !(flags & (1L<<26))) { flags |= (1L<<14); if (!(flags & (1L<<19)) || proto->package) { op = strcopy(op, " __MANGLE__"); if (proto->package) { op = strcopy(op - 1, proto->package); func = op + 1; op = strcopy(op, "_DATA__"); } } else func = 0; } break; case (0401+29): if (paren == 0 && (flags & ((1L<<1)|(1L<<27))) == (1L<<1)) { op -= 3; do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return c; } if (paren == 1 && !(flags & (1L<<23))) flags |= (1L<<27); flags |= (1L<<25); break; case ((0500+4)+30): goto fsm_id; case (0500+1): if ((flags & ((1L<<19)|(1L<<27))) == (1L<<27)) { flags &= ~(1L<<15); line = proto->line; op = strcopy(op - 8, "__VA_START__"); do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); for (;;) { switch (lex(proto, (flags & ((1L<<16))) | (1L<<21))) { case 0: case ';': break; case (0401+0): if (!(flags & (1L<<15))) { flags |= (1L<<15); m = proto->tp; e = proto->ip; } continue; default: continue; } break; } do{(ip=proto->ip);(op=proto->op);call=proto->call;}while(0); if (flags & (1L<<15)) { v = m; n = e - m; } else { v = "ap"; n = 2; } op = strcopy(op, " __OTORP__("); proto->ip = proto->variadic; proto->op = op; flags &= ~(1L<<15); group = 0; bp = proto->ip + 1; if (*bp == 'r' && !sstrncmp( bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9; for (;;) { switch (lex(proto, (flags & ((1L<<16))) | (1L<<21))) { case '(': if (paren++) group++; continue; case ')': if (--paren == 0) { if (flags & (1L<<15)) { flags &= ~(1L<<15); if (!(flags & (1L<<28))) { op = memcopy(op, m, e - m); op = strcopy(op, " = "); } op = strcopy(op, "va_arg("); op = memcopy(op, v, n); (*op++=( ',')); (*op++=( ' ')); if (m > bp) op = memcopy(op, bp, m - bp); else op = strcopy(op, "int "); if (group > 1) op = strcopy(op, ")()"); else op = memcopy(op, e, proto->ip - e - 1); (*op++=( ')')); (*op++=( ';')); } group = 0; break; } continue; case ',': if (paren == 1) { if (flags & (1L<<15)) { flags &= ~(1L<<15); if (!(flags & (1L<<28))) { op = memcopy(op, m, e - m); op = strcopy(op, " = "); } op = strcopy(op, "va_arg("); op = memcopy(op, v, n); (*op++=( ',')); (*op++=( ' ')); if (m > bp) op = memcopy(op, bp, m - bp); else op = strcopy(op, "int "); if (group > 1) op = strcopy(op, ")()"); else op = memcopy(op, e, proto->ip - e - 1); (*op++=( ')')); (*op++=( ';')); bp = proto->ip + 1; if (*bp == 'r' && !sstrncmp( bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9; } group = 0; proto->op = op; } continue; case (0401+0): if (group <= 1) { flags |= (1L<<15); m = proto->tp; e = proto->ip; } continue; default: continue; } break; } op = strcopy(op, ")"); flags |= (1L<<28); proto->line = line; call = 0; break; } /* FALLTHROUGH */ case (0401+0): fsm_id: if (flags & (1L<<0)) { if (!args && paren == 1) args++; break; } if (paren == 0) { if (last == ')') { if (proto->brace == 0 && !(flags & (1L<<1))) flags |= (1L<<23); call = !call; } else if ((flags & (1L<<23)) || c == (0401+0) || c == ((0500+4)+30)) call++; else flags |= (1L<<23); if (last == (0401+0)) flags |= (1L<<7); } c = (0401+0); flags |= (1L<<25); break; case (0401+1): if (*proto->tp >= '0' && *proto->tp <= '9') { n = 0; for (;; op--) { switch (*(op - 1)) { case 'f': case 'F': t = op; while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); if (*t == '.') op--; n = 0; break; case 'l': case 'L': if (!(n & 01)) { n |= 01; t = op; while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); if (*t == '.') { n = 0; op--; break; } } continue; case 'u': case 'U': n |= 02; continue; } break; } if (n & 01) *op++ = 'L'; if (n & 02) { m = op; t = op = m + 10; while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') *--t = c; c = *t; strcopy(m + 1, "(unsigned)"); *t = c; break; } } goto fsm_other; case '[': if ((flags & (1L<<0)) && paren == 0 && group <= 2) flags |= (1L<<23); default: fsm_other: if (flags & (1L<<0)) break; flags |= (1L<<25); if (paren == 0) flags |= (1L<<17); break; } else if (c == '#' && *ip != '(') flags |= (1L<<22); last = c; if ((flags & ((1L<<5)|(1L<<15))) == ((1L<<5)|(1L<<15)) && ((flags & ((1L<<3)|(1L<<23))) || proto->brace || c != '(' && c != ')' && c != '*' && c != (0401+0))) (op=proto->op); else (proto->op=op); goto fsm_start; } else if (flags & ((1L<<10)|(1L<<11))) { if ((flags & (1L<<29)) && c == '%' && *ip == '{') t = 0; else { if (c == '#') { for (t = ip; *t == ' ' || *t == '\t'; t++); if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f') { t = 0; } } else t = ""; } if (t) { n = ip - proto->tp; ip -= n; op -= n; } else while (*ip != '\n') *op++ = *ip++; op = init(proto, op, flags); op = linesync(proto, op, proto->line); flags &= ~((1L<<10)|(1L<<11)); proto->flags &= ~((1L<<10)|(1L<<11)); goto fsm_start; } do{(proto->ip=ip);(proto->op=op);proto->flags&=~((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->flags|=flags&((1L<<5)|(1L<<9)|(1L<<17)|(1L<<27)|(1L<<28));proto->call=call;}while(0); return c; } void pppclose __PARAM__((char* iob), (iob)) __OTORP__(char* iob;) { register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t)); if (proto->flags & (1L<<16)) close(proto->fd); free((char*)proto); } char* pppopen __PARAM__((char* file, int fd, char* package, char* comment, int flags), (file, fd, package, comment, flags)) __OTORP__(char* file; int fd; char* package; char* comment; int flags;) { register Proto_t* proto; register char* iob; register long n; register char* s; char* t; int pragma; int clr; int hit; int i; int z; char* b; char com[80]; int m = 0; static int retain; if (flags & (1<<0)) flags &= ~(1<<5); if (flags & (1<<11)) flags &= ~retain; else retain &= (1<<6); if (file && (fd = open(file, O_RDONLY)) < 0) return 0; { n = (16*1024); if (!(proto = (( 0)?( Proto_t*)realloc((char*)( 0),sizeof( Proto_t)*( 1)+( 5 * n + 2)):( Proto_t*)calloc(1,sizeof( Proto_t)*( 1)+( 5 * n + 2))))) return 0; proto->iz = n; proto->oz = 3 * n; proto->flags |= (1L<<16); } proto->fd = fd; proto->package = package; iob = (char*)proto + sizeof(Proto_t); proto->op = proto->ob = iob; proto->ip = proto->ib = iob + proto->oz + n; if (m) proto->options |= (1L<<0); if (!comment) comment = "/*"; else if (comment[1]) { proto->cc[1] = comment[1]; proto->cc[2] = comment[2] ? comment[2] : comment[0]; } else proto->cc[1] = proto->cc[2] = comment[0]; n = read(fd, proto->ip, proto->iz); if (!(proto->flags & (1L<<16))) close(fd); if (n < 0) { pppclose(iob); return 0; } *(proto->ip + n) = 0; /* license comment */ *com = 0; hit = 0x02; pragma = -1; s = proto->ip; m = 80; while (m-- > 0 && *s && hit != (0x01|0x02)) { while (*s == ' ' || *s == '\t') s++; if (*s == '#') { b = s++; while (*s == ' ' || *s == '\t') s++; if (*s == *"pragma"&& !sstrncmp( s, "pragma", sizeof("pragma") - 1) && (*(s += sizeof("pragma") - 1) == ' ' || *s == '\t')) { clr = 0; while (*s && *s != '\r' && *s != '\n') { for (; *s == ' ' || *s == '\t'; s++); for (t = s; *s && *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n'; s++); z = s - t; for (i = 0; i < (sizeof( pragmas)/sizeof( pragmas[0])); i++) if (pragmas[i].size == z && !sstrncmp( t, pragmas[i].name, z)) { clr = 1; hit |= pragmas[i].hit; switch (pragmas[i].hit) { case 0x01: pragma = pragmas[i].val; break; } } } if (clr) { if (!(flags & (1<<1)) || (flags & (1<<8))) for (; b < s; *b++ = ' '); } } } else if (*s == *"/* : : generated by proto : : */\n"&& !sstrncmp( s, "/* : : generated by proto : : */\n", sizeof("/* : : generated by proto : : */\n") - 1)) { pragma = 0; break; } else if (*s == '%' && *(s + 1) == '{') proto->flags |= (1L<<29); while (*s && *s++ != '\n') ; } if (flags & (1<<10)) proto->flags |= (1L<<20); if (flags & (1<<12)) proto->test = 1; if (flags & (1<<2)) proto->options |= (1L<<6); if (flags & (1<<0)) pragma = -pragma; if (flags & (1<<1)) pragma = 0; if (flags & (1<<7)) proto->flags |= (1L<<13); if (!(proto->flags & (1L<<29)) && file && (m = sstrlen( file)) > 2 && file[--m] == 'y' && file[--m] == '.') proto->flags |= (1L<<29); if (pragma <= 0) { if (flags & (1<<10)) { flags &= ~((1<<4)|(1<<5)); proto->flags |= (1L<<19); } else if (!(flags & ((1<<3)|(1<<9)))) { pppclose(iob); return 0; } else if ((flags & ((1<<3)|(1<<9))) == (1<<9) || !pragma) { proto->flags |= (1L<<18); if (proto->flags & (1L<<16)) proto->oz += proto->iz; proto->iz = n; memcopy(proto->op, proto->ip, n); return iob; } } if (!(retain & (1<<6))) { retain |= (1<<6); ppfsm(4, ((char*)0)); } proto->line = 1; if (flags & ((1<<4)|(1<<5))) { if (flags & (1<<5)) { proto->flags |= (1L<<11); if (flags & (1<<11)) retain |= (1<<5); } else if (flags & (1<<4)) { if (flags & (1<<11)) retain |= (1<<4); if (flags & (1<<0)) { *proto->op++ = '#'; proto->op = strcopy(proto->op, "pragma"); *proto->op++ = ' '; proto->op = strcopy(proto->op, pragmas[0].name); *proto->op++ = '\n'; } else proto->flags |= (1L<<10); } if (!(flags & (1<<0))) { if (proto->flags & (1L<<29)) { proto->op = strcopy(proto->op, "%{\n"); proto->op = strcopy(proto->op, "/* : : generated by proto : : */\n"); proto->op = strcopy(proto->op, "%}\n"); } else { if (n) *proto->op++ = '\n'; proto->op = strcopy(proto->op, "/* : : generated by proto : : */\n"); if (n) proto->op = linesync(proto, proto->op, proto->line); else if (proto->flags & ((1L<<10)|(1L<<11))) proto->op = init(proto, proto->op, proto->flags); } } } proto->file = file; if (flags & (1<<0)) { proto->flags |= (1L<<0); if (!(flags & (1<<4))) proto->flags |= (1L<<5); } return iob; } int pppread __PARAM__((char* iob), (iob)) __OTORP__(char* iob;) { register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t)); register int n; if (proto->flags & (1L<<18)) { if (proto->iz) { n = proto->iz; proto->iz = 0; } else if (!(proto->flags & (1L<<16))) n = 0; else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & (1L<<0)) && n < proto->oz) { proto->flags &= ~(1L<<16); close(proto->fd); } } else { if (proto->op == proto->ob) { if (proto->flags & (1L<<4)) return -1; if (proto->flags & (1L<<29)) { register char* ip = proto->ip; register char* op = proto->ob; register char* ep = proto->ob + proto->oz - 2; if (!*ip) { ip = proto->ip = proto->ib; if (!(proto->flags & (1L<<16))) n = 0; else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & (1L<<0)) && n < proto->iz) { if (n < 0) n = 0; proto->flags &= ~(1L<<16); close(proto->fd); } ip[n] = 0; } if (proto->flags & (1L<<30)) { proto->flags &= ~(1L<<30); if (*ip == '%') { *op++ = *ip++; if (proto->flags & (1L<<31)) proto->flags &= ~(1L<<29); else proto->flags |= (1L<<31); } } if (proto->flags & (1L<<29)) while (op < ep && (n = *op++ = *ip)) { ip++; if (n == '%') { if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n')) { *op++ = *ip++; if (proto->flags & (1L<<31)) proto->flags &= ~(1L<<29); else proto->flags |= (1L<<31); break; } if (!*ip) { *op++ = '%'; proto->flags |= (1L<<30); break; } } else if (n == '\n') proto->line++; } proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip); proto->ip = ip; } else lex(proto, proto->flags); if ((proto->flags & ((1L<<4)|(1L<<16))) == (1L<<4)) proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n"); } n = proto->op - proto->ob; proto->op = proto->ob; } return n; } static int proto __PARAM__((char* file, char* package, char* copy, char* comment, int flags), (file, package, copy, comment, flags)) __OTORP__(char* file; char* package; char* copy; char* comment; int flags;) { char* b; char* e; char* p; int n; int m; int x; int fd; char buf[1024]; if (file && access(file, 4)) proto_error(((char*)0), 2, file, "not found"); else if (b = pppopen(file, 0, package, comment, flags)) { if (!file) fd = 1; else if (flags & ((1<<13)<<1)) { e = file + sstrlen( file) - 1; x = *e; *e = '_'; if ((fd = creat(file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { proto_error(b, 2, file, "cannot create temporary file"); pppclose(b); return flags | ((1<<13)<<0); } *e = x; } else if (copy) { if (((n = sstrlen( copy)) + sstrlen( file) + 2) > sizeof(buf)) { proto_error(b, 2, copy, "copy path too long"); pppclose(b); return flags | ((1<<13)<<0); } strcopy( buf, copy); e = buf + n; if (*file != '/') *e++ = '/'; strcopy( e, file); if ((fd = creat(buf, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { for (e = buf; *e == '/'; e++); do { if (*e == '/') { *e = 0; if (access(buf, 0) && mkdir(buf, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) { proto_error(b, 2, buf, "cannot create copy directory"); pppclose(b); return flags | ((1<<13)<<0); } *e = '/'; } } while (*e++); if ((fd = creat(buf, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { proto_error(b, 2, buf, "cannot create copy file"); pppclose(b); return flags | ((1<<13)<<0); } } file = buf; } else fd = 1; if (file && (flags & ((1<<13)<<2))) proto_error(b, 0, "convert to", file); while ((n = pppread(b)) > 0) { p = b; for (;;) { if ((m = write(fd, p, n)) <= 0) { proto_error(b, 2, "write error", ((char*)0)); flags |= ((1<<13)<<0); break; } if ((n -= m) <= 0) break; p += m; } if (m < 0) break; } if (fd > 1) close(fd); if (file && (flags & ((1<<13)<<1))) { *e = '_'; strcopy( b, file); *e = x; if (replace(b, file, !(flags & (1<<0)))) proto_error(b, 2, "cannot rename to", file); } pppclose(b); } return flags; } typedef struct Sufcom_s { char suffix[4]; char comment[4]; } Sufcom_t; static const Sufcom_t sufcom[] = { "c", "/*", "cpp", "/*", "cxx", "/*", "c++", "/*", "C", "/*", "CPP", "/*", "CXX", "/*", "C++", "/*", "f", "C", "F", "C", "h", "/*", "hpp", "/*", "hxx", "/*", "H", "/*", "HPP", "/*", "HXX", "/*", "ksh", "#", "KSH", "#", "l", "/*", "L", "/*", "p", "(*)", "pas", "(*)", "P", "(*)", "PAS", "(*)", "pl", "#", "PL", "#", "pl1", "/*", "pli", "/*", "PL1", "/*", "PLI", "/*", "sh", "#", "SH", "#", "sml", "(*)", "SML", "(*)", "y", "/*", "Y", "/*", }; static char* type __PARAM__((register char* file, char* comment), (file, comment)) __OTORP__(register char* file; char* comment;) { register char* suffix; register int i; if (file && (!comment || !*comment)) { suffix = 0; while (*file) if (*file++ == '.') suffix = file; if (suffix && sstrlen( suffix) <= 3) for (i = 0; i < sizeof(sufcom) / sizeof(sufcom[0]); i++) if (!strcmp(suffix, sufcom[i].suffix)) return (char*)sufcom[i].comment; } return comment; } int main __PARAM__((int argc, char** argv), (argc, argv)) __OTORP__(int argc; char** argv;) { char* b; char* file; int fd; int n; char* op; char* oe; char* comment = 0; char* copy = 0; char* list = 0; char* package = 0; int flags = (1<<4); char buf[1024]; char opt[4 * 1024]; while ((file = *++argv) && *file == '-' && *(file + 1)) { for (;;) { switch (*++file) { case 0: break; case 'c': if (!*(comment = ++file)) comment = *++argv; break; case 'd': flags |= (1<<1); continue; case 'e': if (!*(package = ++file) && !(package = *++argv)) { file = "??"; continue; } break; case 'f': flags |= (1<<3); continue; case 'h': flags &= ~(1<<4); continue; case 'i': flags |= (1<<0); continue; case 'n': flags |= (1<<7); continue; case 'p': flags |= (1<<9); continue; case 'r': flags |= ((1<<13)<<1); continue; case 's': flags |= (1<<5); continue; case 't': flags |= (1<<12); continue; case 'v': flags |= ((1<<13)<<2); continue; case 'x': flags |= (1<<2); continue; case 'z': flags |= (1<<1)|(1<<8); continue; case 'C': if (!*(copy = ++file) && !(copy = *++argv)) { file = "??"; continue; } break; case 'L': if (!*(list = ++file) && !(list = *++argv)) { file = "??"; continue; } break; case 'P': case '+': flags |= (1<<10); continue; case 'S': comment = "#"; continue; default: proto_error(((char*)0), 2, file, "unknown option"); /* FALLTHROUGH */ case '?': b = "Usage: proto [-dfhinprstvzP+S] [-C directory] [-e package]\n [-L file] file ...\n"; write(2, b, sstrlen( b)); return 2; } break; } } if (list) { if (*list == '-' && !*(list + 1)) fd = 0; else if ((fd = open(list, O_RDONLY)) < 0) proto_error(((char*)0), 3, list, "not found"); do { for (b = buf; (n = read(fd, b, 1)) > 0 && *b != '\n' && b < &buf[sizeof(buf) - 1]; b++); if (b > buf) { *b = 0; flags = proto(buf, package, copy, type(buf, comment), flags); } } while (n > 0); if (fd > 0) close(fd); } if (file) do flags = proto(file, package, copy, type(file, comment), flags); while (file = *++argv); else if (!list) flags = proto(file, package, copy, type(file, comment), flags); return errors ? 1 : (flags & ((1<<13)<<0)) ? 2 : 0; } ksh-1.0.0-beta.2/src/cmd/INIT/ratz.c000066400000000000000000005111651415700074400166020ustar00rootroot00000000000000/* * ratz -- read a tar gzip archive from the standard input * * coded for portability * _SEAR_* macros for Win32 self extracting archives -- see sear(1). */ #pragma clang diagnostic ignored "-Wdeprecated-register" #pragma clang diagnostic ignored "-Wparentheses" static char id[] = "\n@(#)$Id: ratz (Jean-loup Gailly, Mark Adler, Glenn Fowler) 1.2.3 2010-10-10 $\0\n"; #if _PACKAGE_ast #include #include static const char usage[] = "[-?\n@(#)$Id: ratz (Jean-loup Gailly, Mark Adler, Glenn Fowler) 1.2.3 2010-10-10 $\n]" "[-author?Jean-loup Gailly]" "[-author?Mark Adler]" "[-author?Glenn Fowler ]" "[-copyright?Copyright (c) 1995-2005 Jean-loup Gailly and Mark Adler]" "[-license?http://www.opensource.org/licenses/zlib-license]" "[+NAME?ratz - read a tar gzip archive]" "[+DESCRIPTION?\bratz\b extracts files and directories from a tar gzip" " archive on the standard input. It is a standalone program for systems" " that do not have \bpax\b(1), \btar\b(1) or \bgunzip\b(1). Only regular" " files and directories are extracted; all other file types are ignored.]" "[+?\b.exe\b files generated by \bsear\b(1) are fully functional \bratz\b" " executables, so any \bratz\b option may be used on a \bsear\b file." " This allows \bsear\b file contents to be examined and extracted without" " executing any embedded installation scripts.]" "[c:cat|uncompress?Uncompress the standard input and copy it to the standard" " output.]" #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) "[i!:install?Execute the sear installation script.]" "[k:keep?Keep the installation temporary directory.]" #endif "[l:local?Reject files that traverse outside the current directory.]" "[m:meter?Display a one line text meter showing archive read progress.]" "[n!:convert?In EBCDIC environments convert text archive members from ASCII" " to the native EBCDIC.]" "[t:list?List each file path on the standard output but do not extract.]" "[v:verbose?List each file path on the standard output as it is extracted.]" "[V?Print the program version and exit.]" "[+SEE ALSO?\bgunzip\b(1), \bpackage\b(1), \bpax\b(1), \bsear\b(1), \btar\b(1)]" ; #else #define NiL ((char*)0) #endif #define METER_width 80 #define METER_parts 20 #ifndef _GUNZIP_H #define _GUNZIP_H 1 /* * stripped down zlib containing public gzfopen()+gzread() in one file * USE THE REAL ZLIB AFTER BOOTSTRAP */ #define ZLIB_INTERNAL 1 #define NO_GZCOMPRESS 1 #define gz_headerp voidp #include #include #if _PACKAGE_ast || defined(__STDC__) || defined(_SEAR_EXEC) || defined(_WIN32) #define FOPEN_READ "rb" #define FOPEN_WRITE "wb" #else #define FOPEN_READ "r" #define FOPEN_WRITE "w" #endif #ifndef O_BINARY #define O_BINARY 0 #endif #if _PACKAGE_ast #ifndef setmode #define setmode(d,m) #endif #else #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__) #define _WINIX 1 #endif #if _WIN32 && !_WINIX #include #include #include #include #define access _access #define chmod _chmod #define close _close #define dup _dup #define lseek _lseek #define open _open #define read _read #define setmode _setmode #define unlink _unlink #define mkdir(a,b) _mkdir(a) #else #define HAVE_UNISTD_H 1 #include #include #ifndef setmode #define setmode(d,m) #endif #endif #if defined(__STDC__) #include #include #endif #endif #ifndef _ZLIB_H #define _ZLIB_H 1 /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef _ZCONF_H #define _ZCONF_H 1 #if _PACKAGE_ast #include /* for { _WINIX __IMPORT__ __EXPORT__ } */ #define z_off_t int32_t #if _typ_int64_t #define z_off64_t int64_t #endif #else #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__) #define _WINIX 1 #endif #endif #if _BLD_z && defined(__EXPORT__) #define ZEXTERN __EXPORT__ #define ZEXPORT #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MS-DOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MS-DOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if HAVE_UNISTD_H # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) # define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* _ZCONF_H */ #define ZLIB_VERSION "1.2.3" #define ZLIB_VERNUM 0x1230 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'd), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #endif /* _ZLIB_H */ #ifndef _ZUTIL_H #define _ZUTIL_H 1 #if !_PACKAGE_ast && !defined(STDC) #if defined(__STDC__) # include #endif # include # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 #include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ # else # ifndef fdopen # define fdopen(fd,mode) NULL /* No fdopen() */ # endif # endif #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b # endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # define vsnprintf _vsnprintf # endif # endif # ifdef __SASC # define NO_vsnprintf # endif #endif #ifdef VMS # define NO_vsnprintf #endif #if defined(pyr) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MS-DOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef Z_DEBUG # include extern int z_verbose; extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #endif /* _ZUTIL_H */ #ifndef _ZUTIL_C #define _ZUTIL_C #ifndef HAVE_MEMCPY void zmemcpy(dest, source, len) Bytef* dest; const Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int zmemcmp(s1, s2, len) const Bytef* s1; const Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MS-DOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ voidpf zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ #endif /* _ZUTIL_C */ #ifndef _CRC32_H #define _CRC32_H 1 /* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ #ifndef TBLS #define TBLS 1 #endif local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }, }; #endif /* _CRC32_H */ #ifndef _CRC32_C #define _CRC32_C 1 /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { if (buf == Z_NULL) return 0; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffff; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffff; } #undef DO1 #undef DO8 #endif /* _CRC32_C */ #ifndef _ADLER32_C #define _ADLER32_C 1 #define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* use NO_DIVIDE if your processor does not do division in hardware */ #ifdef NO_DIVIDE # define MOD(a) \ do { \ if (a >= (BASE << 16)) a -= (BASE << 16); \ if (a >= (BASE << 15)) a -= (BASE << 15); \ if (a >= (BASE << 14)) a -= (BASE << 14); \ if (a >= (BASE << 13)) a -= (BASE << 13); \ if (a >= (BASE << 12)) a -= (BASE << 12); \ if (a >= (BASE << 11)) a -= (BASE << 11); \ if (a >= (BASE << 10)) a -= (BASE << 10); \ if (a >= (BASE << 9)) a -= (BASE << 9); \ if (a >= (BASE << 8)) a -= (BASE << 8); \ if (a >= (BASE << 7)) a -= (BASE << 7); \ if (a >= (BASE << 6)) a -= (BASE << 6); \ if (a >= (BASE << 5)) a -= (BASE << 5); \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) # define MOD4(a) \ do { \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE # define MOD4(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long sum2; unsigned n; /* split Adler-32 into component sums */ sum2 = (adler >> 16) & 0xffff; adler &= 0xffff; /* in case user likes doing a byte at a time, keep it fast */ if (len == 1) { adler += buf[0]; if (adler >= BASE) adler -= BASE; sum2 += adler; if (sum2 >= BASE) sum2 -= BASE; return adler | (sum2 << 16); } /* initial Adler-32 value (deferred check for len == 1 speed) */ if (buf == Z_NULL) return 1L; /* in case short lengths are provided, keep it somewhat fast */ if (len < 16) { while (len--) { adler += *buf++; sum2 += adler; } if (adler >= BASE) adler -= BASE; MOD4(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX; n = NMAX / 16; /* NMAX is divisible by 16 */ do { DO16(buf); /* 16 sums unrolled */ buf += 16; } while (--n); MOD(adler); MOD(sum2); } /* do remaining bytes (less than NMAX, still just one modulo) */ if (len) { /* avoid modulos if none remaining */ while (len >= 16) { len -= 16; DO16(buf); buf += 16; } while (len--) { adler += *buf++; sum2 += adler; } MOD(adler); MOD(sum2); } /* return recombined sums */ return adler | (sum2 << 16); } #endif /* _ADLER32_C */ #ifndef _DEFLATE_H #define _DEFLATE_H 1 /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define EXTRA_STATE 69 #define NAME_STATE 73 #define COMMENT_STATE 91 #define HCRC_STATE 103 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ uInt pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush parameter for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MS-DOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding */ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to suppress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef Z_DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ void _tr_init OF((deflate_state *s)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); void _tr_align OF((deflate_state *s)); void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef Z_DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch _length_code[]; extern uch _dist_code[]; #else extern const uch _length_code[]; extern const uch _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->last_lit] = 0; \ s->l_buf[s->last_lit++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (length); \ ush dist = (distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* _DEFLATE_H */ #ifndef _INFTREES_H #define _INFTREES_H 1 typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of dynamic tree. The maximum found in a long but non- exhaustive search was 1444 code structures (852 for length/literals and 592 for distances, the latter actually the result of an exhaustive search). The true maximum is not known, but the value below is more than safe. */ #define ENOUGH 2048 #define MAXD 592 /* Type of code to build for inftable() */ typedef enum { CODES, LENS, DISTS } codetype; #endif /* _INFTREES_H */ #ifndef _INFLATE_H #define _INFLATE_H 1 /* Possible inflate modes between inflate() calls */ typedef enum { HEAD, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN, /* i: waiting for length/lit code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ LENGTH, /* i: waiting for 32-bit length (gzip) */ DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to the BAD or MEM mode -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE Read deflate blocks: TYPE -> STORED or TABLE or LEN or CHECK STORED -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN Read deflate codes: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* state maintained between inflate() calls. Approximately 7K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ }; #endif /* _INFLATE_H */ #ifndef _INFTREES_C #define _INFTREES_C 1 #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int inflate_table(type, lens, codes, table, bits, work) codetype type; unsigned short FAR *lens; unsigned codes; code FAR * FAR *table; unsigned FAR *bits; unsigned short FAR *work; { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code this; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ int end; /* use base and extra for symbol > end */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ this.op = (unsigned char)64; /* invalid code marker */ this.bits = (unsigned char)1; this.val = (unsigned short)0; *(*table)++ = this; /* make a table to force an error */ *(*table)++ = this; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } for (min = 1; min <= MAXBITS; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked when a LENS table is being made against the space in *table, ENOUGH, minus the maximum space needed by the worst case distance code, MAXD. This should never happen, but the sufficiency of ENOUGH has not been proven exhaustively, hence the check. This assumes that when type == LENS, bits == 9. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ end = 19; break; case LENS: base = lbase; base -= 257; extra = lext; extra -= 257; end = 256; break; default: /* DISTS */ base = dbase; extra = dext; end = -1; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = ((unsigned int)1) << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if (type == LENS && used >= ENOUGH - MAXD) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ this.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { this.op = (unsigned char)0; this.val = work[sym]; } else if ((int)(work[sym]) > end) { this.op = (unsigned char)(extra[work[sym]]); this.val = base[work[sym]]; } else { this.op = (unsigned char)(32 + 64); /* end of block */ this.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = ((unsigned int)1) << (len - drop); fill = ((unsigned int)1) << curr; min = fill; /* save offset to next table */ do { fill -= incr; next[(huff >> drop) + fill] = this; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = ((unsigned int)1) << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += min; /* here min is 1 << curr */ /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += ((unsigned int)1) << curr; if (type == LENS && used >= ENOUGH - MAXD) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* Fill in rest of table for incomplete codes. This loop is similar to the loop above in incrementing huff for table indices. It is assumed that len is equal to curr + drop, so there is no loop needed to increment through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ this.op = (unsigned char)64; /* invalid code marker */ this.bits = (unsigned char)(len - drop); this.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; this.bits = (unsigned char)len; } /* put invalid code marker in table */ next[huff >> drop] = this; /* backwards increment the len-bit code huff */ incr = ((unsigned int)1) << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; } /* set return parameters */ *table += used; *bits = root; return 0; } #endif /* _INFTREES_C */ #ifndef _INFFAST_C #define _INFFAST_C 1 /* Allow machine dependent optimization for post-increment or pre-increment. Based on testing to date, Pre-increment preferred for: - PowerPC G3 (Adler) - MIPS R5000 (Randers-Pehrson) Post-increment preferred for: - none No measurable difference: - Pentium III (Anderson) - M68060 (Nikl) */ #undef OFF /* (ancient) SunOS */ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ #else # define OFF 1 # define PUP(a) *++(a) #endif /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void inflate_fast(strm, start) z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; unsigned char FAR *in; /* local strm->next_in */ unsigned char FAR *last; /* while in < last, enough input available */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code this; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in - OFF; last = in + (strm->avail_in - 5); out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT dmax = state->dmax; #endif wsize = state->wsize; whave = state->whave; write = state->write; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (((unsigned int)1) << state->lenbits) - 1; dmask = (((unsigned int)1) << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = lcode[hold & lmask]; dolen: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op == 0) { /* literal */ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); PUP(out) = (unsigned char)(this.val); } else if (op & 16) { /* length base */ len = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((((unsigned int)1) << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = dcode[hold & dmask]; dodist: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op & 16) { /* distance base */ dist = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } dist += (unsigned)hold & ((((unsigned int)1) << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } from = window - OFF; if (write == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } else if (write < op) { /* wrap around window */ from += wsize + write - op; op -= write; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; if (write < len) { /* some from start of window */ op = write; len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += write - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } } else if ((op & 64) == 0) { /* 2nd level distance code */ this = dcode[this.val + (hold & ((((unsigned int)1) << op) - 1))]; goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ this = lcode[this.val + (hold & ((((unsigned int)1) << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (((unsigned int)1) << bits) - 1; /* update state and return */ strm->next_in = in + OFF; strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and write == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* _INFFAST_C */ #ifndef _INFLATE_C #define _INFLATE_C 1 /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, unsigned out)); #ifdef BUILDFIXED void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; strm->adler = 1; /* to support ill-conceived Java test suite */ state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768; state->head = Z_NULL; state->wsize = 0; state->whave = 0; state->write = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflatePrime(strm, bits, value) z_streamp strm; int bits; int value; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; state->hold += value << state->bits; state->bits += bits; return Z_OK; } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; if (windowBits < 0) { state->wrap = 0; windowBits = -windowBits; } else { state->wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } if (windowBits < 8 || windowBits > 15) { ZFREE(strm, state); strm->state = Z_NULL; return Z_STREAM_ERROR; } state->wbits = (unsigned)windowBits; state->window = Z_NULL; return inflateReset(strm); } int ZEXPORT inflateInit_(strm, version, stream_size) z_streamp strm; const char *version; int stream_size; { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifndef _INFFIXED_H #define _INFFIXED_H 1 static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; #endif /* _INFFIXED_H */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, out) z_streamp strm; unsigned out; { struct inflate_state FAR *state; unsigned copy, dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, ((unsigned int)1) << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = ((unsigned int)1) << state->wbits; state->write = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); state->write = 0; state->whave = state->wsize; } else { dist = state->wsize - state->write; if (dist > copy) dist = copy; zmemcpy(state->window + state->write, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); state->write = copy; state->whave = state->wsize; } else { state->write += dist; if (state->write == state->wsize) state->write = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((((unsigned int)1) << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Reverse the bytes in a 32-bit value */ #define REVERSE(q) \ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(strm, flush) z_streamp strm; int flush; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } state->flags = 0; /* expect zlib header */ if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); len = BITS(4) + 8; if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } state->dmax = ((unsigned int)1) << len; Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); if (state->head != Z_NULL) { state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && state->head->extra != Z_NULL) { len = state->head->extra_len - state->length; zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->length = 0; state->mode = NAME; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) state->head->name[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) state->head->comment[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } if (state->head != Z_NULL) { state->head->hcrc = (int)((state->flags >> 9) & 1); state->head->done = 1; } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; /* FALLTHROUGH */ case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; /* FALLTHROUGH */ case TYPE: if (flush == Z_BLOCK) goto inf_leave; /* FALLTHROUGH */ case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY; /* FALLTHROUGH */ case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; /* FALLTHROUGH */ case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; /* FALLTHROUGH */ case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.val < 16) { NEEDBITS(this.bits); DROPBITS(this.bits); state->lens[state->have++] = this.val; } else { if (this.val == 16) { NEEDBITS(this.bits + 2); DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (this.val == 17) { NEEDBITS(this.bits + 3); DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(this.bits + 7); DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; /* FALLTHROUGH */ case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); break; } for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.op && (this.op & 0xf0) == 0) { last = this; for (;;) { this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); state->length = (unsigned)this.val; if ((int)(this.op) == 0) { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); state->mode = LIT; break; } if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; /* FALLTHROUGH */ case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); state->mode = DIST; /* FALLTHROUGH */ case DIST: for (;;) { this = state->distcode[BITS(state->distbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if ((this.op & 0xf0) == 0) { last = this; for (;;) { this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)this.val; state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; /* FALLTHROUGH */ case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif if (state->offset > state->whave + out - left) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; /* FALLTHROUGH */ case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->write) { copy -= state->write; from = state->window + (state->wsize - copy); } else from = state->window + (state->write - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; if (( #ifdef GUNZIP state->flags ? hold : #endif REVERSE(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; /* FALLTHROUGH */ case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if (hold != (state->total & 0xffffffff)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; /* FALLTHROUGH */ case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) if (updatewindow(strm, out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; unsigned long id; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary id */ if (state->mode == DICT) { id = adler32(0L, Z_NULL, 0); id = adler32(id, dictionary, dictLength); if (id != state->check) return Z_DATA_ERROR; } /* copy dictionary to window */ if (updatewindow(strm, strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } if (dictLength > state->wsize) { zmemcpy(state->window, dictionary + dictLength - state->wsize, state->wsize); state->whave = state->wsize; } else { zmemcpy(state->window + state->wsize - dictLength, dictionary, dictLength); state->whave = dictLength; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } int ZEXPORT inflateGetHeader(strm, head) z_streamp strm; gz_headerp head; { struct inflate_state FAR *state; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; /* save header structure */ state->head = head; #ifdef GUNZIP head->done = 0; #endif return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; unsigned char FAR *buf; unsigned len; { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(strm) z_streamp strm; { unsigned len; /* number of bytes to look at or looked at */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold <<= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) z_streamp dest; z_streamp source; { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; unsigned wsize; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, ((unsigned int)1) << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ zmemcpy(dest, source, sizeof(z_stream)); zmemcpy(copy, state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) { wsize = ((unsigned int)1) << state->wbits; zmemcpy(window, state->window, wsize); } copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; } #endif /* _INFLATE_C */ #ifndef _GZIO_C #define _GZIO_C 1 typedef voidp gzFile; #ifndef Z_BUFSIZE # ifdef MAXSEG_64K # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ # else # define Z_BUFSIZE 16384 # endif #endif #ifndef Z_PRINTF_BUFSIZE # define Z_PRINTF_BUFSIZE 4096 #endif #ifdef __MVS__ # pragma map (fdopen , "\174\174FDOPEN") FILE *fdopen(int, const char *); #endif #define ALLOC(size) malloc(size) #define TRYFREE(p) {if (p) free(p);} static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ typedef struct gz_stream { z_stream stream; int z_err; /* error code for last stream operation */ int z_eof; /* set if end of input file */ FILE *file; /* .gz file */ Byte *inbuf; /* input buffer */ Byte *outbuf; /* output buffer */ uLong crc; /* crc32 of uncompressed data */ char *msg; /* error message */ char *path; /* path name for debugging only */ int transparent; /* 1 if input file is not a .gz file */ #if _PACKAGE_ast int fatal; /* fatal stream error => all other ops fail */ int nocrc; /* 1 to skip 'r' crc checks */ int noclose; /* 1 to skip destroy fclose */ int verified;/* 2-byte magic read and verified ('v') */ #endif char mode; /* 'w' or 'r' */ z_off_t start; /* start of compressed data in file (header skipped) */ z_off_t in; /* bytes into deflate or inflate */ z_off_t out; /* bytes out of deflate or inflate */ int back; /* one character push-back */ int last; /* true if push-back is last character */ } gz_stream; local gzFile gz_open OF((const char *path, const char *mode, FILE* fp)); local int get_byte OF((gz_stream *s)); local void check_header OF((gz_stream *s)); local int destroy OF((gz_stream *s)); local uLong getLong OF((gz_stream *s)); /* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The file is given either by FILE pointer or path name (if fp == 0). gz_open returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ local gzFile gz_open (path, mode, fp) const char *path; const char *mode; FILE *fp; { int err; int level = Z_DEFAULT_COMPRESSION; /* compression level */ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ char *p = (char*)mode; gz_stream *s; char fmode[80]; /* copy of mode, without the compression level */ char *m = fmode; if (!path || !mode) return Z_NULL; s = (gz_stream *)ALLOC(sizeof(gz_stream)); if (!s) return Z_NULL; s->stream.zalloc = (alloc_func)0; s->stream.zfree = (free_func)0; s->stream.opaque = (voidpf)0; s->stream.next_in = s->inbuf = Z_NULL; s->stream.next_out = s->outbuf = Z_NULL; s->stream.avail_in = s->stream.avail_out = 0; s->file = NULL; s->z_err = Z_OK; s->z_eof = 0; s->in = 0; s->out = 0; s->back = EOF; s->crc = crc32(0L, Z_NULL, 0); #if _PACKAGE_ast s->fatal = 0; s->nocrc = 0; s->verified = 0; #endif s->msg = NULL; s->transparent = 0; s->path = (char*)ALLOC(strlen(path)+1); if (s->path == NULL) { return destroy(s), (gzFile)Z_NULL; } strcpy(s->path, path); /* do this early for debugging */ s->mode = '\0'; do { if (*p == 'r') s->mode = 'r'; if (*p == 'w' || *p == 'a') s->mode = 'w'; if (*p >= '0' && *p <= '9') { level = *p - '0'; } else if (*p == 'f') { strategy = Z_FILTERED; } else if (*p == 'h') { strategy = Z_HUFFMAN_ONLY; } else if (*p == 'R') { strategy = Z_RLE; #if _PACKAGE_ast } else if (*p == 'n') { s->nocrc = 1; } else if (*p == 'o') { s->noclose = 1; } else if (*p == 'v') { s->verified = 1; #endif } else { *m++ = *p; /* copy the mode */ } } while (*p++ && m != fmode + sizeof(fmode)); if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == 'w') { #ifdef NO_GZCOMPRESS err = Z_STREAM_ERROR; #else #if _PACKAGE_ast s->nocrc = 0; #endif err = deflateInit2(&(s->stream), level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); /* windowBits is passed < 0 to suppress zlib header */ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); #endif if (err != Z_OK || s->outbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } else { s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); err = inflateInit2(&(s->stream), -MAX_WBITS); /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are * present after the compressed stream. */ if (err != Z_OK || s->inbuf == Z_NULL) { return destroy(s), (gzFile)Z_NULL; } } s->stream.avail_out = Z_BUFSIZE; errno = 0; if (!(s->file = fp) && !(s->file = F_OPEN(path, fmode))) { return destroy(s), (gzFile)Z_NULL; } if (s->mode == 'w') { /* Write a very simple .gz header: */ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); s->start = 10L; /* We use 10L instead of ftell(s->file) to because ftell causes an * fflush on some systems. This version of the library doesn't use * start anyway in write mode, so this initialization is not * necessary. */ } else { #if _PACKAGE_ast sfsetbuf(s->file, (void*)s->file, SF_UNBOUND); #endif check_header(s); /* skip the .gz header */ s->start = (z_off_t)(ftell(s->file) - s->stream.avail_in); } return (gzFile)s; } /* =========================================================================== Associate a gzFile with the stdio stream fp. */ gzFile ZEXPORT gzfopen (fp, mode) FILE* fp; const char *mode; { FILE* sp = (FILE*)fp; char name[20]; if (!sp) return (gzFile)Z_NULL; sprintf(name, "", fileno(sp)); /* for debugging */ return gz_open (name, mode, sp); } /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been successfully opened for reading. */ local int get_byte(s) gz_stream *s; { if (s->z_eof) return EOF; if (s->stream.avail_in == 0) { errno = 0; s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); if (s->stream.avail_in == 0) { s->z_eof = 1; if (ferror(s->file)) s->z_err = Z_ERRNO; return EOF; } s->stream.next_in = s->inbuf; } s->stream.avail_in--; return *(s->stream.next_in)++; } /* =========================================================================== Check the gzip header of a gz_stream opened for reading. Set the stream mode to transparent if the gzip magic header is not present; set s->err to Z_DATA_ERROR if the magic header is present but the rest of the header is incorrect. IN assertion: the stream s has already been created successfully; s->stream.avail_in is zero for the first time, but may be non-zero for concatenated .gz files. */ local void check_header(s) gz_stream *s; { int method; /* method byte */ int flags; /* flags byte */ uInt len; int c; #if _PACKAGE_ast if (!s->verified) for (len = 0; len < 2; len++) { c = get_byte(s); if (c != gz_magic[len]) { if (len != 0) s->stream.avail_in++, s->stream.next_in--; if (c != EOF) { s->stream.avail_in++, s->stream.next_in--; s->transparent = 1; } s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; return; } } #else /* Assure two bytes in the buffer so we can peek ahead -- handle case where first byte of header is at the end of the buffer after the last gzip segment */ len = s->stream.avail_in; if (len < 2) { if (len) s->inbuf[0] = s->stream.next_in[0]; errno = 0; len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; s->stream.avail_in += len; s->stream.next_in = s->inbuf; if (s->stream.avail_in < 2) { s->transparent = s->stream.avail_in; return; } } /* Peek ahead to check the gzip magic header */ if (s->stream.next_in[0] != gz_magic[0] || s->stream.next_in[1] != gz_magic[1]) { s->transparent = 1; return; } s->stream.avail_in -= 2; s->stream.next_in += 2; #endif /* Check the rest of the gzip header */ method = get_byte(s); flags = get_byte(s); if (method != Z_DEFLATED || (flags & RESERVED) != 0) { s->z_err = Z_DATA_ERROR; return; } /* Discard time, xflags and OS code: */ for (len = 0; len < 6; len++) (void)get_byte(s); if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ len = (uInt)get_byte(s); len += ((uInt)get_byte(s))<<8; /* len is garbage if EOF but the loop below will quit anyway */ while (len-- != 0 && get_byte(s) != EOF) ; } if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ while ((c = get_byte(s)) != 0 && c != EOF) ; } if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ while ((c = get_byte(s)) != 0 && c != EOF) ; } if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ for (len = 0; len < 2; len++) (void)get_byte(s); } s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; } /* =========================================================================== * Cleanup then free the given gz_stream. Return a zlib error code. Try freeing in the reverse order of allocations. */ local int destroy (s) gz_stream *s; { int err = Z_OK; if (!s) return Z_STREAM_ERROR; TRYFREE(s->msg); if (s->stream.state != NULL) { if (s->mode == 'w') { #ifdef NO_GZCOMPRESS err = Z_STREAM_ERROR; #else err = deflateEnd(&(s->stream)); #endif } else if (s->mode == 'r') { err = inflateEnd(&(s->stream)); } } #if _PACKAGE_ast if (s->file != NULL && (s->noclose ? (s->mode == 'r' ? 0 : fflush(s->file)) : fclose(s->file))) { #else if (s->file != NULL && fclose(s->file)) { #endif #ifdef ESPIPE if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ #endif err = Z_ERRNO; } if (s->z_err < 0) err = s->z_err; TRYFREE(s->inbuf); TRYFREE(s->outbuf); TRYFREE(s->path); TRYFREE(s); return err; } /* =========================================================================== Reads the given number of uncompressed bytes from the compressed file. gzread returns the number of bytes actually read (0 for end of file). */ int ZEXPORT gzread (file, buf, len) gzFile file; voidp buf; unsigned len; { gz_stream *s = (gz_stream*)file; Bytef *start = (Bytef*)buf; /* starting point for crc computation */ Byte *next_out; /* == stream.next_out but not forced far (for MS-DOS) */ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; if (s->z_err == Z_STREAM_END) return 0; /* EOF */ next_out = (Byte*)buf; s->stream.next_out = (Bytef*)buf; s->stream.avail_out = len; if (s->stream.avail_out && s->back != EOF) { *next_out++ = s->back; s->stream.next_out++; s->stream.avail_out--; s->back = EOF; s->out++; start++; if (s->last) { s->z_err = Z_STREAM_END; return 1; } } while (s->stream.avail_out != 0) { if (s->transparent) { /* Copy first the lookahead bytes: */ uInt n = s->stream.avail_in; if (n > s->stream.avail_out) n = s->stream.avail_out; if (n > 0) { zmemcpy(s->stream.next_out, s->stream.next_in, n); next_out += n; s->stream.next_out = next_out; s->stream.next_in += n; s->stream.avail_out -= n; s->stream.avail_in -= n; } if (s->stream.avail_out > 0) { s->stream.avail_out -= (uInt)fread(next_out, 1, s->stream.avail_out, s->file); } len -= s->stream.avail_out; s->in += len; s->out += len; if (len == 0) s->z_eof = 1; return (int)len; } if (s->stream.avail_in == 0 && !s->z_eof) { errno = 0; s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); if (s->stream.avail_in == 0) { s->z_eof = 1; if (ferror(s->file)) { s->z_err = Z_ERRNO; break; } } s->stream.next_in = s->inbuf; } s->in += s->stream.avail_in; s->out += s->stream.avail_out; s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->in -= s->stream.avail_in; s->out -= s->stream.avail_out; if (s->z_err == Z_STREAM_END) { /* Check CRC and original size */ #if _PACKAGE_ast if (!s->nocrc) #endif s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); start = s->stream.next_out; #if _PACKAGE_ast if (getLong(s) != s->crc && !s->nocrc) { #else if (getLong(s) != s->crc) { #endif s->z_err = Z_DATA_ERROR; } else { (void)getLong(s); /* The uncompressed length returned by above getlong() may be * different from s->out in case of concatenated .gz files. * Check for such files: */ check_header(s); if (s->z_err == Z_OK) { inflateReset(&(s->stream)); #if _PACKAGE_ast if (!s->nocrc) #endif s->crc = crc32(0L, Z_NULL, 0); #if _PACKAGE_ast else s->z_err = Z_STREAM_END; #endif } } } if (s->z_err != Z_OK || s->z_eof) break; } #if _PACKAGE_ast if (!s->nocrc) #endif s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); if (len == s->stream.avail_out && (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) return -1; return (int)(len - s->stream.avail_out); } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets z_err in case of error. */ local uLong getLong (s) gz_stream *s; { uLong x = (uLong)get_byte(s); int c; x += ((uLong)get_byte(s))<<8; x += ((uLong)get_byte(s))<<16; c = get_byte(s); if (c == EOF) s->z_err = Z_DATA_ERROR; x += ((uLong)c)<<24; return x; } #endif /* _GZIO_C */ #endif /* _GUNZIP_H */ #undef local #ifndef _RATZ_C #define _RATZ_C 1 #include #ifndef S_IRUSR #define S_IRUSR 0400 #endif #ifndef S_IWUSR #define S_IWUSR 0200 #endif #ifndef S_IXUSR #define S_IXUSR 0100 #endif #ifndef S_IRGRP #define S_IRGRP 0040 #endif #ifndef S_IWGRP #define S_IWGRP 0020 #endif #ifndef S_IXGRP #define S_IXGRP 0010 #endif #ifndef S_IROTH #define S_IROTH 0004 #endif #ifndef S_IWOTH #define S_IWOTH 0002 #endif #ifndef S_IXOTH #define S_IXOTH 0001 #endif /* * Standard Archive Format * USTAR - Uniform Standard Tape ARchive */ #define TBLOCK 512 #define NAMSIZ 100 #define PFXSIZ 155 #define TMODLEN 8 #define TUIDLEN 8 #define TGIDLEN 8 #define TSIZLEN 12 #define TMTMLEN 12 #define TCKSLEN 8 #define TMAGIC "ustar" /* ustar and a null */ #define TMAGLEN 6 #define TVERSION "00" /* 00 and no null */ #define TVERSLEN 2 #define TUNMLEN 32 #define TGNMLEN 32 #define TDEVLEN 8 #define TPADLEN 12 /* * values used in typeflag field */ #define REGTYPE '0' /* regular file */ #define AREGTYPE 0 /* alternate REGTYPE */ #define LNKTYPE '1' /* hard link */ #define SYMTYPE '2' /* soft link */ #define CHRTYPE '3' /* character special */ #define BLKTYPE '4' /* block special */ #define DIRTYPE '5' /* directory */ #define FIFOTYPE '6' /* FIFO special */ #define CONTTYPE '7' /* reserved */ #define SOKTYPE '8' /* socket -- reserved */ #define VERTYPE 'V' /* version -- reserved */ #define EXTTYPE 'x' /* extended header -- reserved */ /* * bits used in mode field */ #define TSUID 04000 /* set uid on exec */ #define TSGID 02000 /* set gid on exec */ #define TSVTX 01000 /* sticky bit -- reserved */ /* * file permissions */ #define TUREAD 00400 /* read by owner */ #define TUWRITE 00200 /* write by owner */ #define TUEXEC 00100 /* execute by owner */ #define TGREAD 00040 /* read by group */ #define TGWRITE 00020 /* execute by group */ #define TGEXEC 00010 /* write by group */ #define TOREAD 00004 /* read by other */ #define TOWRITE 00002 /* write by other */ #define TOEXEC 00001 /* execute by other */ #define TAR_SUMASK ((1L<<(TCKSLEN-1)*3)-1) typedef struct { char name[NAMSIZ]; char mode[TMODLEN]; char uid[TUIDLEN]; char gid[TGIDLEN]; char size[TSIZLEN]; char mtime[TMTMLEN]; char chksum[TCKSLEN]; char typeflag; char linkname[NAMSIZ]; char magic[TMAGLEN]; char version[TVERSLEN]; char uname[TUNMLEN]; char gname[TGNMLEN]; char devmajor[TDEVLEN]; char devminor[TDEVLEN]; char prefix[PFXSIZ]; char pad[TPADLEN]; } Header_t; static struct { char* id; unsigned long blocks; unsigned long files; } state; #if !_PACKAGE_ast static void usage() { #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) fprintf(stderr, "Usage: %s [-ciklmntvV] [ [no]name[=value] ... ]\n", state.id); #else fprintf(stderr, "Usage: %s [-clmntvV] < input.tgz\n", state.id); #endif exit(2); } #endif /* * the X/Open dd EBCDIC table */ static const unsigned char a2e[] = { 0000,0001,0002,0003,0067,0055,0056,0057, 0026,0005,0045,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0074,0075,0062,0046, 0030,0031,0077,0047,0034,0035,0036,0037, 0100,0132,0177,0173,0133,0154,0120,0175, 0115,0135,0134,0116,0153,0140,0113,0141, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0172,0136,0114,0176,0156,0157, 0174,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0321,0322,0323,0324,0325,0326, 0327,0330,0331,0342,0343,0344,0345,0346, 0347,0350,0351,0255,0340,0275,0232,0155, 0171,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0221,0222,0223,0224,0225,0226, 0227,0230,0231,0242,0243,0244,0245,0246, 0247,0250,0251,0300,0117,0320,0137,0007, 0040,0041,0042,0043,0044,0025,0006,0027, 0050,0051,0052,0053,0054,0011,0012,0033, 0060,0061,0032,0063,0064,0065,0066,0010, 0070,0071,0072,0073,0004,0024,0076,0341, 0101,0102,0103,0104,0105,0106,0107,0110, 0111,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0142,0143,0144,0145,0146,0147, 0150,0151,0160,0161,0162,0163,0164,0165, 0166,0167,0170,0200,0212,0213,0214,0215, 0216,0217,0220,0152,0233,0234,0235,0236, 0237,0240,0252,0253,0254,0112,0256,0257, 0260,0261,0262,0263,0264,0265,0266,0267, 0270,0271,0272,0273,0274,0241,0276,0277, 0312,0313,0314,0315,0316,0317,0332,0333, 0334,0335,0336,0337,0352,0353,0354,0355, 0356,0357,0372,0373,0374,0375,0376,0377, }; /* * the X/Open dd IBM table */ static const unsigned char a2i[] = { 0000,0001,0002,0003,0067,0055,0056,0057, 0026,0005,0045,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0074,0075,0062,0046, 0030,0031,0077,0047,0034,0035,0036,0037, 0100,0132,0177,0173,0133,0154,0120,0175, 0115,0135,0134,0116,0153,0140,0113,0141, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0172,0136,0114,0176,0156,0157, 0174,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0321,0322,0323,0324,0325,0326, 0327,0330,0331,0342,0343,0344,0345,0346, 0347,0350,0351,0255,0340,0275,0137,0155, 0171,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0221,0222,0223,0224,0225,0226, 0227,0230,0231,0242,0243,0244,0245,0246, 0247,0250,0251,0300,0117,0320,0241,0007, 0040,0041,0042,0043,0044,0025,0006,0027, 0050,0051,0052,0053,0054,0011,0012,0033, 0060,0061,0032,0063,0064,0065,0066,0010, 0070,0071,0072,0073,0004,0024,0076,0341, 0101,0102,0103,0104,0105,0106,0107,0110, 0111,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0142,0143,0144,0145,0146,0147, 0150,0151,0160,0161,0162,0163,0164,0165, 0166,0167,0170,0200,0212,0213,0214,0215, 0216,0217,0220,0232,0233,0234,0235,0236, 0237,0240,0252,0253,0254,0255,0256,0257, 0260,0261,0262,0263,0264,0265,0266,0267, 0270,0271,0272,0273,0274,0275,0276,0277, 0312,0313,0314,0315,0316,0317,0332,0333, 0334,0335,0336,0337,0352,0353,0354,0355, 0356,0357,0372,0373,0374,0375,0376,0377, }; /* * the MVS OpenEdition EBCDIC table */ static const unsigned char a2o[] = { 0000,0001,0002,0003,0067,0055,0056,0057, 0026,0005,0025,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0074,0075,0062,0046, 0030,0031,0077,0047,0034,0035,0036,0037, 0100,0132,0177,0173,0133,0154,0120,0175, 0115,0135,0134,0116,0153,0140,0113,0141, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0172,0136,0114,0176,0156,0157, 0174,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0321,0322,0323,0324,0325,0326, 0327,0330,0331,0342,0343,0344,0345,0346, 0347,0350,0351,0255,0340,0275,0137,0155, 0171,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0221,0222,0223,0224,0225,0226, 0227,0230,0231,0242,0243,0244,0245,0246, 0247,0250,0251,0300,0117,0320,0241,0007, 0040,0041,0042,0043,0044,0045,0006,0027, 0050,0051,0052,0053,0054,0011,0012,0033, 0060,0061,0032,0063,0064,0065,0066,0010, 0070,0071,0072,0073,0004,0024,0076,0377, 0101,0252,0112,0261,0237,0262,0152,0265, 0273,0264,0232,0212,0260,0312,0257,0274, 0220,0217,0352,0372,0276,0240,0266,0263, 0235,0332,0233,0213,0267,0270,0271,0253, 0144,0145,0142,0146,0143,0147,0236,0150, 0164,0161,0162,0163,0170,0165,0166,0167, 0254,0151,0355,0356,0353,0357,0354,0277, 0200,0375,0376,0373,0374,0272,0256,0131, 0104,0105,0102,0106,0103,0107,0234,0110, 0124,0121,0122,0123,0130,0125,0126,0127, 0214,0111,0315,0316,0313,0317,0314,0341, 0160,0335,0336,0333,0334,0215,0216,0337, }; /* * ASCII text vs. control */ static const unsigned char ascii_text[] = { 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; static int block(fp, gz, buf) FILE* fp; gzFile gz; char* buf; { int r; if (gz) r = gzread(gz, buf, sizeof(Header_t)) == sizeof(Header_t); else r = fread(buf, sizeof(Header_t), 1, fp) == 1; if (r) state.blocks++; return r; } static int skip(fp, gz, buf, n) FILE* fp; gzFile gz; char* buf; unsigned long n; { while (n > 0) { if (!block(fp, gz, buf)) { fprintf(stderr, "%s: unexpected EOF\n", state.id); return 1; } if (n <= sizeof(Header_t)) break; n -= sizeof(Header_t); } return 0; } static unsigned long number(s) register char* s; { unsigned long n = 0; while (*s == ' ') s++; while (*s >= '0' && *s <= '7') n = (n << 3) + (*s++ - '0'); return n; } #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) #ifndef PATH_MAX #define PATH_MAX 256 #endif #define EXIT(n) return(sear_exec((char*)0,(char**)0,(char*)0,(n))) static int sear_stdin; static char* sear_tmp; static char sear_buf[PATH_MAX]; static int sear_seek(off_t offset, int tmp) { int n; char cmd[PATH_MAX]; GetModuleFileName(NULL, cmd, sizeof(cmd)); sear_stdin = dup(0); close(0); if (open(cmd, O_BINARY|O_RDONLY) || lseek(0, offset, 0) != offset) { fprintf(stderr, "%s: %s: cannot seek to data offset\n", state.id, cmd); return -1; } if (tmp) { if ((n = GetTempPath(sizeof(cmd), cmd)) <= 0 || n > sizeof(cmd)) { fprintf(stderr, "%s: cannot determine temporary directory path\n", state.id); return -1; } if (!GetTempFileName(cmd, "SEA", 0, sear_buf)) { fprintf(stderr, "%s: cannot determine temporary file path\n", state.id); return -1; } sear_tmp = sear_buf; if (!DeleteFile(sear_tmp)) { fprintf(stderr, "%s: %s: cannot initialize temporary directory\n", state.id, sear_tmp); return -1; } if (!CreateDirectory(sear_tmp, NULL)) { fprintf(stderr, "%s: %s: cannot create temporary directory\n", state.id, sear_tmp); return -1; } if (!SetCurrentDirectory(sear_tmp)) { fprintf(stderr, "%s: %s: cannot cd to temporary directory\n", state.id, sear_tmp); return -1; } } return 0; } /* * remove dir and its subdirs */ static void sear_rm_r(char* dir) { WIN32_FIND_DATA info; HANDLE hp; if (!SetCurrentDirectory(dir)) return; if ((hp = FindFirstFile("*.*", &info)) != INVALID_HANDLE_VALUE) { do { if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) SetFileAttributes(info.cFileName, info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); DeleteFile(info.cFileName); } else if (info.cFileName[0] != '.' || info.cFileName[1] != 0 && (info.cFileName[1] != '.' || info.cFileName[2] != 0)) sear_rm_r(info.cFileName); } while(FindNextFile(hp, &info)); FindClose(hp); } if (SetCurrentDirectory("..")) RemoveDirectory(dir); } /* * system(3) without PATH search that should work on all Windows variants */ static int sear_system(const char* command, int nowindow) { PROCESS_INFORMATION pinfo; STARTUPINFO sinfo; char* cp; char path[PATH_MAX]; int n = *command == '"'; DWORD flags = NORMAL_PRIORITY_CLASS; strncpy(path, &command[n], PATH_MAX - 4); n = n ? '"' : ' '; for (cp = path; *cp; *cp++) if (*cp == n) break; *cp = 0; if (GetFileAttributes(path) == 0xffffffff && GetLastError() == ERROR_FILE_NOT_FOUND) strcpy(cp, ".exe"); ZeroMemory(&sinfo, sizeof(sinfo)); if (nowindow) flags |= CREATE_NO_WINDOW; if (!CreateProcess(path, (char*)command, 0, 0, TRUE, flags, NULL, NULL, &sinfo, &pinfo)) n = GetLastError() == ERROR_FILE_NOT_FOUND ? 127 : 126; else { CloseHandle(pinfo.hThread); WaitForSingleObject(pinfo.hProcess, INFINITE); if (!GetExitCodeProcess(pinfo.hProcess, &n)) n = 1; CloseHandle(pinfo.hProcess); Sleep(2 * 1000); } return n; } /* * copy t to f but no farther than e * next t returned */ static char* copy(char* t, const char* f, char* e) { while (t < e && *f) *t++ = *f++; return t; } /* * execute cmd, chdir .., and remove sear_tmp */ static int sear_exec(const char* cmd, char* const* arg, char* operands, int code) { const char* a; char* b; char* e; int r; int sh; int nowindow; char buf[1024]; fflush(stdout); fflush(stderr); if (sear_tmp) { close(0); dup(sear_stdin); close(sear_stdin); nowindow = 0; if (cmd) { if (arg) for (r = 0; arg[r]; r++) if (!strcmp(arg[r], "remote")) { nowindow = 1; break; } sh = 0; for (a = cmd; *a && *a != ' '; a++) if (a[0] == '.' && a[1] == 's' && a[2] == 'h' && (!a[3] || a[3] == ' ')) { sh = 1; break; } b = buf; e = buf + sizeof(buf) - 1; if (sh || arg) { if (sh) { b = copy(b, "ksh.exe ", e); if (*cmd && *cmd != '/') b = copy(b, "./", e); } b = copy(b, cmd, e); while (a = *arg++) { if ((e - b) < 3) break; b = copy(b, " \"", e); b = copy(b, a, e); b = copy(b, "\"", e); } } if (operands) { if (b == buf) b = copy(b, cmd, e); b = copy(b, " -- ", e); b = copy(b, operands, e); } if (b > buf) { *b = 0; cmd = (const char*)buf; } r = sear_system(cmd, nowindow); } else r = code; if (code >= 0) sear_rm_r(sear_tmp); } else r = cmd ? 0 : code; return r; } #else #define EXIT(n) return(n) #endif int main(argc, argv) int argc; char** argv; { register int c; register char* s; register char* t; register char* e; unsigned long n; unsigned long m; const unsigned char* a2x; int clear; int list; int local; int meter; int unzip; int verbose; unsigned int mode; unsigned long total; off_t pos; gzFile gz; FILE* fp; Header_t header; unsigned char num[4]; char path[sizeof(header.prefix) + sizeof(header.name) + 4]; char buf[sizeof(header)]; #if defined(_SEAR_OPTS) char* opts[4]; #endif #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) int install = 1; #endif setmode(0, O_BINARY); setmode(1, O_BINARY); clear = 0; list = 0; local = 0; meter = 0; unzip = 0; verbose = 0; if (s = *argv) { t = s; while (*s) if (*s++ == '/') t = s; if (!strcmp(t, "gunzip")) unzip = 1; state.id = t; } else state.id = "ratz"; switch ((unsigned char)'~') { case 0241: switch ('\n') { case 0025: a2x = a2o; break; default: a2x = a2e; break; } break; case 0137: a2x = a2i; break; default: a2x = 0; break; } #if defined(_SEAR_OPTS) opts[0] = argv[0]; opts[1] = _SEAR_OPTS; opts[2] = argv[1]; opts[3] = 0; argv = opts; #endif #if _PACKAGE_ast error_info.id = state.id; for (;;) { switch (optget(argv, usage)) { case 'c': unzip = 1; continue; #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) case 'i': install = 0; continue; case 'k': install = -1; continue; #endif case 'l': local = 1; continue; case 'm': meter = 1; continue; case 'n': a2x = 0; continue; case 't': list = 1; continue; case 'v': verbose = 1; continue; case 'V': sfprintf(sfstdout, "%s\n", id + 10); return 0; case '?': error(ERROR_usage(2), "%s", opt_info.arg); UNREACHABLE(); case ':': error(2, "%s", opt_info.arg); continue; } break; } if (error_info.errors) { error(ERROR_usage(2), "%s", optusage(NiL)); UNREACHABLE(); } argv += opt_info.index; #else while ((s = *++argv) && *s == '-' && *(s + 1)) { if (*(s + 1) == '-') { if (!*(s + 2)) { argv++; break; } usage(); break; } for (;;) { switch (c = *++s) { case 0: break; case 'c': unzip = 1; continue; #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK) case 'i': install = 0; continue; case 'k': install = -1; continue; #endif case 'l': local = 1; continue; case 'm': meter = 1; continue; case 'n': a2x = 0; continue; case 't': list = 1; continue; case 'v': verbose = 1; continue; case 'V': fprintf(stdout, "%s\n", id + 10); return 0; default: fprintf(stderr, "%s: -%c: unknown option\n", state.id, c); /* FALLTHROUGH */ case '?': usage(); break; } break; } } #endif #if defined(_SEAR_SEEK) if (sear_seek((off_t)_SEAR_SEEK, install && !list)) { Sleep(2 * 1000); return 1; } #endif /* * commit on the first gzip magic char */ if ((c = getchar()) == EOF) EXIT(0); ungetc(c, stdin); if (c != gz_magic[0]) gz = 0; else if (!(gz = gzfopen(stdin, FOPEN_READ))) { fprintf(stderr, "%s: gunzip open error\n", state.id); EXIT(1); } if (unzip) { if (!gz) { fprintf(stderr, "%s: not a gzip file\n", state.id); EXIT(1); } while ((c = gzread(gz, buf, sizeof(buf))) > 0) if (fwrite(buf, c, 1, stdout) != 1) { fprintf(stderr, "%s: write error\n", state.id); EXIT(1); } if (c < 0) { fprintf(stderr, "%s: read error\n", state.id); EXIT(1); } if (fflush(stdout)) { fprintf(stderr, "%s: flush error\n", state.id); EXIT(1); } EXIT(0); } if (meter) { if ((pos = lseek(0, (off_t)0, SEEK_CUR)) < 0) meter = 0; else { if (lseek(0, (off_t)(-4), SEEK_END) < 0 || read(0, num, 4) != 4) meter = 0; else if (!(total = ((num[0]|(num[1]<<8)|(num[2]<<16)|(num[3]<<24)) + sizeof(Header_t) - 1) / sizeof(Header_t))) total = 1; lseek(0, pos, SEEK_SET); } } /* * loop on all the header blocks */ while (block(stdin, gz, (char*)&header)) { /* * last 2 blocks are NULL */ if (!*header.name) break; /* * verify the checksum */ s = header.chksum; e = header.chksum + sizeof(header.chksum); if (a2x) { for (; s < e; s++) *s = a2x[*(unsigned char*)s]; s = header.chksum; } n = number(s) & TAR_SUMASK; while (s < e) *s++ = 040; m = 0; s = (char*)&header; e = (char*)&header + sizeof(header); while (s < e) m += *(unsigned char*)s++; m &= TAR_SUMASK; if (m != n) { if (state.files) fprintf(stderr, "%s: archive corrupted\n", state.id); else fprintf(stderr, "%s: not a tar archive\n", state.id); fprintf(stderr, "check sum %lu != %lu\n", m, n); EXIT(1); } /* * convert to the native charset */ if (a2x) for (e = (s = (char*)&header) + sizeof(header); s < e; s++) *s = a2x[*(unsigned char*)s]; /* * get the pathname, type and size */ state.files++; t = path; if (!strncmp(header.magic, TMAGIC, sizeof(header.magic)) && *header.prefix) { s = header.prefix; e = header.prefix + sizeof(header.prefix); while (s < e && (c = *s++)) *t++ = c; *t++ = '/'; } s = header.name; e = header.name + sizeof(header.name); while (s < e && (c = *s++)) *t++ = c; *t = 0; /* * verify the dir prefix */ t = 0; s = path; while (*s) if (*s++ == '/') t = s; if (t) { *--t = 0; if (!list && access(path, 0)) { s = path; do { if (!(c = *s) || c == '/') { *s = 0; if (access(path, 0) && mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) { fprintf(stderr, "%s: %s: cannot create directory\n", state.id, path); EXIT(1); } *s = c; } } while (*s++); } if (*(t + 1)) *t = '/'; else header.typeflag = DIRTYPE; } /* * check for non-local paths */ if (local && (path[0] == '/' || path[0] == '.' && path[1] == '.' && (!path[2] || path[2] == '/'))) { fprintf(stderr, "%s: %s: non-local path rejected", state.id, path); if ((header.typeflag == REGTYPE || header.typeflag == AREGTYPE) && (n = number(header.size))) while (n > 0) { if (!block(stdin, gz, buf)) { fprintf(stderr, "%s: unexpected EOF\n", state.id); EXIT(1); } if (n <= sizeof(header)) break; n -= sizeof(header); } continue; } /* * create and grab the data */ n = number(header.mode); mode = 0; if (n & TUREAD) mode |= S_IRUSR; if (n & TUWRITE) mode |= S_IWUSR; if (n & TUEXEC) mode |= S_IXUSR; if (n & TGREAD) mode |= S_IRGRP; if (n & TGWRITE) mode |= S_IWGRP; if (n & TGEXEC) mode |= S_IXGRP; if (n & TOREAD) mode |= S_IROTH; if (n & TOWRITE) mode |= S_IWOTH; if (n & TOEXEC) mode |= S_IXOTH; if (list || meter) { if (meter) { int i; int j; int k; int n; int p; char bar[METER_parts + 1]; for (s = path; *s; s++) if (s[0] == ' ' && s[1] == '-' && s[2] == '-' && s[3] == ' ') break; if (*s) { if (clear) { fprintf(stderr, "%*s", clear, "\r"); clear = 0; } fprintf(stderr, "\n%s\n\n", path); } else { n = (int)strlen(s = path); p = (state.blocks * 100) / total; if (n > (METER_width - METER_parts - 1)) { s += n - (METER_width - METER_parts - 1); n = METER_width - METER_parts - 1; } j = n + METER_parts + 2; if (!clear) clear = j + 5; if ((k = clear - j - 5) < 0) k = 0; if ((i = (p / (100 / METER_parts))) >= sizeof(bar)) i = sizeof(bar) - 1; n = 0; while (n < i) bar[n++] = '*'; while (n < sizeof(bar) - 1) bar[n++] = ' '; bar[n] = 0; clear = fprintf(stderr, "%02d%% |%s| %s%*s", p, bar, s, k, "\r"); } } else { if (verbose) { switch (header.typeflag) { case REGTYPE: case AREGTYPE: c = '-'; break; case DIRTYPE: c = 'd'; break; case LNKTYPE: c = 'h'; break; case SYMTYPE: c = 'l'; break; default: c = '?'; break; } printf("%c", c); m = 0400; while (m) { printf("%c", (n & m) ? 'r' : '-'); m >>= 1; printf("%c", (n & m) ? 'w' : '-'); m >>= 1; printf("%c", (n & m) ? 'x' : '-'); m >>= 1; } printf(" %10lu ", number(header.size)); } switch (header.typeflag) { case LNKTYPE: printf("%s == %s\n", path, header.linkname); break; case SYMTYPE: printf("%s => %s\n", path, header.linkname); break; default: printf("%s\n", path); break; } } if (list) { if (skip(stdin, gz, buf, number(header.size))) EXIT(1); continue; } } else if (verbose) printf("%s\n", path); switch (header.typeflag) { case REGTYPE: case AREGTYPE: while (!(fp = fopen(path, FOPEN_WRITE))) if (unlink(path)) { fprintf(stderr, "%s: warning: %s: cannot create file\n", state.id, path); break; } n = number(header.size); c = a2x ? 0 : -1; while (n > 0) { if (!block(stdin, gz, buf)) { fprintf(stderr, "%s: unexpected EOF\n", state.id); EXIT(1); } switch (c) { case 0: if ((m = n) < 4) { for (e = (s = buf) + m; s < e; s++) if (a2x[*(unsigned char*)s] != '\n') break; } else { if (m > 256) m = 256; for (e = (s = buf) + m; s < e; s++) if (!ascii_text[*(unsigned char*)s]) break; } if (s < e) { c = -1; break; } c = 1; /* FALLTHROUGH */ case 1: for (e = (s = buf) + sizeof(header); s < e; s++) *s = a2x[*(unsigned char*)s]; break; } if (fp && fwrite(buf, n > sizeof(header) ? sizeof(header) : n, 1, fp) != 1) { fprintf(stderr, "%s: %s: write error\n", state.id, path); EXIT(1); } if (n <= sizeof(header)) break; n -= sizeof(header); } if (fp && fclose(fp)) { fprintf(stderr, "%s: %s: write error\n", state.id, path); EXIT(1); } break; case DIRTYPE: if (access(path, 0) && mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) { fprintf(stderr, "%s: %s: cannot create directory\n", state.id, path); EXIT(1); } break; case SYMTYPE: #if defined(S_IFLNK) || defined(S_ISLNK) while (symlink(header.linkname, path)) if (unlink(path)) { fprintf(stderr, "%s: %s: cannot symlink to %s\n", state.id, path, header.linkname); EXIT(1); } continue; #endif #if !_WIN32 || _WINIX case LNKTYPE: while (link(header.linkname, path)) if (unlink(path)) { fprintf(stderr, "%s: %s: cannot link to %s\n", state.id, path, header.linkname); EXIT(1); } continue; #endif default: fprintf(stderr, "%s: %s: file type %c ignored\n", state.id, path, header.typeflag); if (skip(stdin, gz, buf, number(header.size))) EXIT(1); continue; } if (chmod(path, mode)) fprintf(stderr, "%s: %s: cannot change mode to %03o\n", state.id, path, mode); } if (clear) fprintf(stderr, "%*s", clear, "\r"); if (!state.files) fprintf(stderr, "%s: warning: empty archive\n", state.id); else if (verbose) fprintf(stderr, "%lu file%s, %lu block%s\n", state.files, state.files == 1 ? "" : "s", state.blocks, state.blocks == 1 ? "" : "s"); #if defined(_SEAR_EXEC) #if !defined(_SEAR_ARGS) #define _SEAR_ARGS 0 #endif if (install && sear_exec(_SEAR_EXEC, argv, _SEAR_ARGS, install)) { Sleep(2 * 1000); return 1; } #endif return 0; } #endif /* _RATZ_C */ ksh-1.0.0-beta.2/src/cmd/INIT/regress.sh000066400000000000000000001034511415700074400174570ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2012 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : regress - run regression tests in command.tst command=regress case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in 0123) USAGE=$' [-? @(#)$Id: regress (AT&T Research) 2012-02-02 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 1995-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?regress - run regression tests] [+DESCRIPTION?\bregress\b runs the tests in \aunit\a, or \aunit\a\b.tst\b if \aunit\a does not exist. If \acommand\a is omitted then it is assumed to be the base name of \aunit\a. All testing is done in the temporary directory \aunit\a\b.tmp\b.] [+?Default test output lists the \anumber\a and \adescription\a for each active \bTEST\b group and the \anumber\a:\aline\a for each individual \bEXEC\b test. Each test that fails results in a diagnostic that contains the word \bFAILED\b; no other diagnostics contain this word.] [b:ignore-space?Ignore space differences when comparing expected output.] [i:pipe-input?Repeat each test with the standard input redirected through a pipe.] [k:keep?Enable \bcore\b dumps, exit after the first test that fails, and do not remove the temporary directory \aunit\a\b.tmp\b.] [l:local-fs?Force \aunit\a\b.tmp\b to be in a local filesystem.] [o:pipe-output?Repeat each test with the standard output redirected through a pipe.] [p:pipe-io?Repeat each test with the standard input and standard output redirected through pipes.] [q:quiet?Output information on \bFAILED\b tests only.] [r!:regular?Run each test with the standard input and standard output redirected through regular files.] [t:test?Run only tests matching \apattern\a. Tests are numbered and consist of at least two digits (0 filled if necessary). Tests matching \b+(0)\b are always run.]:[pattern] [x:trace?Enable debug tracing.] [v:verbose?List differences between actual (<) and expected (>) output, errors and exit codes. Also disable long output line truncation.] unit [ command [ arg ... ] ] [+INPUT FILES?The regression test file \aunit\a\b.tst\b is a \bksh\b(1) script that is executed in an environment with the following functions defined:] { [+BODY \b{ ... }?Defines the test body; used for complex tests.] [+CD \b\adirectory\a?Create and change to working directory for one test.] [+CLEANUP \b\astatus\a?Called at exit time to remove the temporary directory \aunit\a\b.tmp\b, list the tests totals via \bTALLY\b, and exit with status \astatus\a.] [+COMMAND \b\aarg\a ...?Runs the current command under test with \aarg\a ... appended to the default args.] [+CONTINUE?The background job must be running.] [+COPY \b\afrom to\a?Copy file \afrom\a to \ato\a. \afrom\a may be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post test comparisons are still done for \afrom\a.] [+DIAGNOSTICS \b[ \b1\b | \b0\b | \apattern\a ]]?No argument or an argument of \b1\b declares that diagnostics are to expected for the remainder of the current \bTEST\b; \b0\b reverts to the default state that diagnostics are not expected; otherwise the argument is a \bksh\b(1) pattern that must match the non-empty contents of the standard error.] [+DO \b\astatement\a?Defines additional statements to be executed for the current test. \astatement\a may be a { ... } group.] [+EMPTY \bINPUT|OUTPUT|ERROR|SAME?The corresponding file is expected to be empty.] [+ERROR \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The standard error is expected to match either the contents of \afile\a or the line \adata\a. \bERROR -n\b does not append a newline to \adata\a. \afilter\a is a shell command or pipeline that reads standard input and writes standard output that is applied to ERROR before comparison with the expected contents.] [+EXEC \b[ \aarg\a ... ]]?Runs the command under test with optional arguments. \bINPUT\b, \bOUTPUT\b, \bERROR\b, \bEXIT\b and \bSAME\b calls following this \bEXEC\b up until the next \bEXEC\b or the end of the script provide details for the expected results. If no arguments are specified then the arguments from the previous \bEXEC\b in the current \bTEST\b group are used, or no arguments if this is the first \bEXEC\b in the group.] [+EXIT \b\astatus\a?The command exit status is expected to match the pattern \astatus\a.] [+EXITED?The background job must have exited.] [+EXPORT \b[-]] \aname\a=\avalue\a ...?Export environment variables for one test.] [+FATAL \b\amessage\a ...?\amessage\a is printed on the standard error and \bregress\b exits with status \b1\b.] [+FIFO \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The \bIO\B file is a fifo.] [+IF \b\acommand\a [\anote\a]]?If the \bsh\b(1) \acommand\a exits 0 then tests until the next \bELIF\b, \bELSE\b or \bFI\b are enabled. Otherwise those tests are skipped. \bIF\b ... \bFI\b may be nested, but must not cross \bTEST\b boundaries. \anote\a is listed on the standard error if the corresponding test block is enabled; \bIF\b, \bELIF\b, \bELSE\b may nave a \anote\a operand.] [+IGNORE \b\afile\a ...?\afile\a is ignored for subsequent result comparisons. \afile\a may be \bOUTPUT\b or \bERROR\b.] [+IGNORESPACE?Ignore space differences when comparing expected output.] [+INCLUDE \b\afile\a ...?One or more \afile\a operands are read via the \bksh\b(1) \b.\b(1) command. \bVIEW\b is used to locate the files.] [+INFO \b\adescription\a?\adescription\a is printed on the standard error.] [+INITIALIZE?Called by \bregress\b to initialize a each \bTEST\b group.] [+INPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The standard input is set to either the contents of \afile\a or the line \adata\a. \bINPUT -n\b does not append a newline to \adata\a. \afilter\a is a shell command or pipeline that reads standard input and writes standard output that is applied to OUTPUT before comparison with the expected contents.] [+INTRO?Called by \bregress\b to introduce all \bTEST\b groups.] [+IO \b[ \bFIFO\b | \bPIPE\b ]] \bINPUT|OUTPUT|ERROR\b [ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?Internal support for the \bINPUT\b, \bOUTPUT\b and \bERROR\b functions.] [+JOB \b\aop\a [ ... ]]?Like \bEXEC\b except the command is run as a background job for the duration of the group or until it is killed via \bKILL\b.] [+KEEP \b\apattern\a ...?The temporary directory is cleared for each test. Files matching \apattern\a are retained between tests.] [+KILL \b[ \asignal\a ]]?Kill the background job with \asignal\a [ \bSIGKILL\b ]].] [+MOVE \b\afrom to\a?Rename file \afrom\a to \ato\a. \afrom\a may be a regular file or \bINPUT\b, \bOUTPUT\b or \bERROR\b. Post test comparisons are ignored for \afrom\a.] [+NOTE \b\acomment\a?\acomment\a is added to the current test trace output.] [+OUTPUT \b[ \b-e\b \afilter\a ]] [ \b-n\b ]] \afile\a | - \adata\a ...?The standard output is expected to match either the contents of \afile\a or the line \adata\a. \bOUTPUT -n\b does not append a newline to \adata\a. \afilter\a is a shell command or pipeline that reads standard input and writes standard output that is applied to ERROR before comparison with the expected contents.] [+PIPE \bINPUT|OUTPUT|ERROR\b [ \b-n\b ]] \afile\a | - \adata\a ...?The \bIO\B file is a pipe.] [+PROG \b\acommand\a [ \aarg\a ... ]]?\acommand\a is run with optional arguments.] [+REMOVE \b\afile\a ...?\afile\a ... are removed after the current test is done.] [+RUN?Called by \bregress\b to run the current test.] [+SAME \b\anew old\a?\anew\a is expected to be the same as \aold\a after the current test completes.] [+SET \b[\bno\b]]\aname\a[=\avalue\a]]?Set the command line option --\aname\a. The setting is in effect for all tests until the next explicit \bSET\b.] [+TALLY?Called by \bregress\b display the \bTEST\b results.] [+TEST \b\anumber\a [ \adescription\a ... ]]?Define a new test group labelled \anumber\a with optional \adescription\a.] [+TITLE \b[+]] \atext\a?Set the \bTEST\b output title to \atext\a. If \b+\b is specified then \atext\a is appended to the default title. The default title is the test file base name, and, if different from the test file base name, the test unit base name.] [+TWD \b[ \adir\a ... ]]?Set the temporary test dir to \adir\a. The default is \aunit\a\b.tmp\b, where \aunit\a is the test input file sans directory and suffix. If \adir\a matches \b/*\b then it is the directory name; if \adir\a is non-null then the prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is omitted then \b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is used.] [+UMASK \b[ \amask\a ]]?Run subsequent tests with \bumask\b(1) \amask\a. If \amask\a is omitted then the original \bumask\b is used.] [+UNIT \b\acommand\a [ \aarg\a ... ]]?Define the command and optional default arguments to be tested. \bUNIT\b explicitly overrides the default command name derived from the test script file name. A \acommand\a operand with optional arguments overrides the \bUNIT\b \acommand\a and arguments, with the exception that if the \bUNIT\b \acommand\a is \b-\b or \b+\b the \bUNIT\b arguments are appended to the operand or default unit command and arguments.] [+VIEW \b\avar\a [ \afile\a ]]?\avar\a is set to the full pathname of \avar\a [ \afile\a ]] in the current \b$VPATH\b view if defined.] } [+SEE ALSO?\bnmake\b(1), \bksh\b(1)] ' ;; *) USAGE='ko:[[no]name[=value]]t:[test]v unit [path [arg ...]]' ;; esac function FATAL # message { print -r -u2 "$command: $*" GROUP=FINI exit 1 } function EMPTY { typeset i typeset -n ARRAY=$1 for i in ${!ARRAY[@]} do unset ARRAY[$i] done } function INITIALIZE # void { typeset i j cd "$TWD" case $KEEP in "") RM * ;; *) for i in * do case $i in !($KEEP)) j="$j $i" ;; esac done case $j in ?*) RM $j ;; esac ;; esac : >INPUT >OUTPUT.ex >ERROR.ex BODY="" COPY="" DIAGNOSTICS="" DONE="" ERROR="" EXIT=0 IGNORE="" INIT="" INPUT="" MOVE="" OUTPUT="" EMPTY FILE EMPTY FILTER EMPTY SAME EMPTY TYPE } function INTRO { typeset base command if [[ ! $TEST_quiet ]] then base=${REGRESS##*/} base=${base%.tst} command=${COMMAND##*/} command=${command%' '*} set -- $TITLE TITLE= case $1 in ''|+) if [[ $command == $base ]] then TITLE=$COMMAND else TITLE="$COMMAND, $base" fi if (( $# )) then shift fi ;; esac while (( $# )) do if [[ $TITLE ]] then TITLE="$TITLE, $1" else TITLE="$1" fi shift done print -u2 "TEST $TITLE" fi } function TALLY # extra message text { typeset msg case $GROUP in INIT) ;; *) msg="TEST $TITLE, $TESTS test" case $TESTS in 1) ;; *) msg=${msg}s ;; esac msg="$msg, $ERRORS error" case $ERRORS in 1) ;; *) msg=${msg}s ;; esac if (( $# )) then msg="$msg, $*" fi print -u2 "$msg" GROUP=INIT TESTS=0 ERRORS=0 ;; esac } function TITLE # text { TITLE=$@ } function UNWIND { while (( COND > 1 )) do print -r -u2 "$command: line $LINE: no matching FI for IF on line ${COND_LINE[COND]}" (( COND-- )) done if (( COND > 0 )) then (( COND = 0 )) FATAL "line $LINE: no matching FI for IF on line ${COND_LINE[COND+1]}" fi if [[ $JOBPID ]] then if [[ $JOBPID != 0 ]] then kill -KILL $JOBPID 2>/dev/null wait fi JOBPID= fi JOBSTATUS= JOBOP= wait } function CLEANUP # status { typeset note if [[ $GROUP != INIT ]] then if [[ ! $TEST_keep ]] then cd $SOURCE if [[ $TEST_local ]] then RM ${TEST_local} fi RM "$TWD" fi if (( $1 )) && [[ $GROUP != FINI ]] then note=terminated fi fi TALLY $note [[ $TEST_keep ]] || UNWIND exit $1 } function RUN # [ op ] { typeset i r=1 [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG #print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM FLUSHED=$FLUSHED JOBOP=$JOBOP case $GROUP in INIT) RM "$TWD" if [[ $TEST_local ]] then TEST_local=${TMPDIR:-/tmp}/rt-$$/${TWD##*/} mkdir -p "$TEST_local" && ln -s "$TEST_local" "$TWD" || FATAL "$TWD": cannot create directory TEST_local=${TEST_local%/*} else mkdir "$TWD" || FATAL "$TWD": cannot create directory fi cd "$TWD" TWD=$PWD : > rmu if rm -u rmu >/dev/null 2>&1 then TEST_rmu=-u else rm rmu fi if [[ $UNIT ]] then set -- "${ARGV[@]}" case $1 in ""|[-+]*) UNIT $UNIT "${ARGV[@]}" ;; *) UNIT "${ARGV[@]}" ;; esac fi INTRO ;; FINI) ;; $TEST_select) if [[ $ITEM == $FLUSHED ]] then return 0 fi FLUSHED=$ITEM if (( COND_SKIP[COND] )) then return 1 fi ((COUNT++)) if (( $ITEM <= $LASTITEM )) then LABEL=$TEST#$COUNT else LASTITEM=$ITEM LABEL=$TEST:$ITEM fi TEST_file="" exec >/dev/null for i in $INPUT do case " $OUTPUT " in *" $i "*) if [[ -f $i.sav ]] then cp $i.sav $i COMPARE="$COMPARE $i" elif [[ -f $i ]] then cp $i $i.sav COMPARE="$COMPARE $i" fi ;; esac done for i in $OUTPUT do case " $COMPARE " in *" $i "*) ;; *) COMPARE="$COMPARE $i" ;; esac done for i in $INIT do $i $TEST INIT done #print -u2 AHA#$LINENO $0 GROUP=$GROUP ITEM=$ITEM JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS if [[ $JOBPID != 0 && ( $JOBPID || $JOBSTATUS ) ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi RESULTS elif [[ $BODY ]] then SHOW=$NOTE if [[ ! $TEST_quiet ]] then print -r -u2 " $SHOW" fi for i in $BODY do $i $TEST BODY done else SHOW= if [[ ${TYPE[INPUT]} == PIPE ]] then if [[ ${TYPE[OUTPUT]} == PIPE ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi cat <$TWD/INPUT | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT RESULTS 'pipe input' else if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi cat <$TWD/INPUT | COMMAND "${ARGS[@]}" >$TWD/OUTPUT RESULTS 'pipe io' fi elif [[ ${TYPE[OUTPUT]} == PIPE ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT RESULTS 'pipe output' else if [[ $TEST_regular ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi if [[ ${TYPE[INPUT]} == FIFO ]] then COMMAND "${ARGS[@]}" >$TWD/OUTPUT else COMMAND "${ARGS[@]}" <$TWD/INPUT >$TWD/OUTPUT fi RESULTS fi if [[ $TEST_pipe_input ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi (trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" >$TWD/OUTPUT STATUS=$? RESULTS 'pipe input' fi if [[ $TEST_pipe_output ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi COMMAND "${ARGS[@]}" <$TWD/INPUT | cat >$TWD/OUTPUT STATUS=$? RESULTS 'pipe output' fi if [[ $TEST_pipe_io ]] then if [[ ! $TEST_quiet ]] then print -nu2 "$LABEL" fi (trap '' PIPE; cat <$TWD/INPUT 2>/dev/null; exit 0) | COMMAND "${ARGS[@]}" | cat >$TWD/OUTPUT STATUS=$? RESULTS 'pipe io' fi fi set -- $COPY COPY="" while : do case $# in 0|1) break ;; *) cp $1 $2 ;; esac shift 2 done set -- $MOVE MOVE="" while (( $# > 1 )) do mv $1 $2 shift 2 done fi for i in $DONE do $i $TEST DONE $STATUS done COMPARE="" r=0 ;; esac if [[ $COMMAND_ORIG ]] then COMMAND=$COMMAND_ORIG COMMAND_ORIG= ARGS=(${ARGS_ORIG[@]}) fi return $r } function DO # cmd ... { [[ $GROUP == $TEST_select ]] || return 1 (( COND_SKIP[COND] )) && return 1 [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK return 0 } function UNIT # cmd arg ... { typeset cmd=$1 case $cmd in [-+]) shift if (( UNIT_READONLY )) then COMMAND="$COMMAND $*" else #BUG# ARGV=("${ARGV[@]}" "$@") set -- "${ARGV[@]}" "$@" ARGV=("$@") fi return ;; esac (( UNIT_READONLY )) && return if [[ $UNIT ]] && (( $# <= 1 )) then set -- "${ARGV[@]}" case $1 in "") set -- "$cmd" ;; [-+]*) set -- "$cmd" "${ARGV[@]}" ;; *) cmd=$1 ;; esac fi UNIT= COMMAND=$cmd shift typeset cmd=$(whence $COMMAND) if [[ ! $cmd ]] then FATAL $COMMAND: not found elif [[ ! $cmd ]] then FATAL $cmd: not found fi case $# in 0) ;; *) COMMAND="$COMMAND $*" ;; esac } function TWD # [ dir ] { case $1 in '') TWD=${TWD##*/}; TWD=${TMPDIR:-/tmp}/tst-${TWD%.*}-$$-$RANDOM ;; /*) TWD=$1 ;; *) TWD=${TMPDIR:-/tmp}/$1 ;; esac } function TEST # number description arg ... { RUN LINE=$TESTLINE UNWIND COUNT=0 LASTITEM=0 case $1 in -) ((LAST++)); TEST=$LAST ;; +([0123456789])) LAST=$1 TEST=$1 ;; *) LAST=0${1/[!0123456789]/} TEST=$1 ;; esac NOTE= if [[ ! $TEST_quiet && $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] )) then print -r -u2 "$TEST $2" fi unset ARGS unset EXPORT EXPORTS=0 TEST_file="" if [[ $TEST != ${GROUP}* ]] then GROUP=${TEST%%+([abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ])} if [[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] )) then INITIALIZE fi fi ((SUBTESTS=0)) [[ $TEST == $TEST_select ]] && (( ! COND_SKIP[COND] )) } function EXEC # arg ... { if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi if ((SUBTESTS++)) then RUN fi case $# in 0) set -- "${ARGS[@]}" ;; esac ITEM=$LINE NOTE="$(print -r -f '%q ' -- $COMMAND_ORIG "$@")${JOBPID:+&}" ARGS=("$@") } function JOB # arg ... { JOBPID=0 EXEC "$@" } function CONTINUE { RUN || return JOBOP=CONTINUE ITEM=$LINE NOTE="$(print -r -f '%q ' -- $JOBOP)" #print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE } function EXITED { RUN || return JOBOP=EXITED ITEM=$LINE NOTE="$(print -r -f '%q ' -- $JOBOP)" #print -u2 AHA#$LINENO JOBOP=$JOBOP ITEM=$ITEM NOTE=$NOTE } function KILL # [ signal ] { RUN || return JOBOP=$2 [[ $JOBOP ]] || JOBOP=KILL ITEM=$LINE NOTE="$(print -r -f '%q ' -- $JOBOP)" } function CD { RUN if [[ $GROUP == $TEST_select ]] && (( ! COND_SKIP[COND] )) then mkdir -p "$@" && cd "$@" || FATAL cannot initialize working directory "$@" fi } function EXPORT { typeset x n v if [[ $GROUP == INIT ]] then for x do n=${x%%=*} v=${x#*=} ENVIRON[ENVIRONS++]=$n="'$v'" done else RUN if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi for x do n=${x%%=*} v=${x#*=} EXPORT[EXPORTS++]=$n="'$v'" done fi } function FLUSH { if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi if ((SUBTESTS++)) then RUN fi } function PROG # cmd arg ... { typeset command args if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi ITEM=$LINE NOTE="$(print -r -f '%q ' -- "$@")" COMMAND_ORIG=$COMMAND COMMAND=$1 shift ARGS_ORIG=(${ARGS[@]}) ARGS=("$@") } function NOTE # description { NOTE=$* } function IO # [ PIPE ] INPUT|OUTPUT|ERROR [-f*|-n] file|- data ... { typeset op i v f file type x if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG while : do case $1 in FIFO|PIPE) type=$1; shift ;; *) break ;; esac done op=$1 shift [[ $type ]] && TYPE[$op]=$type FILTER[$op]= file=$TWD/$op while : do case $1 in -x) x=1 shift ;; -e) (( $# > 1 )) && shift FILTER[$op]=$1 shift ;; -e*) FILTER[$op]=${1#-e} shift ;; -f*|-n) f=$1 shift ;; *) break ;; esac done case $# in 0) ;; *) case $1 in -) ;; *) file=$1 eval i='$'$op case " $i " in *" $file "*) ;; *) eval $op='"$'$op' $file"' ;; esac ;; esac shift ;; esac case " $IGNORE " in *" $file "*) for i in $IGNORE do case $i in $file) ;; *) v="$v $i" ;; esac done IGNORE=$v ;; esac FILE[$op]=$file case $op in OUTPUT|ERROR) file=$file.ex if [[ $file != /* ]] then file=$TWD/$file fi ;; esac #unset SAME[$op] SAME[$op]= if [[ $file == /* ]] then RM $file.sav else RM $TWD/$file.sav fi if [[ $file == */* ]] then mkdir -p ${file%/*} fi if [[ $file != */ ]] then if [[ $type == FIFO ]] then rm -f $file mkfifo $file fi if [[ ${TYPE[$op]} != FIFO ]] then if [[ $JOBOP ]] then case $#:$f in 0:) ;; *:-f) printf -- "$@" ;; *:-f*) printf -- "${f#-f}""$@" ;; *) print $f -r -- "$@" ;; esac >> $file else case $#:$f in 0:) ;; *:-f) printf -- "$@" ;; *:-f*) printf -- "${f#-f}""$@" ;; *) print $f -r -- "$@" ;; esac > $file fi elif [[ $#:$f != 0: ]] then case $#:$f in *:-f) printf -- "$@" ;; *:-f*) printf -- "${f#-f}""$@" ;; *) print $f -r -- "$@" ;; esac >> $file & fi if [[ $x ]] then chmod +x $file fi fi } function INPUT # file|- data ... { IO $0 "$@" } function COPY # from to { if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi COPY="$COPY $@" } function MOVE # from to { typeset f if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi for f do case $f in INPUT|OUTPUT|ERROR) f=$TWD/$f ;; /*) ;; *) f=$PWD/$f ;; esac MOVE="$MOVE $f" done } function SAME # new old { typeset i file v if [[ $GROUP != $TEST_select ]] || (( COND_SKIP[COND] )) then return fi case $# in 2) case $1 in INPUT) cat $2 > $1; return ;; esac SAME[$1]=$2 file=$1 COMPARE="$COMPARE $1" ;; 3) SAME[$2]=$3 file=$2 eval i='$'$1 case " $i " in *" $2 "*) ;; *) eval $1='"$'$1' $2"' ;; esac COMPARE="$COMPARE $2" ;; esac case " $IGNORE " in *" $file "*) for i in $IGNORE do case $i in $file) ;; *) v="$v $i" ;; esac done IGNORE=$v ;; esac } function OUTPUT # file|- data ... { IO $0 "$@" } function ERROR # file|- data ... { IO $0 "$@" } function RM # rm(1) args { if [[ ! $TEST_rmu ]] then chmod -R u+rwx "$@" >/dev/null 2>&1 fi rm $TEST_rmu $TEST_rmflags "$@" } function REMOVE # file ... { typeset i for i do RM $i $i.sav done } function IGNORE # file ... { typeset i for i do case $i in INPUT|OUTPUT|ERROR) i=$TWD/$i ;; esac case " $IGNORE " in *" $i "*) ;; *) IGNORE="$IGNORE $i" ;; esac done } function KEEP # pattern ... { typeset i for i do case $KEEP in "") KEEP="$i" ;; *) KEEP="$KEEP|$i" ;; esac done } function DIAGNOSTICS # [ 1 | 0 ] { case $#:$1 in 0:|1:1) DIAGNOSTICS=1 EXIT='*' ;; 1:|1:0) DIAGNOSTICS="" EXIT=0 ;; *) DIAGNOSTICS=$1 EXIT='*' ;; esac } function IGNORESPACE { : ${IGNORESPACE=-b} } function EXIT # status { EXIT=$1 } function INFO # info description { typeset -R15 info=$1 if [[ ! $1 ]] then info=no fi shift if [[ ! $TEST_quiet ]] then print -r -u2 "$info " "$@" fi } function COMMAND # arg ... { typeset input ((TESTS++)) case " ${ENVIRON[*]} ${EXPORT[*]}" in *' 'LC_ALL=*) ;; *' 'LC_+([A-Z])=*) EXPORT[EXPORTS++]="LC_ALL=" ;; esac if [[ $TEST_keep ]] then ( PS4='' set -x print -r -- "${ENVIRON[@]}" "${EXPORT[@]}" "PATH=$PATH" $COMMAND "$@" ) 2>&1 >/dev/null | sed -e 's,^print -r -- ,,' -e 's,$, "$@",' >$TWD/COMMAND chmod +x $TWD/COMMAND fi if [[ $UMASK != $UMASK_ORIG ]] then : >$TWD/ERROR umask $UMASK fi if [[ ${TYPE[INPUT]} == FIFO && ${FILE[INPUT]} == */INPUT ]] then input="< ${FILE[INPUT]}" fi if [[ $TEST_trace ]] then set +x eval print -u2 "$PS4" "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' '$input' '"2>$TWD/ERROR"' '"${JOBPID:+&}"' fi eval "${ENVIRON[@]}" "${EXPORT[@]}" PATH='$PATH' '$'COMMAND '"$@"' $input "2>$TWD/ERROR" "${JOBPID:+&}" STATUS=$? [[ $TEST_trace ]] && set -x if [[ $JOBPID ]] then JOBPID=$! fi [[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG return $STATUS } function RESULTS # pipe* { typeset i j k s failed ignore io op if [[ $1 ]] then io="$1 " fi [[ $JOBOP || $JOBPID || $JOBSTATUS ]] && sleep 1 for i in $COMPARE $TWD/OUTPUT $TWD/ERROR do case " $IGNORE $ignore $MOVE " in *" $i "*) continue ;; esac ignore="$ignore $i" op=${i##*/} if [[ ${FILTER[$op]} ]] then eval "{ ${FILTER[$op]} ;} < $i > $i.fi" mv $i.fi $i fi j=${SAME[$op]} if [[ ! $j ]] then if [[ $i == /* ]] then k=$i else k=$TWD/$i fi for s in ex sav err do [[ -f $k.$s ]] && break done j=$k.$s fi if [[ "$DIAGNOSTICS" && $i == */ERROR ]] then if [[ $STATUS == 0 && ! -s $TWD/ERROR || $DIAGNOSTICS != 1 && $(<$i) != $DIAGNOSTICS ]] then failed=$failed${failed:+,}DIAGNOSTICS if [[ $TEST_verbose && $DIAGNOSTICS != 1 ]] then print -u2 " ===" "diagnostic pattern '$DIAGNOSTICS' did not match" ${i#$TWD/} "===" cat $i >&2 fi fi continue fi diff $IGNORESPACE $i $j >$i.diff 2>&1 if [[ -s $i.diff ]] then failed=$failed${failed:+,}${i#$TWD/} if [[ $TEST_verbose ]] then print -u2 " ===" diff $IGNORESPACE ${i#$TWD/} "expected ===" cat $i.diff >&2 fi fi done if [[ $JOBOP ]] then if [[ $JOBPID ]] && ! kill -0 $JOBPID 2>/dev/null then wait $JOBPID JOBSTATUS=$? JOBPID= fi #print -u2 AHA#$LINENO JOBOP=$JOBOP JOBPID=$JOBPID JOBSTATUS=$JOBSTATUS case $JOBOP in CONTINUE) if [[ ! $JOBPID ]] then failed=$failed${failed:+,}EXITED fi ;; EXITED) if [[ $JOBPID ]] then failed=$failed${failed:+,}RUNNING fi ;; *) if [[ ! $JOBPID ]] then failed=$failed${failed:+,}EXITED fi if ! kill -$JOBOP $JOBPID 2>/dev/null then failed=$failed${failed:+,}KILL-$JOBOP fi ;; esac JOBOP= fi if [[ ! $failed && $STATUS != $EXIT ]] then failed="exit code $EXIT expected -- got $STATUS" fi if [[ $failed ]] then ((ERRORS++)) if [[ ! $TEST_quiet ]] then SHOW="FAILED ${io}[ $failed ] $NOTE" print -r -u2 " $SHOW" fi if [[ $TEST_keep ]] then GROUP=FINI exit fi elif [[ ! $TEST_quiet ]] then SHOW=$NOTE print -r -u2 " $SHOW" fi } function SET # [no]name[=value] { typeset i r if [[ $TEST ]] then RUN fi for i do if [[ $i == - ]] then r=1 elif [[ $i == + ]] then r= else if [[ $i == no?* ]] then i=${i#no} v= elif [[ $i == *=* ]] then v=${i#*=} if [[ $v == 0 ]] then v= fi i=${i%%=*} else v=1 fi i=${i//-/_} if [[ $r ]] then READONLY[$i]=1 elif [[ ${READONLY[$i]} ]] then continue fi eval TEST_$i=$v fi done } function VIEW # var [ file ] { nameref var=$1 typeset i bwd file pwd view root offset if [[ $var ]] then return 0 fi case $# in 1) file=$1 ;; *) file=$2 ;; esac pwd=${TWD%/*} bwd=${PMP%/*} if [[ -r $file ]] then if [[ ! -d $file ]] then var=$PWD/$file return 0 fi for i in $file/* do if [[ -r $i ]] then var=$PWD/$file return 0 fi break done fi for view in ${VIEWS[@]} do case $view in /*) ;; *) view=$pwd/$view ;; esac case $offset in '') case $pwd in $view/*) offset=${pwd#$view} ;; *) offset=${bwd#$view} ;; esac ;; esac if [[ -r $view$offset/$file ]] then if [[ ! -d $view$offset/$file ]] then var=$view$offset/$file return 0 fi for i in $view$offset/$file/* do if [[ -f $i ]] then var=$view$offset/$file return 0 fi break done fi done var= return 1 } function INCLUDE # file ... { typeset f v x for f do if VIEW v $f || [[ $PREFIX && $f != /* ]] && VIEW v $PREFIX$f then x=$x$'\n'". $v" else FATAL $f: not found fi done [[ $x ]] && trap "$x" 0 } function UMASK # [ mask ] { if (( $# )) then UMASK=$1 else UMASK=$UMASK_ORIG fi } function PIPE # INPUT|OUTPUT|ERROR file|- data ... { IO $0 "$@" } function FIFO # INPUT|OUTPUT|ERROR file|- data ... { IO $0 "$@" } function IF # command(s) [note] { [[ $GROUP == $TEST_select ]] || return RUN (( COND++ )) COND_LINE[COND]=$LINE if (( COND > 1 && COND_SKIP[COND-1] )) then (( COND_KEPT[COND] = 1 )) (( COND_SKIP[COND] = 1 )) elif eval "{ $1 ;} >/dev/null 2>&1" then (( COND_KEPT[COND] = 1 )) (( COND_SKIP[COND] = 0 )) [[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE $2" else (( COND_KEPT[COND] = 0 )) (( COND_SKIP[COND] = 1 )) fi } function ELIF # command(s) [note] { [[ $GROUP == $TEST_select ]] || return RUN if (( COND <= 0 )) then FATAL line $LINE: no matching IF for ELIF fi if (( COND_KEPT[COND] )) then (( COND_SKIP[COND] = 0 )) elif eval "$* > /dev/null 2>&1" then (( COND_KEPT[COND] = 1 )) (( COND_SKIP[COND] = 0 )) [[ $2 && ! $TEST_quiet ]] && print -u2 "NOTE $2" else (( COND_SKIP[COND] = 1 )) fi } function ELSE # [note] { [[ $GROUP == $TEST_select ]] || return RUN if (( COND <= 0 )) then FATAL line $LINE: no matching IF for ELSE fi if (( COND_KEPT[COND] )) then (( COND_SKIP[COND] = 1 )) else (( COND_KEPT[COND] = 1 )) (( COND_SKIP[COND] = 0 )) [[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE $1" fi } function FI { [[ $GROUP == $TEST_select ]] || return RUN if (( COND <= 0 )) then FATAL line $LINE: no matching IF for FI on line $LINE fi (( ! COND_KEPT[COND] )) && [[ $1 && ! $TEST_quiet ]] && print -u2 "NOTE $1" (( COND-- )) } # main integer ERRORS=0 ENVIRONS=0 EXPORTS=0 TESTS=0 SUBTESTS=0 LINE=0 TESTLINE=0 integer ITEM=0 LASTITEM=0 COND=0 UNIT_READONLY=0 COUNT typeset ARGS COMMAND COPY DIAGNOSTICS ERROR EXEC FLUSHED=0 GROUP=INIT typeset IGNORE INPUT KEEP OUTPUT TEST SOURCE MOVE NOTE UMASK UMASK_ORIG typeset ARGS_ORIG COMMAND_ORIG TITLE UNIT ARGV PREFIX OFFSET IGNORESPACE typeset COMPARE MAIN JOBPID='' JOBSTATUS='' typeset TEST_file TEST_keep TEST_pipe_input TEST_pipe_io TEST_pipe_output TEST_local typeset TEST_quiet TEST_regular=1 TEST_rmflags='-rf --' TEST_rmu TEST_select typeset -A SAME VIEWS FILE TYPE READONLY FILTER typeset -a COND_LINE COND_SKIP COND_KEPT ENVIRON EXPORT typeset -Z LAST=00 unset FIGNORE while getopts -a $command "$USAGE" OPT do case $OPT in b) (( $OPTARG )) && IGNORESPACE=-b ;; i) SET - pipe-input=$OPTARG ;; k) SET - keep=$OPTARG ;; l) SET - local ;; o) SET - pipe-output=$OPTARG ;; p) SET - pipe-io=$OPTARG ;; q) SET - quiet=$OPTARG ;; r) SET - regular=$OPTARG ;; t) if [[ $TEST_select ]] then TEST_select="$TEST_select|${OPTARG//,/\|}" else TEST_select="${OPTARG//,/\|}" fi ;; x) SET - trace=$OPTARG ;; v) SET - verbose=$OPTARG ;; *) GROUP=FINI exit 2 ;; esac done shift $OPTIND-1 case $# in 0) FATAL test unit name omitted ;; esac export COLUMNS=80 SOURCE=$PWD PATH=$SOURCE:${PATH#?(.):} PATH=${PATH%%:?(.)}:/bin:/usr/bin UNIT=$1 shift if [[ -f $UNIT && ! -x $UNIT ]] then REGRESS=$UNIT else REGRESS=${UNIT%.tst} REGRESS=$REGRESS.tst [[ -f $REGRESS ]] || FATAL $REGRESS: regression tests not found fi UNIT=${UNIT##*/} UNIT=${UNIT%.tst} MAIN=$UNIT if [[ $VPATH ]] then set -A VIEWS ${VPATH//:/' '} OFFSET=${SOURCE#${VIEWS[0]}} if [[ $OFFSET ]] then OFFSET=${OFFSET#/}/ fi fi if [[ $REGRESS == */* ]] then PREFIX=${REGRESS%/*} if [[ ${#VIEWS[@]} ]] then for i in ${VIEWS[@]} do PREFIX=${PREFIX#$i/} done fi PREFIX=${PREFIX#$OFFSET} if [[ $PREFIX ]] then PREFIX=$PREFIX/ fi fi TWD=$PWD/$UNIT.tmp PMP=$(pwd -P)/$UNIT.tmp UMASK_ORIG=$(umask) UMASK=$UMASK_ORIG ARGV=("$@") if [[ ${ARGV[0]} && ${ARGV[0]} != [-+]* ]] then UNIT "${ARGV[@]}" UNIT_READONLY=1 fi trap 'code=$?; CLEANUP $code' EXIT if [[ ! $TEST_select ]] then TEST_select="[0123456789]*" fi TEST_select="@($TEST_select|+(0))" if [[ $TEST_trace ]] then export PS4=':$LINENO: ' typeset -ft $(typeset +f) set -x fi if [[ $TEST_verbose ]] then typeset SHOW else typeset -L70 SHOW fi if [[ ! $TEST_keep ]] && (ulimit -c 0) >/dev/null 2>&1 then ulimit -c 0 fi set --pipefail # some last minute shenanigans alias BODY='BODY=BODY; function BODY' alias CONTINUE='LINE=$LINENO; CONTINUE' alias DO='(( $ITEM != $FLUSHED )) && RUN DO; DO &&' alias DONE='DONE=DONE; function DONE' alias EXEC='LINE=$LINENO; EXEC' alias EXITED='LINE=$LINENO; EXITED' alias INIT='INIT=INIT; function INIT' alias JOB='LINE=$LINENO; JOB' alias KILL='LINE=$LINENO; KILL' alias PROG='LINE=$LINENO; FLUSH; PROG' alias TEST='TESTLINE=$LINENO; TEST' alias IF='LINE=$LINENO; FLUSH; IF' alias ELIF='LINE=$LINENO; FLUSH; ELIF' alias ELSE='LINE=$LINENO; FLUSH; ELSE' alias FI='LINE=$LINENO; FLUSH; FI' # do the tests . $REGRESS RUN GROUP=FINI ksh-1.0.0-beta.2/src/cmd/INIT/rt.sh000066400000000000000000000225031415700074400164300ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## : rt - nmake test output filter command=rt flags='--silent --keepgoing' failed=0 heading=1 verbose=0 case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 0123) ARGV0="-a $command" USAGE=$' [-? @(#)$Id: rt (AT&T Research) 2010-07-27 $ ] [-author?Glenn Fowler ] [-copyright?Copyright (c) 2005-2012 AT&T Intellectual Property] [-license?http://www.eclipse.org/org/documents/epl-v10.html] [+NAME?rt - run "nmake test" and filter output] [+DESCRIPTION?\brt\b runs \bnmake test\b and filters the regression test output to contain only test summary lines. If no \atest\a operands are specified then \btest\b is assumed. If \b-\b is specified then the \afile\a operands, or the standard input if no \afile\a operands are specified, are filtered instead of the output from \bnmake\b.] [f:failed?Only list failed test results.] [h!:heading?Enable per-file heading when more than one \afile\a operand follows \b-\b.] [v:verbose?Run with \bREGRESSFLAGS=-v\b.] [ test ... | - [ file ... ] ] [+SEE ALSO?\bnmake\b(1), \bregress\b(1)] [+CAVEATS?\brt\b guesses the regression test output style. Garbled output indicates a bad guess.] ' ;; *) ARGV0="" USAGE="fhv" ;; esac function usage { OPTIND=0 getopts $ARGV0 "$USAGE" OPT '-?' exit 2 } while getopts $ARGV0 "$USAGE" OPT do case $OPT in f) failed=1 ;; h) heading=0 ;; v) (( verbose=$OPTARG )) && flags="$flags REGRESSFLAGS=-v" ;; esac done shift `expr $OPTIND - 1` ifs=${IFS:-$' \t\n'} set -o noglob component= dots='............................................' bad=' ***' style=unknown integer tests errors signals lineno=0 skip=0 typeset -l lower function results # tests errors signals { integer t=$1 e=$2 s=$3 typeset label note if [[ $style != unknown ]] && (( errors >= 0 )) then style=unknown if (( !failed || errors )) then if (( failed )) then print -r -n -- "$unit" fi if (( t >= 0 )) then if (( t == 1)) then label="test " else label=tests fi printf $'%s%5d %s' "$prefix" "$t" "$label" prefix= else prefix="$prefix..........." fi if (( s )) then label=signal (( e=s )) else label=error fi if (( e != 1)) then label=${label}s fi if (( e == 1 )) then note=" $bad" elif (( e > 1 )) then note=$bad fi printf $'%s%5d %s%s\n' "$prefix" "$e" "$label" "$note" fi fi } function unit { typeset x if [[ $component ]] then x=${component##*/} if [[ " $x " != *' '$unit' '* && " $unit " != *' '$x' '* ]] then if [[ $component == cmd/?*lib/* ]] then unit="$unit $x" else unit="$x $unit" fi fi fi unit="$unit ${dots:1:${#dots}-${#unit}}" if [[ $1 ]] then unit="$unit..........." fi if (( ! failed )) then print -r -n -- "$unit" fi } if [[ $1 == - ]] then shift if (( $# <= 1 )) then heading=0 fi if (( heading )) then for i do print test heading $i cat -- "$i" done else cat "$@" fi else if [[ $1 == *=* ]] then set test "$@" elif (( ! $# )) then set test fi nmake "$@" $flags 2>&1 fi | while read -r line do set '' $line shift case $line in TEST[' ']*', '*' error'*) IFS=${IFS}"," set '' $line IFS=$ifs set '' $* while : do case $2 in '') break ;; error|errors) errors=$1 break ;; test|tests) tests=$1 ;; esac shift done results $tests $errors continue ;; TEST[' ']*) results $tests $errors IFS=${IFS}"," set '' $line IFS=$ifs set '' $* unit=${3##*/} case $4 in [a-zA-Z]*) unit="$unit $4" ;; esac unit prefix= errors=0 signals=0 style=regress continue ;; 'pathname and options of item under test') read -r line || break results $tests $errors $signals set '' $line unit=${2##*/} unit tests=0 errors=0 signals=0 style=script continue ;; 'test heading '*) if (( heading )) then if (( heading > 1 )) then print else heading=2 fi set '' $line shift 3 print -r -- "==> $* <==" fi continue ;; 'test '*' begins at '????-??-??+??:??:??|'test '*' begins at '*' '*' '*' '*' '*) results $tests $errors $signals unit=${2##*/} unit=${unit%.sh} unit prefix= tests=-1 errors=0 signals=0 style=shell continue ;; 'test '*' at '????-??-??+??:??:??' [ '*' ]'|'test '*' at '*' '*' '*' '*' '*) case $line in *' [ '*test*error*' ]') while : do case $1 in '[') tests=$2 errors=$4 if (( errors > 256 )) then (( signals++ )) fi break ;; esac shift done ;; *' [ '*test*signal*' ]') while : do case $1 in '[') tests=$2 signals=$4 if (( signals )) then (( errors++ )) fi break ;; esac shift done ;; *) if [[ $3 != passed ]] then (( errors )) || (( errors++ )) fi ;; esac results $tests $errors $signals continue ;; '## ---'*(-)'--- ##') (( ++lineno > skip )) || continue read -r line || break lower=$line set '' $lower case $lower in '##'*'test suite:'*'##') results $tests $errors $signals set -- ${lower//*suite:} set -- ${*//[.#]/} unit=$* if [[ $unit == *' tests' ]] then unit=${unit/' tests'/} fi main=$unit prefix= tests=0 errors=0 signals=0 category= style=autotest (( skip = lineno + 1 )) unit continue ;; esac ;; +(-)) case $style in regress) continue ;; esac (( ++lineno > skip )) || continue read -r line || break set '' $line case $line in 'Running tests for '*) results $tests $errors $signals shift 4 unit= while (( $# )) do if [[ $1 == on ]] then break fi if [[ $unit ]] then unit="$unit " fi unit=$unit${1##*/} shift done main=$unit prefix= tests=-1 errors=-1 category= style=perl (( skip = lineno + 1 )) continue ;; *' : '*)results $tests $errors $signals unit=${2##*/} unit=${unit%.sh} unit prefix= tests=0 errors=0 signals=0 style=timing (( skip = lineno + 1 )) continue ;; esac ;; +([0-9])*([a-zA-Z0-9])' '*) case $style in script) case $line in *FAILED*|*failed*) (( errors++ )) ;; *) (( tests++ )) ;; esac ;; esac ;; make:*|'make ['*']:'*) case $line in *': warning:'*|*'making test'*|*'action'?(s)' failed'*|*': *** '*) ;; *) results $tests $errors $signals print -r -u2 -- "$line" ;; esac continue ;; +([/a-zA-Z_0-9]):) component=${line%:} ;; '') continue ;; esac case $style in autotest) case $line in +([0-9]):*ok) (( tests++ )) ;; +([0-9]):*FAILED*) (( tests++ )) (( errors++ )) if (( $verbose )) then if [[ ! $prefix ]] then prefix=$unit print fi print -r -- " ${line//*'FAILED '/}" fi ;; esac continue ;; perl) case $line in *'........ '*) if [[ $1 == */* ]] then cat=${1%%/*} if [[ $cat != $category ]] then results $tests $errors $signals category=$cat unit="$main $category" unit prefix= tests=0 errors=0 signals=0 fi (( tests++ )) case $line in *' ok') ;; *) (( errors++ )) if (( $verbose )) then if [[ ! $prefix ]] then prefix=$unit print fi print -r -- "$line" fi ;; esac else results $tests $errors $signals case $line in *' ok') errors=0 ;; *) errors=1 ;; esac unit="$main $1" unit if (( $verbose && errors )) then prefix=$unit print shift 2 print -r -- "$@" else prefix= fi results $tests $errors $signals tests=-1 errors=-1 category= fi style=perl ;; esac continue ;; esac case $line in *FAILED*|*failed*) (( errors++ )) ;; *) case $style in regress)case $line in ['<>']*);; *) continue ;; esac ;; script) continue ;; shell) ((errors++ )) ;; timing) (( tests++ )) continue ;; unknown)continue ;; esac ;; esac if (( $verbose )) then if [[ ! $prefix ]] then prefix=$unit print fi print -r -- "$line" fi done results $tests $errors $signals ksh-1.0.0-beta.2/src/cmd/INIT/silent.sh000066400000000000000000000035331415700074400173030ustar00rootroot00000000000000######################################################################## # # # This software is part of the ast package # # Copyright (c) 1994-2011 AT&T Intellectual Property # # Copyright (c) 2020-2021 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 1.0 # # by AT&T Intellectual Property # # # # A copy of the License is available at # # http://www.eclipse.org/org/documents/epl-v10.html # # (with md5 checksum b35adb5213ca9657e911e9befb180842) # # # # Information and Software Systems Research # # AT&T Research # # Florham Park NJ # # # # Glenn Fowler # # # ######################################################################## # non-ksh stub for the nmake silent prefix # @(#)silent (AT&T Research) 1992-08-11 (command set -o posix) 2>/dev/null && set -o posix modern_export=`v=; export v=ok 2>/dev/null; echo "$v"` while : do case $# in 0) exit 0 ;; esac case $1 in *=*) case $modern_export in ok) export "$1" ;; *) `echo $1 | sed "s/\\([^=]*\\)=\\(.*\\)/eval \\1='\\2'; export \\1/"` ;; esac shift ;; *) break ;; esac done "$@" ksh-1.0.0-beta.2/src/cmd/INIT/socket.c000066400000000000000000000031061415700074400171010ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ /* * small test for -lnsl */ #ifndef socket #include #include #endif int main() { return socket(0, 0, 0) < 0; } ksh-1.0.0-beta.2/src/cmd/INIT/w.c000066400000000000000000000030571415700074400160640ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #ifndef DONTCARE #include #include #endif int main() { wchar_t w = ' '; return iswspace(w) == 0; } ksh-1.0.0-beta.2/src/cmd/INIT/w2.c000066400000000000000000000030031415700074400161350ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1994-2011 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #include int main() { wchar_t w = ' '; return iswspace(w) == 0; } ksh-1.0.0-beta.2/src/cmd/Mamfile000066400000000000000000000013101415700074400161720ustar00rootroot00000000000000info mam static note * note * This build file is in the Make Abstract Machine (MAM) language. It was note * first generated by nmake, but in the ksh 93u+m distribution we maintain note * it manually because nmake had too many problems to keep using. The note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added note * support for indentation to improve readability. The language is note * documented in Glenn Fowler's paper "A Make Abstract Machine": note * http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html note * note component level :MAKE: equivalent make install make all exec - ${MAMAKE} -r '*' ${MAMAKEARGS} done all virtual done install virtual ksh-1.0.0-beta.2/src/cmd/builtin/000077500000000000000000000000001415700074400163505ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/cmd/builtin/Mamfile000066400000000000000000000065341415700074400176550ustar00rootroot00000000000000info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-06-20 note * note * This build file is in the Make Abstract Machine (MAM) language. It was note * first generated by nmake, but in the ksh 93u+m distribution we maintain note * it manually because nmake had too many problems to keep using. The note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added note * support for indentation to improve readability. The language is note * documented in Glenn Fowler's paper "A Make Abstract Machine": note * http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html note * setv INSTALLROOT ../../.. setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast setv PACKAGE_cmd ${INSTALLROOT} setv PACKAGEROOT ../../../../.. setv CC cc setv mam_cc_FLAGS setv KSH_RELFLAGS setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} setv IFFEFLAGS setv LDFLAGS make .INIT make ${PACKAGE_ast_INCLUDE}/cmdlist.h make ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/prototyped.h dontcare done ${PACKAGE_ast_INCLUDE}/cmdlist.h exec - sed -e '/^CMDLIST(.*)$/!d' -e 's/CMDLIST(\(.*\))/\1/' -e '/^getconf$/d' -e '/^ln$/d' -e '/^mv$/d' -e '/^md5sum$/d' -e '/^sum$/d' ${PACKAGE_ast_INCLUDE}/cmdlist.h bind -lcmd done .INIT dontcare virtual make install make pty make pty.o make pty.c make FEATURE/pty implicit meta FEATURE/pty features/%>FEATURE/% features/pty pty make features/pty done features/pty exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libast} ${mam_libcmd} : run features/pty done FEATURE/pty generated make ${PACKAGE_ast_INCLUDE}/ast_time.h implicit done ${PACKAGE_ast_INCLUDE}/ast_time.h prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit prev ${PACKAGE_ast_INCLUDE}/regex.h implicit make ${PACKAGE_ast_INCLUDE}/proc.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/proc.h prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/cmd.h implicit done pty.c meta pty.o %.c>%.o pty.c pty prev pty.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""builtin"\" -D_PACKAGE_ast -DCMD_STANDALONE=b_pty -c pty.c done pty.o generated bind -lutil dontcare exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${CCFLAGS} ${LDFLAGS} -lm ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o pty pty.o ${mam_libutil} ${mam_libast} ${mam_libcmd} done pty generated make ${INSTALLROOT}/bin exec - if silent test ! -d ${INSTALLROOT}/bin exec - then mkdir -p ${INSTALLROOT}/bin exec - fi done ${INSTALLROOT}/bin generated make ${INSTALLROOT}/bin/pty prev pty exec - test '' = 'pty' || ${STDCMP} 2>/dev/null -s pty ${INSTALLROOT}/bin/pty || { ${STDMV} ${INSTALLROOT}/bin/pty ${INSTALLROOT}/bin/pty.old 2>/dev/null || true; ${STDCP} pty ${INSTALLROOT}/bin/pty ;} done ${INSTALLROOT}/bin/pty generated make ${INSTALLROOT}/bin exec - if silent test ! -d ${INSTALLROOT}/bin exec - then mkdir -p ${INSTALLROOT}/bin exec - fi done ${INSTALLROOT}/bin virtual done install virtual ksh-1.0.0-beta.2/src/cmd/builtin/RELEASE000066400000000000000000000007561415700074400173630ustar00rootroot0000000000000012-02-28 pty.c: change --verbose[=level] to --debug=level 12-01-26 pty.c: fix --man docs 10-06-21 pty.c: add 4 sec timeout for initial handshake -- fix me!! 10-04-12 pty: fix sfpoll() result read/write bug 10-04-01 pty: add --tty='stty-settings' 10-03-19 pty: add --dialogue 10-03-15 pty: fix select() fd management 09-03-31 features/pty,Makefile: add pty.h and -lutil refs for Linux -- great, another util library 09-01-30 pty.c: add (for fd_set!! on mvs.390) 06-07-20 pty.c: add ksh-1.0.0-beta.2/src/cmd/builtin/features/000077500000000000000000000000001415700074400201665ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/cmd/builtin/features/pty000066400000000000000000000025441415700074400207320ustar00rootroot00000000000000set prototyped header sys/types.h header pty.h header libutil.h header sys/pty.h header sys/ptyio.h header sys/vty.h header sys/ioctl.h header stropts.h lib openpty,_getpty,ptsname -lutil lib grantpt,unlockpt,posix_openpt stdlib.h lib cfmakeraw termios.h tst - -lm output{ #include #if _lib_ptsname #include #endif #include #include #include #include int main() { int i; struct stat statb; static char* pty[] = { "/dev/ptyp0000", "/dev/ptym/ptyp0", "/dev/ptyp0" }; #if _lib_ptsname int fd; static char* ptc[] = { "/dev/ptmx", "/dev/ptc", "/dev/ptmx_bsd" }; for (i = 0; i < sizeof(ptc) / sizeof(ptc[0]); i++) if((fd = open(ptc[i], 2))>=0) { if (ptsname(fd)) { sfprintf(sfstdout, "#define _pty_clone\t\"%s\"\n", ptc[i]); close(fd); break; } close(fd); } #endif for (i = 0;; i++) if(i >= (sizeof(pty) / sizeof(pty[0]) - 1) || stat(pty[i], &statb)>=0) { sfprintf(sfstdout, "#define _pty_first\t\"%s\"\n", pty[i]); break; } return 0; } }end fail{ echo '#error The output block in src/cmd/builtin/features/pty failed to compile. Rebuild with IFFEFLAGS=-d1 to debug.' }end extern _getpty char* (int*, int, mode_t, int) extern openpty int (int*, int*, char*, struct termios*, struct winsize*) extern ptsname char* (int) ksh-1.0.0-beta.2/src/cmd/builtin/pty.c000066400000000000000000000631001415700074400173300ustar00rootroot00000000000000/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1992-2013 AT&T Intellectual Property * * Copyright (c) 2020-2021 Contributors to ksh 93u+m * * and is licensed under the * * Eclipse Public License, Version 1.0 * * by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.eclipse.org/org/documents/epl-v10.html * * (with md5 checksum b35adb5213ca9657e911e9befb180842) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * David Korn * * * ***********************************************************************/ #pragma prototyped static const char usage[] = "[-?\n@(#)pty (AT&T Research) 2013-05-22\n]" "[-author?Glenn Fowler ]" "[-author?David Korn ]" "[-copyright?Copyright (c) 2001-2013 AT&T Intellectual Property]" "[-license?http://www.eclipse.org/org/documents/epl-v10.html]" "[--catalog?builtin]" "[+NAME?pty - create pseudo terminal and run command]" "[+DESCRIPTION?\bpty\b creates a pseudo pty and then runs \bcommand\b " "with arguments given by \aarg\a and the standard input, standard " "output, and standard error connected to the pseudo terminal. By " "default, the \bpty\b creates a new session.]" "[+?If \bcommand\b does not contain a \b/\b, the \bPATH\b variable will " "be used to locate the \bcommand\b.]" "[+?Input to \bpty\b will be written to the standard input of this " "command. The standard output and standard error from the command will " "be written to the standard output of \bpty\b.]" "[+?The \bpty\b command terminates when the command completes.]" "[d:dialogue?Execute the dialogue on the standard input. A dialogue is a " "sequence of commands, one command per line. All \are\a patterns are " "extended regular expressions. The \are\a \b?1\b will print the subject " "string on the standard error and match the string; the \are\a \b?0\b " "will print the subject string on the standard error and not match the " "string. The \are\a \b?.\b matches EOF. The commands are:]" "{" "[\b#\b \acomment\a?comment line]" "[c \atext\a?write \atext\a to the master; C style escapes " "in text are converted, including \\E for ESC and \\cX for " "control-X]" "[d \amilliseconds\a?set the delay before each master write to " "\amilliseconds\a; the default is no delay]" "[i \are\a?read a line from the master; if it matches \are\a " "then execute lines until matching \be\b or \bf\b]" "[e [re]]?else [if match re]] then execute lines until matching " "\be\b or \bf\b]" "[f?end of \bi\b/\be\b block]" "[m \atext\a?write \atext\a to the standard error]" "[p \atext\a?peek input until \atext\a is found at the beginning " "of a line; input is not consumed]" "[r [\are\a]]?read a line from the master [and it should match " "re]]]" "[s \amilliseconds\a?sleep for \amilliseconds\a]" "[t \amilliseconds\a?set the master read timeout to " "\amilliseconds\a; the default is \b1000\b]" "[u \are\a?read lines from the master until one matches \are\a]" "[v \alevel\a?set the verbose trace \alevel\a, more output for " "higher levels, disabled for level 0]" "[w \atext\a?write \atext\a\\r\\n to the master; C style escapes " "in text are converted, including \\E for ESC and \\cX for " "control-X]" "[x [\acode\a]]" "?exit \bpty\b with exit code \b0\b [\acode\a]]]" "[I \are\a?ignore master lines matching \are\a]" "[L \alabel\a?prefix all diagnostics with \alabel\a:]" "[P \atext\a?delay each master write until the beginning of " "an unread input line exactly matches \atext\a]" "}" "[D:debug?Set the debug trace \alevel\a, higher levels produce more " "output, disabled for level 0.]#[level]" "[l:log?Log the master stdout and stderr to \afile\a.]:[file]" "[m:messages?Redirect diagnostic message output to \afile\a.]:[file]" "[s!:session?Create a separate session for the process started by " "\bpty\b.]" "[t:timeout?Set the master read timeout to " "\amilliseconds\a.]#[milliseconds:=1000]" "[T:tty?Pass \astty\a to the \bstty\b(1) command to initialize the " "pty.]:[stty]" "[w:delay?Set the delay before each master write to " "\amilliseconds\a.]#[milliseconds:=0]" "\n" "\ncommand [arg ...]\n" "\n" "[+EXIT STATUS?If the command determined by \bcommand\b is run the exit " "status of \bpty\b is that of this command. Otherwise, the exit status " "is one of the following:]" "{" "[+127?The command is found but cannot be executed.]" "[+128?The command could not be found.]" "}" "[+SEE ALSO?\bcommand\b(1), \bexec\b(1)]" ; #include #include #include #include #include #include #include #include #include #include #include #include #include "FEATURE/pty" #define MODE_666 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) #define MAXNAME 64 #ifndef CMIN #define CMIN 1 #endif static noreturn void outofmemory(void) { error(ERROR_SYSTEM|ERROR_PANIC, "out of memory"); UNREACHABLE(); } #if !_lib_openpty && !_lib__getpty && !defined(_pty_clone) # if !_lib_grantpt || !_lib_unlock # if !_lib_ptsname static char *minionname(const char *name) { static char sname[MAXNAME]; char *last; strncpy(sname,name,sizeof(sname)); last = strrchr(sname,'/'); last[1] = 't'; return(sname); } # endif static char *master_name(char *name) { static char sname[MAXNAME]; int n; if(!name) { strcpy(sname,_pty_first); return(sname); } n = strlen(_pty_first); if(name[n-1]=='9') name[n-1]='a'; else if(name[n-1]=='f') { if(_pty_first[n-2]=='0' && name[n-2]=='9') { name[n-2]='0'; if(name[n-3]=='9' || name[n-3]=='z') return(NULL); name[n-3]++; } if(_pty_first[n-2]=='p' && (name[n-2]=='z' || name[n-2]=='Z')) { if(name[n-2]=='z') name[n-2]=='P'; else return(0); } else name[n-2]++; name[n-1]='0'; } else name[n-1]++; return(name); } #endif #if !_lib_openpty static char *ptymopen(int *master) { char *minion=0; # if _lib__getpty return(_getpty(master,O_RDWR,MODE_666,0)); # else # if defined(_pty_clone) *master = open(_pty_clone,O_RDWR|O_CREAT,MODE_666); if(*master>=0) minion = ptsname(*master); # else int fdm; char *name=0; while(name=master_name(name)) { fdm = open(name,O_RDWR|O_CREAT,MODE_666); if(fdm >= 0) { *master = fdm; # if _lib_ptsname minion = ptsname(fdm); # else minion = minionname(name); # endif break; } } # endif # endif return(minion); } # endif #endif static int mkpty(int* master, int* minion) { struct termios tty; struct termios* ttyp; #ifdef TIOCGWINSZ struct winsize win; struct winsize* winp; #endif #if !_lib_openpty char* sname; #endif #ifdef SIGTTOU sigset_t blckttou, oldset; (void)sigemptyset(&blckttou); (void)sigaddset(&blckttou, SIGTTOU); sigprocmask(SIG_BLOCK, &blckttou, &oldset); #endif alarm(6); if (tcgetattr(sffileno(sfstderr), &tty) < 0) { if (errno != ENOTTY) error(-1, "unable to get standard error terminal attributes"); #if _lib_cfmakeraw cfmakeraw(&tty); #else tty.c_iflag |= IGNPAR; tty.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); tty.c_oflag &= ~OPOST; tty.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); #endif /* _lib_cfmakeraw */ ttyp = 0; } tty.c_lflag |= ICANON | IEXTEN | ISIG | ECHO | ECHOE | ECHOK; #ifdef ECHOKE tty.c_lflag |= ECHOKE; #endif tty.c_oflag |= (ONLCR | OPOST); #ifdef OCRNL tty.c_oflag &= ~OCRNL; #endif #ifdef ONLRET tty.c_oflag &= ~ONLRET; #endif tty.c_iflag |= BRKINT; tty.c_iflag &= ~IGNBRK; tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = CMIN; #ifdef B115200 cfsetispeed(&tty, B115200); cfsetospeed(&tty, B115200); #elif defined(B57600) cfsetispeed(&tty, B57600); cfsetospeed(&tty, B57600); #elif defined(B38400) cfsetispeed(&tty, B38400); cfsetospeed(&tty, B38400); #endif ttyp = &tty; #ifdef TIOCGWINSZ if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) < 0) { if (errno != ENOTTY) error(-1, "unable to get standard error window size"); win.ws_row = 0; win.ws_col = 0; winp = 0; } if (win.ws_row < 24) win.ws_row = 24; if (win.ws_col < 80) win.ws_col = 80; winp = &win; #endif #ifdef __linux__ # if !_lib_openpty # undef _lib_openpty # define _lib_openpty 1 # endif #endif #if _lib_openpty if (openpty(master, minion, NULL, ttyp, winp) < 0) return -1; #else #if _lib_grantpt && _lib_unlockpt #if !_lib_posix_openpt #ifndef _pty_clone #define _pty_clone "/dev/ptmx" #endif #define posix_openpt(m) open(_pty_clone,m) #endif if ((*master = posix_openpt(O_RDWR)) < 0) return -1; if (grantpt(*master) || unlockpt(*master) || !(sname = ptsname(*master)) || (*minion = open(sname, O_RDWR|O_cloexec)) < 0) { close(*master); return -1; } #else if (!(sname = ptymopen(master)) || (*minion = open(sname, O_RDWR|O_cloexec)) < 0) return -1; #endif #ifdef I_PUSH struct termios tst; if (tcgetattr(*minion, &tst) < 0 && (ioctl(*minion, I_PUSH, "ptem") < 0 || ioctl(*minion, I_PUSH, "ldterm") < 0)) { close(*minion); close(*master); return -1; } #endif #endif if (ttyp && tcsetattr(*minion, TCSANOW, ttyp) < 0) error(ERROR_warn(0), "unable to set pty terminal attributes"); #ifdef TIOCSWINSZ if (winp && ioctl(*minion, TIOCSWINSZ, winp) < 0) error(ERROR_warn(0), "unable to set pty window size"); #endif fcntl(*master, F_SETFD, FD_CLOEXEC); #if !O_cloexec fcntl(*minion, F_SETFD, FD_CLOEXEC); #endif #ifdef SIGTTOU sigprocmask(SIG_SETMASK, &oldset, NULL); #endif alarm(0); return 0; } static Proc_t* runcmd(char** argv, int minion, int session) { long ops[4]; if (session) { ops[0] = PROC_FD_CTTY(minion); ops[1] = 0; } else { ops[0] = PROC_FD_DUP(minion, 0, PROC_FD_CHILD); ops[1] = PROC_FD_DUP(minion, 1, PROC_FD_CHILD); ops[2] = PROC_FD_DUP(minion, 2, PROC_FD_CHILD); ops[3] = 0; } return procopen(argv[0], argv, NiL, ops, 0); } /* * default master dance */ static int process(Sfio_t* mp, Sfio_t* lp, int delay, int timeout) { int i; int n; int t; ssize_t r; char* s; Sfio_t* ip; Sfio_t* sps[2]; struct stat dst; struct stat fst; ip = sfstdin; if (!fstat(sffileno(ip), &dst) && !stat("/dev/null", &fst) && dst.st_dev == fst.st_dev && dst.st_ino == fst.st_ino) ip = 0; do { i = 0; t = timeout; if (mp) sps[i++] = mp; if (ip) { sps[i++] = ip; t = -1; } if (!i) break; if ((n = sfpoll(sps, i, t)) <= 0) { if (n < 0) error(ERROR_SYSTEM|2, "poll failed"); break; } for (i = t = 0; i < n; i++) { if (!(sfvalue(sps[i]) & SF_READ)) /*skip*/; else if (sps[i] == mp) { t++; if (!(s = (char*)sfreserve(mp, SF_UNBOUND, -1))) { sfclose(mp); mp = 0; } else if ((r = sfvalue(mp)) > 0 && (sfwrite(sfstdout, s, r) != r || sfsync(sfstdout))) { error(ERROR_SYSTEM|2, "output write failed"); goto done; } } else { t++; if (!(s = sfgetr(ip, '\n', 1))) ip = 0; else if (sfputr(mp, s, '\r') < 0 || sfsync(mp)) { error(ERROR_SYSTEM|2, "write failed"); goto done; } } } } while (t); done: if (mp) sfclose(mp); return error_info.errors != 0; } /* * return 1 is extended re pattern matches text */ static int match(char* pattern, char* text, int must) { regex_t* re; int code; char buf[64]; if (!pattern[0]) return 1; if (pattern[0] == '?' && pattern[1] && !pattern[2]) { switch (pattern[1]) { case '0': case '1': if (text) error(2, "got \"%s\"", fmtesq(text, "\"")); else error(2, "got EOF"); return pattern[1] == '1'; case '.': if (!text) return 1; if (must) error(2, "expected EOF, got \"%s\"", fmtesq(text, "\"")); return 0; } } if (!text) { if (must) error(2, "expected \"%s\", got EOF", pattern); return 0; } if (!(re = regcache(pattern, REG_EXTENDED, &code))) { regerror(code, re, buf, sizeof(buf)); error(2, "%s: %s", pattern, buf); return 0; } if (regexec(re, text, 0, NiL, 0)) { if (must) error(2, "expected \"%s\", got \"%s\"", pattern, fmtesq(text, "\"")); return 0; } return 1; } typedef struct Master_s { Vmalloc_t* vm; /* allocation region */ char* ignore; /* ignore master lines matching this re */ char* peek; /* peek buffer pointer */ char* cur; /* current line */ char* nxt; /* next line */ char* end; /* end of lines */ char* max; /* end of buf */ char* buf; /* current buffer */ char* prompt; /* peek prompt */ int cursor; /* cursor in buf, 0 if fresh line */ int line; /* prompt line number */ int restore; /* previous line save char */ } Master_t; /* * read one line from the master */ #define MASTER_EOF (-1) #define MASTER_TIMEOUT (-2) static char* masterline(Sfio_t* mp, Sfio_t* lp, char* prompt, int must, int timeout, Master_t* bp) { char* r; char* s; char* t; ssize_t n; ssize_t a; size_t promptlen = 0; ptrdiff_t d; char promptbuf[64]; if (prompt) promptlen = sfsprintf(promptbuf, sizeof(promptbuf), prompt, ++bp->line); again: if (prompt) { if (bp->cur < bp->end && bp->restore >= 0) *bp->cur = bp->restore; if (strneq(bp->cur, promptbuf, promptlen)) r = bp->cur; else r = 0; if (bp->cur < bp->end && bp->restore >= 0) *bp->cur = 0; if (r) { error(-1, "p \"%s\"", fmtnesq(promptbuf, "\"", promptlen)); return r; } if (r = bp->nxt) { if (strneq(r, promptbuf, promptlen)) { error(-1, "p \"%s\"", fmtnesq(promptbuf, "\"", promptlen)); return r; } while (r = memchr(r, '\n', bp->end - r)) { if (strneq(r, promptbuf, promptlen)) { error(-1, "p \"%s\"", fmtnesq(promptbuf, "\"", promptlen)); return r; } r++; } } *bp->cur = 0; } else if (bp->nxt) { if (bp->restore >= 0) *bp->cur = bp->restore; r = bp->cur; bp->restore = *bp->nxt; *bp->nxt = 0; if (bp->nxt >= bp->end) { bp->cur = bp->end = bp->buf; bp->nxt = 0; } else { bp->cur = bp->nxt; if (bp->nxt = memchr(bp->nxt + 1, '\n', bp->end - bp->nxt - 1)) bp->nxt++; } goto done; } if ((n = sfpoll(&mp, 1, timeout)) <= 0 || !((int)sfvalue(mp) & SF_READ)) { if (n < 0) { if (must) error(ERROR_SYSTEM|2, "poll failed"); else error(-1, "r poll failed"); } else if (bp->cur < bp->end) { if (bp->restore >= 0) { *bp->cur = bp->restore; bp->restore = -1; } r = bp->cur; *bp->end = 0; bp->nxt = 0; if (prompt && strneq(r, promptbuf, promptlen)) { error(-1, "p \"%s\"", fmtnesq(promptbuf, "\"", promptlen)); return r; } bp->cur = bp->end = bp->buf; goto done; } else if (must >= 0) error(2, "read timeout"); else { errno = 0; error(-1, "r EOF"); } return 0; } if (!(s = sfreserve(mp, SF_UNBOUND, -1))) { if (!prompt) { if (bp->cur < bp->end) { if (bp->restore >= 0) { *bp->cur = bp->restore; bp->restore = -1; } r = bp->cur; *bp->end = 0; bp->cur = bp->end = bp->buf; bp->nxt = 0; goto done; } else { errno = 0; error(-1, "r EOF"); } } return 0; } n = sfvalue(mp); error(-2, "b \"%s\"", fmtnesq(s, "\"", n)); if ((bp->max - bp->end) < n) { a = roundof(bp->max - bp->buf + n, SF_BUFSIZE); r = bp->buf; if (!(bp->buf = vmnewof(bp->vm, bp->buf, char, a, 0))) outofmemory(); bp->max = bp->buf + a; if (bp->buf != r) { d = bp->buf - r; bp->cur += d; bp->end += d; } } memcpy(bp->end, s, n); bp->end += n; if ((r = bp->cur) > bp->buf && bp->restore >= 0) *r = bp->restore; if (bp->cur = memchr(bp->cur, '\n', bp->end - bp->cur)) { bp->restore = *++bp->cur; *bp->cur = 0; if (bp->cur >= bp->end) { bp->cur = bp->end = bp->buf; bp->nxt = 0; } else if (bp->nxt = memchr(bp->cur + 1, '\n', bp->end - bp->cur - 1)) bp->nxt++; if (prompt) goto again; } else { bp->restore = -1; bp->cur = r; bp->nxt = 0; must = 0; goto again; } done: error(-3, "Q \"%s\"", fmtesq(r, "\"")); s = r; if (bp->cursor) { r -= bp->cursor; bp->cursor = 0; } for (t = 0, n = 0; *s; s++) if (*s == '\n') { if (t) { *t++ = '\n'; *t = 0; t = 0; n = 0; } } else if (*s == '\r' && *(s + 1) != '\n') { if (t = strchr(s + 1, '\r')) n += t - s; else n += strlen(s); t = r; } else if (*s == '\a') { if (!t) t = s; *t = ' '; n++; } else if (*s == '\b') { if (!t) t = s; if (t > r) t--; else n++; } else if (t) *t++ = *s; if (t) error(-3, "R \"%s\"", fmtesq(r, "\"")); if (n) *(r + strlen(r) - n) = 0; error(-1, "r \"%s\"", fmtesq(r, "\"")); if (lp) sfputr(lp, fmtesq(r, "\""), '\n'); if (t) bp->cursor = t - r; if (bp->ignore && match(bp->ignore, r, 0)) goto again; return r; } /* * execute dialogue script on stdin */ #define NESTING 64 #define ELSE 0x01 #define IF 0x02 #define KEPT 0x04 #define SKIP 0x08 struct Cond_s; typedef struct Cond_s Cond_t; struct Cond_s { Cond_t* next; Cond_t* prev; char* text; int flags; }; static int dialogue(Sfio_t* mp, Sfio_t* lp, int delay, int timeout) { int op; int line; int n; char* s; char* m; char* e; char* id; Vmalloc_t* vm; Cond_t* cond; Master_t* master; int status = 0; if (!(vm = vmopen(Vmdcheap, Vmbest, 0)) || !(cond = vmnewof(vm, 0, Cond_t, 1, 0)) || !(master = vmnewof(vm, 0, Master_t, 1, 0)) || !(master->buf = vmnewof(vm, 0, char, 2 * SF_BUFSIZE, 0))) outofmemory(); master->vm = vm; master->cur = master->end = master->buf; master->max = master->buf + 2 * SF_BUFSIZE - 1; master->restore = -1; errno = 0; id = error_info.id; error_info.id = 0; line = error_info.line; error_info.line = 0; while (s = sfgetr(sfstdin, '\n', 1)) { error_info.line++; while (isspace(*s)) s++; if ((op = *s++) && isspace(*s)) s++; switch (op) { case 0: case '#': break; case 'c': case 'w': if (cond->flags & SKIP) continue; if (master->prompt && !masterline(mp, lp, master->prompt, 0, timeout, master)) goto done; if (delay) usleep((unsigned long)delay * 1000); if (op == 'w') error(-1, "w \"%s\\r\"", s); else error(-1, "w \"%s\"", s); if ((n = stresc(s)) >= 0) s[n] = 0; if (sfputr(mp, s, op == 'w' ? '\n' : -1) < 0 || sfsync(mp)) { error(ERROR_SYSTEM|2, "write failed"); goto done; } if (delay) usleep((unsigned long)delay * 1000); break; case 'd': delay = (int)strtol(s, &e, 0); if (*e) error(2, "%s: invalid delay -- milliseconds expected", s); break; case 'i': if (!cond->next && !(cond->next = vmnewof(vm, 0, Cond_t, 1, 0))) outofmemory(); cond = cond->next; cond->flags = IF; if ((cond->prev->flags & SKIP) && !(cond->text = 0) || !(cond->text = masterline(mp, lp, 0, 0, timeout, master))) cond->flags |= KEPT|SKIP; else if (match(s, cond->text, 0)) cond->flags |= KEPT; else cond->flags |= SKIP; break; case 'e': if (!(cond->flags & IF)) { error(2, "no matching i for e"); goto done; } if (!*s) { if (cond->flags & ELSE) { error(2, "i block already has a default e"); goto done; } cond->flags |= ELSE; if (cond->flags & KEPT) cond->flags |= SKIP; else { cond->flags |= KEPT; cond->flags &= ~SKIP; } } else if ((cond->flags & KEPT) || !match(s, cond->text, 0)) cond->flags |= SKIP; else cond->flags |= KEPT; break; case 'f': if (!(cond->flags & IF)) { error(2, "no matching i for f"); goto done; } cond = cond->prev; break; case 'm': if (cond->flags & SKIP) continue; if (sfputr(sfstderr, s, '\n') < 0 || sfsync(sfstderr)) { error(ERROR_SYSTEM|2, "standard error write failed"); goto done; } break; case 'p': if (cond->flags & SKIP) continue; if (!(m = masterline(mp, lp, s, 1, timeout, master))) goto done; break; case 'r': if (cond->flags & SKIP) continue; if (!(m = masterline(mp, lp, 0, s[0] == '?' && s[1] == '.' ? -1 : 1, timeout, master))) goto done; match(s, m, 1); break; case 's': n = (int)strtol(s, &e, 0); if (*e) error(2, "%s: invalid delay -- milliseconds expected", s); if (n) usleep((unsigned long)n * 1000); break; case 't': timeout = (int)strtol(s, &e, 0); if (*e) error(2, "%s: invalid timeout -- milliseconds expected", s); break; case 'u': if (cond->flags & SKIP) continue; do { if (!(m = masterline(mp, lp, 0, -1, timeout, master))) { match(s, m, 1); goto done; } } while (!match(s, m, 0)); break; case 'v': error_info.trace = -(int)strtol(s, &e, 0); if (*e) error(2, "%s: invalid verbose level -- number expected", s); break; case 'x': status = (int)strtol(s, &e, 0); if (*e) error(2, "%s: invalid exit code", s); break; case 'I': if (master->ignore) { vmfree(vm, master->ignore); master->ignore = 0; } if (*s && !(master->ignore = vmstrdup(vm, s))) { error(ERROR_SYSTEM|2, "out of memory"); goto done; } break; case 'L': if (error_info.id) { vmfree(vm, error_info.id); error_info.id = 0; } if (*s && !(error_info.id = vmstrdup(vm, s))) { error(ERROR_SYSTEM|2, "out of memory"); goto done; } break; case 'P': if (master->prompt) { vmfree(vm, master->prompt); master->prompt = 0; } if (*s && !(master->prompt = vmstrdup(vm, s))) { error(ERROR_SYSTEM|2, "out of memory"); goto done; } break; default: if (cond->flags & SKIP) continue; error(2, "'%c': unknown op", op); goto done; } } if (cond->prev) error(2, "missing 1 or more f statements"); done: if (mp) sfclose(mp); error_info.id = id; error_info.line = line; if (vm) vmclose(vm); return status ? status : error_info.errors != 0; } typedef struct Argv_s { char** argv; char* args; int argc; } Argv_t; int b_pty(int argc, char** argv, Shbltin_t* context) { int master; int minion; int fd; int drop; int n; char* s; Proc_t* proc; Sfio_t* mp; Sfio_t* lp; Argv_t* ap; char buf[64]; int delay = 0; char* log = 0; char* messages = 0; char* stty = 0; int session = 1; int timeout = 1000; int (*fun)(Sfio_t*,Sfio_t*,int,int) = process; cmdinit(argc, argv, context, ERROR_CATALOG, 0); for (;;) { switch (optget(argv, usage)) { case 'd': if (opt_info.num) fun = dialogue; continue; case 'D': error_info.trace = -(int)opt_info.num; continue; case 'l': log = opt_info.arg; /* FALLTHROUGH */ case 'm': messages = opt_info.arg; continue; case 's': session = !!opt_info.num; continue; case 't': timeout = (int)opt_info.num; continue; case 'T': stty = opt_info.arg; continue; case 'w': delay = (int)opt_info.num; continue; case ':': break; case '?': error(ERROR_usage(2), "%s", opt_info.arg); UNREACHABLE(); } break; } argv += opt_info.index; if (!argv[0]) { error(ERROR_exit(1), "command must be specified"); UNREACHABLE(); } if (mkpty(&master, &minion) < 0) { error(ERROR_system(1), "unable to create pty"); UNREACHABLE(); } if (!(mp = sfnew(NiL, 0, SF_UNBOUND, master, SF_READ|SF_WRITE))) { error(ERROR_system(1), "cannot open master stream"); UNREACHABLE(); } if (stty) { n = 2; for (s = stty; *s; s++) if (isspace(*s)) n++; if (!(ap = newof(0, Argv_t, 1, (n + 2) * sizeof(char*) + (s - stty + 1)))) outofmemory(); ap->argc = n + 1; ap->argv = (char**)(ap + 1); ap->args = (char*)(ap->argv + n + 2); strcpy(ap->args, stty); ap->argv[0] = "stty"; sfsprintf(ap->argv[1] = buf, sizeof(buf), "--fd=%d", minion); ap->argv[2] = s = ap->args; for (n = 2; *s; s++) if (isspace(*s)) { *s = 0; ap->argv[++n] = s + 1; } ap->argv[n + 1] = 0; b_stty(ap->argc, ap->argv, 0); } if (!log) lp = 0; else if (!(lp = sfopen(NiL, log, "w"))) { error(ERROR_system(1), "%s: cannot write", log); UNREACHABLE(); } if (!(proc = runcmd(argv, minion, session))) { error(ERROR_system(1), "unable run %s", argv[0]); UNREACHABLE(); } close(minion); if (messages) { drop = 1; if (strneq(messages, "/dev/fd/", 8)) fd = atoi(messages + 8); else if (streq(messages, "/dev/stdout")) fd = 1; else if ((fd = open(messages, O_CREAT|O_WRONLY, MODE_666)) >= 0) drop = 0; else { error(ERROR_system(1), "%s: cannot redirect messages", messages); UNREACHABLE(); } close(2); dup(fd); if (drop) close(fd); } minion = (*fun)(mp, lp, delay, timeout); master = procclose(proc); if (lp && sfclose(lp)) { error(ERROR_system(1), "%s: write error", log); UNREACHABLE(); } return minion ? minion : master; } ksh-1.0.0-beta.2/src/cmd/ksh93/000077500000000000000000000000001415700074400156435ustar00rootroot00000000000000ksh-1.0.0-beta.2/src/cmd/ksh93/COMPATIBILITY000066400000000000000000000345641415700074400176130ustar00rootroot00000000000000 ksh 93u+m vs. ksh 93u+ The following is a list of changes between ksh 93u+ 2012-08-01 and the new ksh 93u+m reboot that could cause incompatibilities in rare corner cases. Fixes of clear bugs in ksh 93u+ are not included here, even though any bugfix could potentially cause an incompatibility in a script that relies on the bug. For more details, see the NEWS file and for complete details, see the git log. 0. A new '-o posix' shell option has been added to ksh 93u+m that makes the ksh language more compatible with other shells by following the POSIX standard more closely. See the manual page for details. It is enabled by default if ksh is invoked as sh. 1. Bytecode compiled by shcomp 93u+m will not run on older ksh versions. (However, bytecode compiled by older shcomp will run on ksh 93u+m.) 2. Pathname expansion (a.k.a. filename generation, a.k.a. globbing) now never matches the special navigational names '.' (current directory) and '..' (parent directory). This change makes a pattern like .* useful; it now matches all hidden 'dotfiles' in the current directory. 3. The bash-style &>foo redirection operator (shorthand for >foo 2>&1) can now always be used if -o posix is off, and not only in profile scripts. 4. Redirections that store a file descriptor > 9 in a variable, such as {var}>file, now continue to work if brace expansion is turned off. 5. Most predefined aliases have been converted to regular built-in commands that work the same way. 'unalias' no longer removes these. To remove a built-in command, use 'builtin -d'. The 'history' and 'r' predefined aliases remain, but are now only set on interactive shells. There are some minor changes in behavior in some former aliases: - 'redirect' now checks if all arguments are valid redirections before performing them. If an error occurs, it issues an error message instead of terminating the shell. - 'suspend' now refuses to suspend a login shell, as there is probably no parent shell to return to and the login session would freeze. If you really want to suspend a login shell, use 'kill -s STOP $$'. - 'times' now gives high precision output in a POSIX compliant format. 6. 'command' and 'nohup' no longer expand aliases in their first argument, as this is no longer required after the foregoing change. In the unlikely event that you still need this behavior, you can set: alias command='command ' alias nohup='nohup ' 7. The 'login' and 'newgrp' special built-in commands have been removed, so it is no longer an error to define shell functions by these names. These built-ins replaced your shell session with the external commands by the same name, as in 'exec'. If an error occurred (e.g. due to a typo), you would end up immediately logged out, except on a few commercial Unix systems whose 'login' and 'newgrp' cope with this by starting a new shell session upon error. If you do want the old behavior, you can restore it by setting: alias login='exec login' alias newgrp='exec newgrp' 8. 'case' no longer retries to match patterns as literal strings if they fail to match as patterns. This undocumented behaviour broke validation use cases that are expected to work. For example: n='[0-9]' case $n in [0-9]) echo "$n is a digit" ;; esac would output "[0-9] is a digit". In the unlikely event that a script does rely on this behavior, it can be fixed like this: case $n in [0-9] | "[0-9]") echo "$n is a digit or the digit pattern" ;; esac 9. If 'set -u'/'set -o nounset' is active, then the shell now errors out if a nonexistent positional parameter such as $1, $2, ... is accessed. (This does *not* apply to "$@" and "$*".) 10. If 'set -u'/'set -o nounset' is active, then the shell now errors out if $! is accessed before the shell has launched any background process. 11. The 'print', 'printf' and 'echo' built-in commands now return a nonzero exit status if an input/output error occurs. 12. Four obsolete date format specifiers for 'printf %(format)T' were changed to make them compatible with modern date(1) commands: - %k and %l now return a blank-padded hour (24-hour and 12-hour clock). - %f now returns a date with the format '%Y.%m.%d-%H:%M:%S'. - %q now returns the quarter of the current year. 13. The 'typeset' built-in now properly detects and reports options that cannot be used together if they are given as part of the same command. 14. The DEBUG trap has reverted to pre-93t behavior. It is now once again reset like other traps upon entering a subshell or ksh-style function, as documented, and it is no longer prone to crash or get corrupted. 15. 'command -x' now always runs an external command, bypassing built-ins. 16. Unbalanced quotes and backticks now correctly produce a syntax error in -c scripts, 'eval', and backtick-style command substitutions. 17. -G/--globstar: Symbolic links to directories are now followed if they match a normal (non-**) glob pattern. For example, if '/lnk' is a symlink to a directory, '/lnk/**' and '/l?k/**' now work as expected. 18. The variable name search expansions ${!prefix@} and ${!prefix*} now also include the variable 'prefix' itself in the possible results. 19. [[ -v var ]] is now properly equivalent to [[ -n ${var+set} ]]. Undocumented special-casing for numeric types has been removed. For example, the following no longer produces an unexpected error: $ ksh -o nounset -c 'float n; [[ -v n ]] && echo $n' 20. If the HOME variable is unset, the bare tilde ~ now expands to the current user's system home directory instead of merely the username. 21. On Windows/Cygwin, globbing is no longer case-insensitive by default. Turning on the new --globcasedetect shell option restores case-insensitive globbing for case-insensitive file systems. 22. If $PWD or $OLDPWD are passed as invocation-local assignments to cd, their values are no longer altered in the outer scope when cd finishes. For example: ksh -c 'OLDPWD=/bin; OLDPWD=/tmp cd - > /dev/null; echo $OLDPWD' ksh -c 'cd /var; PWD=/tmp cd /usr; echo $PWD' now prints '/bin' followed by '/var'. 23. Path-bound built-ins (such as /opt/ast/bin/cat) can now be executed by invoking the canonical path, so the following will now work: $ /opt/ast/bin/cat --version version cat (AT&T Research) 2012-05-31 $ (PATH=/opt/ast/bin:$PATH; "$(whence -p cat)" --version) version cat (AT&T Research) 2012-05-31 In the event an external command by that path exists, the path-bound built-in will now override it when invoked using the canonical path. To invoke a possible external command at that path, you can still use a non-canonical path, e.g.: /opt//ast/bin/cat or /opt/ast/./bin/cat 24. The readonly attribute of ksh variables is no longer imported from or exported to other ksh shell instances through the environment. 25. Subshells (even if non-forked) now keep a properly separated state of the pseudorandom generator used for $RANDOM, so that using $RANDOM in a non-forked subshell no longer influences a reproducible $RANDOM sequence in the parent environment. In addition, upon invoking a subshell, $RANDOM is now reseeded (as mksh and bash do). 26. The built-in arithmetic function int() has changed to round towards zero instead of negative infinity. Previously, int() was an alias to floor(), but now it behaves like trunc(). 27. The '!' logical negation operator in the '[[' compound command now correctly negates another '!', e.g., [[ ! ! 1 -eq 1 ]] now returns 0/true. Note that this has always been the case for 'test'/'['. 28. By default, arithmetic expressions in ksh no longer interpret a number with a leading zero as octal in any context. Use 8#octalnumber instead. Before, ksh would arbitrarily recognize the leading octal zero in some contexts but not others. One of several examples is: x=010; echo "$((x)), $(($x))" would output '10, 8'. This now outputs '10, 10'. Arithmetic expressions now also behave identically within and outside ((...)) and $((...)). Setting the --posix compliance option turns on the recognition of the leading octal zero for all arithmetic contexts. 29. It is now an error for arithmetic expressions to assign an out-of-range index value to a variable of an enumeration type created with 'enum'. 30. For the 'return' built-in command, you can now freely specify any return value that fits in a signed integer, typically a 32-bit value. Note that $? is truncated to 8 bits when the current (sub)shell exits. ____________________________________________________________________________ KSH-93 VS. KSH-88 (Written by David Korn for ksh 93u+ 2012-08-01) The following is a list of known incompatibilities between ksh-93 and ksh-88. I have not included cases that are clearly bugs in ksh-88. I also have omitted features that are completely upward compatible. 1. Functions, defined with name() with ksh-93 are compatible with the POSIX standard, not with ksh-88. No local variables are permitted, and there is no separate scope. Functions defined with the function name syntax have local variables as in ksh-88, but are statically scoped as in C so that a function does not automatically have access to local variables of the caller. This change also affects function traces. 2. ! is now a reserved word. As a result, any command by that name will no longer work with ksh-93. 3. The -x attribute of alias and typeset -f is no longer effective and the ENV file is only read for interactive shells. You need to use FPATH to make function definitions visible to scripts. 4. A built-in command named command has been added which is always found before the PATH search. Any script which uses this name as the name of a command (or function) will not be compatible. 5. The output format for some built-ins has changed. In particular the output format for set, typeset and alias now have single quotes around values that have special characters. The output for trap without arguments has a format that can be used as input. 6. With ksh-88, a dollar sign ($') followed by a single quote was interpreted literally. Now it is an ANSI C string. You must quote the dollar sign to get the previous behavior. Also, a $ in front of a " indicates that the string needs to be translated for locales other than C or POSIX. The $ is ignored in the C and POSIX locale. 7. With ksh-88, tilde expansion did not take place inside ${...}. with ksh-93, ${foo-~} will cause tilde expansion if foo is not set. You need to escape the ~ for the previous behavior. 8. Some changes in the tokenizing rules were made that might cause some scripts with previously ambiguous use of quoting to produce syntax errors. 9. Programs that rely on specific exit values for the shell, (rather than 0 or non-zero) may not be compatible. The exit status for many shell failures has been changed. 10. Built-ins in ksh-88 were always executed before looking for the command in the PATH variable. This is no longer true. Thus, with ksh-93, if you have the current directory first in your PATH, and you have a program named test in your directory, it will be executed when you type test; the built-in version will be run at the point /bin is found in your PATH. 11. Some undocumented combinations of argument passing to ksh builtins no longer works since ksh-93 is getopts conforming with respect to its built-ins. For example, typeset -8i previously would work as a synonym for typeset -i8. 12. Command substitution and arithmetic expansion are now performed on PS1, PS3, and ENV when they are expanded. Thus, ` and $( as part of the value of these variables must be preceded by a \ to preserve their previous behavior. 13. The ERRNO variable has been dropped. 14. If the file name following a redirection symbol contain pattern characters they will only be expanded for interactive shells. 15. The arguments to a dot script will be restored when it completes. 16. The list of tracked aliases is not displayed with alias unless the -t option is specified. 17. The POSIX standard requires that test "$arg" have exit status of 0, if and only if $arg is null. However, since this breaks programs that use test -t, ksh-93 treats an explicit test -t as if the user had entered test -t 1. 18. The ^T directive of emacs mode has been changed to work the way it does in gnu-emacs. 19. ksh-88 allowed unbalanced parentheses within ${name op val} whereas ksh-93 does not. Thus, ${foo-(} needs to be written as ${foo-\(} which works with both versions. [2021 UPDATE: This is now once again allowed in ksh 93u+m. Note that balanced parentheses ${foo-()} were also broken and are now fixed.] 20. kill -l in ksh-93 lists only the signal names, not their numerical values. 21. Local variables defined by typeset are statically scoped in ksh-93. In ksh-88 they were dynamically scoped although this behavior was never documented. 22. The value of the variable given to getopts is set to ? when the end-of-options is reached to conform to the POSIX standard. 23. Since the POSIX standard requires that octal constants be recognized, doing arithmetic on typeset -Z variables can yield different results that with ksh-88. Most of these differences were eliminated in ksh-93o. Starting in ksh-93u+, the let command no longer recognizes octal constants starting with 0 for compatibility with ksh-88 unless the option letoctal is on. 24. Starting after ksh-93l, If you run ksh name, where name does not contain a /, the current directory will be searched before doing a path search on name as required by the POSIX shell standard. 25. In ksh-93, cd - will output the directory that it changes to on standard output as required by X/Open. With ksh-88, this only happened for interactive shells. 26. As an undocumented feature of ksh-88, a leading 0 to an assignment of an integer variable caused that variable to be treated as unsigned. This behavior was removed starting in ksh-93p. 27. The getopts builtin in ksh-93 requires that optstring contain a leading + to allow options to begin with a +. 28. In emacs/gmacs mode, control-v will not display the version when the stty lnext character is set to control-v or is unset. The sequence escape control-v will display the shell version. 29. In ksh-88, DEBUG traps were executed after each command. In ksh-93 DEBUG traps are executed before each command. 30. In ksh-88, a redirection to a file name given by an empty string was ignored. In ksh-93, this is an error. I am interested in expanding this list so please let me know if you uncover any others. ksh-1.0.0-beta.2/src/cmd/ksh93/DESIGN000066400000000000000000000164311415700074400165440ustar00rootroot00000000000000Here is an overview of the source code organization for ksh93. Directory layout: The directory include contains header files for ksh93. The files nval.h and shell.h are intended to be public headers and can be used to add runtime builtin command. The remainder are private. The directory data contains readonly data files for ksh93. The man pages for built-ins are in builtins.c rather than included as statics with the implementations in the bltins directory because some systems don't make static const data readonly and we want these to be shared by all running shells. The directory edit contains the code for command line editing and history. The fun directory contains some shell function such as pushd, popd, and dirs. The directory features contains files that are used to generate header files in the FEATURE directory. Most of these files are in a format that is processed by iffe. The directory bltins contains code for most of the built-in commands. Additional built-in commands are part of libcmd. The directory sh contains most of the code for ksh93. The directory tests contains a number of regression tests. In most cases, when a bug gets fixed, a test is added to one of these files. The regression tests can be run by going to this directory and running SHELL=shell_path shell_path shtests where shell_path is an absolute pathname for the shell to be tested. The top level directory contains the nmake Makefile, the RELEASE file, the ksh93 man file (sh.1) and nval.3 and shell.3 documentation files. The RELEASE file contains the list of bug fixes and new features since the original ksh93 release. The file COMPATIBILITY is a list of all known incompatibilities with ksh88. Include directory: 1. argnod.h contains the type definitions for command nodes, io nodes, argument nodes, and for positional parameters. It defines the prototypes for all the positional parameters functions. 2. builtins.h contains prototypes for builtins as well as symbolic constants that refer to the name-pairs that are associated with some of the built-ins. It also contains prototypes for many of the strings. 3. defs.h is the catch all for all definitions that don't fit elsewhere and it includes several other headers. It defines a structure that contains ksh global data, sh, and a structure that contains per function data, sh.st. 4. edit.h contains definitions that are common to both vi and emacs edit modes. 5. fault.h contains prototypes for signal related functions and trap and fault handling. 6. fcin.h contains macro and function definitions for reading from a file or string. 7. history.h contains macros and functions definitions related to history file processing. 8. jobs.h contains the definitions relating to job processing and control. 9. lexstates.h contains the states associated with lexical processing. 10. name.h contains the internal definitions related to name-value pair processing. 11. national.h contains a few I18N definitions, mostly obsolete. 12. nval.h is the public interface to the name-value pair library that is documented with nval.3. 13. path.h contains the interface for pathname processing and pathname searching. 14. shell.h is the public interface for shell functions that are documented int shell.3. 15. shlex.h contains the lexical token definitions and interfaces for lexical analysis. 16. shnodes.h contains the definition of the structures for each of the parse nodes and flags for the attributes. 17. shtable.h contains some interfaces and functions for table lookup. 18. streval.h contains the interface to the arithmetic functions. 19. terminal.h is a header file that includes the appropriate terminal include. 20. test.h contains the definitions for the test and [[ ... ]] commands. 21. timeout.h contains the define constant for the maximum shell timeout. 22. ulimit.h includes the appropriate resource header. 23. variables.h contains symbolic constants for the built-in shell variables. 24. version.h contains the version string for this release. sh directory: 1. args.c contains functions for parsing shell options and for processing positional parameters. 2. arith.c contains callback functions for the streval.c library and the interface to shell arithmetic. 3. array.c contains the code for indexed and associative arrays. 4. defs.c contains the data definitions for global symbols. 5. deparse.c contains code to generate shell script from a parse tree. 6. expand.c contains code for file name expansion and pathname expansion. 7. fault.c contains code for signal processing, trap handling and termination. 8. fcin.c contains code for reading and writing a character at a time from a file or string. 9. init.c contains initialization code and callbacks for get and set functions for built-in variables. 10. io.o contains code for redirections and managing file descriptors and file streams. 11. jobs.c contains the code for job management. 12. lex.c contains the code for the lexical analyzer. 13. macro.c contains code for the $ macro expansions, including here-documents. 14. main.c contains the calls to initialization, profile processing and the main evaluation loop as well as mail processing. 15. name.c contains the name-value pair routines that are built on the hash library in libast. 16. nvdisc.c contains code related to name-value pair disciplines. 17. nvtree.c contains code for compound variables and for walking the namespace. 18. nvtype.c contains most of the code related to types that are created with typeset -T. 19. parse.c contains the code for the shell parser. 20. path.c contains the code for pathname lookup and some path functions. It also contains the code that executes commands and scripts. 21. pmain.c is just a calls sh_main() so that all of the rest of the shell can be in a shared library. 22. shcomp.c contains the main program to the shell compiler. This program parses a script and creates a file that the shell can read containing the parse tree. 23. streval.c is an C arithmetic evaluator. 24. string.c contains some string related functions. 25. subshell.c contains the code to save and restore environments so that subshells can run without creating a new process. 26. suid_exec.c contains the program from running execute only and/or setuid/setgid scripts. 27. tdump.c contains the code to dump a parse tree into a file. 28. timers.c contains code for multiple event timeouts. 29. trestore contains the code for restoring the parse tree from the file created by tdump. 30. userinit.c contains a dummy userinit() function. This is now obsolete with the new version of sh_main(). 31. waitevent.c contains the sh_waitnotify function so that builtins can handle processing events when the shell is waiting for input or for process completion. 32. xec.c is the main shell execution loop. edit directory: 1. completion.c contains code for command and file generation and completion. 2. edit.c contains common editing and terminal code for vi and emacs. 3. emacs.c contains code for the emacs editor. 4. hexpand.c contains code for C-shell style history expansions. 5. history.c contains code for creating managing the history file. 6. vi.c contains the code for the vi editor. ksh-1.0.0-beta.2/src/cmd/ksh93/Mamfile000066400000000000000000002240471415700074400171510ustar00rootroot00000000000000info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-06-20 note * note * This build file is in the Make Abstract Machine (MAM) language. It was note * first generated by nmake, but in the ksh 93u+m distribution we maintain note * it manually because nmake had too many problems to keep using. The note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added note * support for indentation to improve readability. The language is note * documented in Glenn Fowler's paper "A Make Abstract Machine": note * http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html note * setv INSTALLROOT ../../.. setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast setv PACKAGEROOT ../../../../.. setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS} setv CC cc setv mam_cc_FLAGS setv KSH_RELFLAGS setv KSH_SHOPTFLAGS setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} setv COTEMP $$ setv IFFEFLAGS setv LDFLAGS setv SH_DICT \"libshell\" make install make ksh make SHOPT.sh implicit done SHOPT.sh generated make pmain.o make sh/pmain.c make FEATURE/externs implicit meta FEATURE/externs features/%>FEATURE/% features/externs externs make features/externs done features/externs exec - set - exec - echo 'int main(){return 0;}' > 1.${COTEMP}.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -c 1.${COTEMP}.c && exec - x=`${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l'*' 2>&1 | sed -e 's/[][()+@?]/#/g' || :` && exec - { exec - case "" in exec - *?) echo " " ;; exec - esac exec - for i in shell dll cmd ast m jobs i socket nsl secdb exec - do case $i in exec - "shell"|shell) exec - ;; exec - *) if test -f ${INSTALLROOT}/lib/lib/$i exec - then y=`cat ${INSTALLROOT}/lib/lib/$i` exec - case $y in exec - *-?*) echo "" $y ;; exec - esac exec - continue exec - elif test ! -f ${INSTALLROOT}/lib/lib$i.a exec - then case `{ ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -L${INSTALLROOT}/lib ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' "$x" ;} | sed -e 's/[][()+@?]/#/g' || :` in exec - *$x*) case `{ ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' "$x" ;} | sed -e 's/[][()+@?]/#/g' || :` in exec - *$x*) continue ;; exec - esac exec - ;; exec - esac exec - fi exec - ;; exec - esac exec - echo " -l$i" exec - done exec - } > shell.req exec - rm -f 1.${COTEMP}.* bind -ldll bind -lcmd bind -last bind -lm dontcare bind -lnsl dontcare exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/externs done FEATURE/externs generated make include/shell.h implicit make ${PACKAGE_ast_INCLUDE}/cmd.h implicit make ${PACKAGE_ast_INCLUDE}/dlldefs.h implicit done ${PACKAGE_ast_INCLUDE}/dlldefs.h dontcare make ${PACKAGE_ast_INCLUDE}/cmdext.h implicit make ${PACKAGE_ast_INCLUDE}/shcmd.h implicit make ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/prototyped.h dontcare done ${PACKAGE_ast_INCLUDE}/shcmd.h dontcare prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/cmdext.h dontcare prev ${PACKAGE_ast_INCLUDE}/shcmd.h implicit make ${PACKAGE_ast_INCLUDE}/stak.h implicit make ${PACKAGE_ast_INCLUDE}/stk.h implicit make ${PACKAGE_ast_INCLUDE}/sfio.h implicit make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare make ${PACKAGE_ast_INCLUDE}/endian.h implicit make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare done ${PACKAGE_ast_INCLUDE}/endian.h dontcare done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit make ${PACKAGE_ast_INCLUDE}/regex.h implicit make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit make ${PACKAGE_ast_INCLUDE}/wctype.h implicit make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit make ${PACKAGE_ast_INCLUDE}/wchar.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit done ${PACKAGE_ast_INCLUDE}/wchar.h dontcare done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare make ${PACKAGE_ast_INCLUDE}/stdio.h implicit make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/regex.h dontcare make ${PACKAGE_ast_INCLUDE}/getopt.h implicit make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/stk.h dontcare prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/stak.h dontcare make ${PACKAGE_ast_INCLUDE}/error.h implicit make ${PACKAGE_ast_INCLUDE}/option.h implicit make ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_api.h implicit make ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit done ${PACKAGE_ast_INCLUDE}/vmalloc.h dontcare prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ast.h dontcare prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/option.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/error.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/cmd.h dontcare prev ${PACKAGE_ast_INCLUDE}/shcmd.h implicit make include/nval.h implicit make ${PACKAGE_ast_INCLUDE}/hash.h implicit make ${PACKAGE_ast_INCLUDE}/hashpart.h implicit done ${PACKAGE_ast_INCLUDE}/hashpart.h dontcare done ${PACKAGE_ast_INCLUDE}/hash.h dontcare prev ${PACKAGE_ast_INCLUDE}/option.h implicit make ${PACKAGE_ast_INCLUDE}/cdt.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit done ${PACKAGE_ast_INCLUDE}/cdt.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/nval.h dontcare make include/name.h implicit prev include/nval.h implicit prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/name.h dontcare prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/shell.h done sh/pmain.c meta pmain.o %.c>%.o sh/pmain.c pmain prev sh/pmain.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/pmain.c done pmain.o generated make libshell.a archive prev shell.req make alarm.o make bltins/alarm.c make FEATURE/time implicit meta FEATURE/time features/%>FEATURE/% features/time time make features/time done features/time exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time make ${PACKAGE_ast_INCLUDE}/times.h implicit make ${PACKAGE_ast_INCLUDE}/ast_time.h implicit done ${PACKAGE_ast_INCLUDE}/ast_time.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/times.h dontcare done FEATURE/time generated make include/builtins.h implicit make include/shtable.h implicit done include/shtable.h dontcare make FEATURE/dynamic implicit meta FEATURE/dynamic features/%>FEATURE/% features/dynamic dynamic make features/dynamic done features/dynamic exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/dynamic prev ${PACKAGE_ast_INCLUDE}/dlldefs.h implicit done FEATURE/dynamic dontcare generated make FEATURE/options implicit meta FEATURE/options features/%>FEATURE/% features/options options make features/options done features/options exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/options done FEATURE/options dontcare generated prev ${PACKAGE_ast_INCLUDE}/option.h implicit done include/builtins.h prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit make include/defs.h implicit make include/regress.h implicit done include/regress.h dontcare prev include/shtable.h implicit prev include/shell.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit prev include/name.h implicit make include/argnod.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit done include/argnod.h dontcare make include/fault.h implicit make FEATURE/sigfeatures implicit meta FEATURE/sigfeatures features/%>FEATURE/% features/sigfeatures sigfeatures make features/sigfeatures done features/sigfeatures exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/sigfeatures done FEATURE/sigfeatures dontcare generated make FEATURE/setjmp implicit meta FEATURE/setjmp features/%>FEATURE/% features/setjmp setjmp make features/setjmp done features/setjmp exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/setjmp done FEATURE/setjmp dontcare generated prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit make ${PACKAGE_ast_INCLUDE}/sig.h implicit done ${PACKAGE_ast_INCLUDE}/sig.h dontcare done include/fault.h dontcare make include/history.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/history.h dontcare prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit prev FEATURE/options implicit prev FEATURE/externs implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/defs.h done bltins/alarm.c meta alarm.o %.c>%.o bltins/alarm.c alarm prev bltins/alarm.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/alarm.c done alarm.o generated make cd_pwd.o make bltins/cd_pwd.c make include/test.h implicit prev include/shtable.h implicit prev include/defs.h implicit prev FEATURE/options implicit done include/test.h make ${PACKAGE_ast_INCLUDE}/ls.h implicit make ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit done ${PACKAGE_ast_INCLUDE}/ast_mode.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ls.h prev include/builtins.h implicit prev include/name.h implicit make include/path.h implicit make FEATURE/acct implicit meta FEATURE/acct >FEATURE/% acct exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : def acct done FEATURE/acct dontcare generated prev include/defs.h implicit prev include/nval.h implicit prev FEATURE/options implicit done include/path.h make include/variables.h implicit prev FEATURE/dynamic implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/option.h implicit prev include/nval.h implicit done include/variables.h prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev include/defs.h implicit done bltins/cd_pwd.c meta cd_pwd.o %.c>%.o bltins/cd_pwd.c cd_pwd prev bltins/cd_pwd.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/cd_pwd.c done cd_pwd.o generated make cflow.o make bltins/cflow.c prev include/builtins.h implicit make include/shnodes.h implicit prev include/argnod.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/shnodes.h prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev include/defs.h implicit done bltins/cflow.c meta cflow.o %.c>%.o bltins/cflow.c cflow prev bltins/cflow.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/cflow.c done cflow.o generated make deparse.o make sh/deparse.c prev include/test.h implicit prev include/shnodes.h implicit prev include/defs.h implicit done sh/deparse.c meta deparse.o %.c>%.o sh/deparse.c deparse prev sh/deparse.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/deparse.c done deparse.o generated make enum.o make bltins/enum.c prev include/defs.h implicit done bltins/enum.c meta enum.o %.c>%.o bltins/enum.c enum prev bltins/enum.c exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=${SH_DICT} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/enum.c prev SHOPT.sh done enum.o generated make getopts.o make bltins/getopts.c prev include/builtins.h implicit prev include/nval.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/variables.h implicit prev include/defs.h implicit done bltins/getopts.c meta getopts.o %.c>%.o bltins/getopts.c getopts prev bltins/getopts.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/getopts.c done getopts.o generated make hist.o make bltins/hist.c make include/edit.h implicit make include/national.h implicit done include/national.h dontcare make include/terminal.h implicit make FEATURE/ttys implicit meta FEATURE/ttys features/%>FEATURE/% features/ttys ttys make features/ttys done features/ttys exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/ttys done FEATURE/ttys dontcare generated done include/terminal.h dontcare prev FEATURE/setjmp implicit prev ${PACKAGE_ast_INCLUDE}/sig.h implicit make FEATURE/locale implicit meta FEATURE/locale features/%>FEATURE/% features/locale locale make features/locale done features/locale exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/locale done FEATURE/locale dontcare generated prev FEATURE/options implicit done include/edit.h dontcare prev include/builtins.h implicit prev include/history.h implicit prev include/name.h implicit make include/io.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/io.h prev include/variables.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev include/defs.h implicit done bltins/hist.c meta hist.o %.c>%.o bltins/hist.c hist prev bltins/hist.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/hist.c done hist.o generated make misc.o make bltins/misc.c prev ${PACKAGE_ast_INCLUDE}/times.h implicit prev FEATURE/time implicit prev FEATURE/locale implicit make include/jobs.h implicit prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit prev include/terminal.h implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/jobs.h prev include/builtins.h implicit prev include/history.h implicit prev include/name.h implicit prev include/io.h implicit prev include/path.h implicit prev include/shnodes.h implicit prev include/variables.h implicit prev include/defs.h implicit done bltins/misc.c meta misc.o %.c>%.o bltins/misc.c misc prev bltins/misc.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/misc.c done misc.o generated make print.o make bltins/print.c make ${PACKAGE_ast_INCLUDE}/ccode.h implicit make ${PACKAGE_ast_INCLUDE}/ast_ccode.h implicit done ${PACKAGE_ast_INCLUDE}/ast_ccode.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ccode.h make ${PACKAGE_ast_INCLUDE}/tmx.h implicit make ${PACKAGE_ast_INCLUDE}/tv.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done ${PACKAGE_ast_INCLUDE}/tv.h dontcare make ${PACKAGE_ast_INCLUDE}/tm.h implicit prev ${PACKAGE_ast_INCLUDE}/times.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/tm.h dontcare done ${PACKAGE_ast_INCLUDE}/tmx.h make include/streval.h implicit make ${PACKAGE_ast_INCLUDE}/ast_float.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit done ${PACKAGE_ast_INCLUDE}/ast_float.h dontcare prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done include/streval.h prev include/builtins.h implicit prev include/history.h implicit prev include/name.h implicit prev include/io.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/print.c meta print.o %.c>%.o bltins/print.c print prev bltins/print.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/print.c done print.o generated make read.o make bltins/read.c prev include/edit.h implicit prev include/terminal.h implicit prev include/history.h implicit prev include/builtins.h implicit prev include/name.h implicit prev include/io.h implicit make include/lexstates.h implicit prev ${PACKAGE_ast_INCLUDE}/wctype.h implicit prev ${PACKAGE_ast_INCLUDE}/wchar.h implicit prev FEATURE/locale implicit done include/lexstates.h prev include/variables.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done bltins/read.c meta read.o %.c>%.o bltins/read.c read prev bltins/read.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/read.c done read.o generated make sleep.o make bltins/sleep.c make FEATURE/poll implicit meta FEATURE/poll features/%>FEATURE/% features/poll poll make features/poll done features/poll exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/poll done FEATURE/poll generated prev FEATURE/time implicit prev include/builtins.h implicit prev ${PACKAGE_ast_INCLUDE}/tmx.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/sleep.c meta sleep.o %.c>%.o bltins/sleep.c sleep prev bltins/sleep.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/sleep.c done sleep.o generated make trap.o make bltins/trap.c prev include/builtins.h implicit prev include/jobs.h implicit prev include/defs.h implicit done bltins/trap.c meta trap.o %.c>%.o bltins/trap.c trap prev bltins/trap.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/trap.c done trap.o generated make test.o make bltins/test.c prev ${PACKAGE_ast_INCLUDE}/tmx.h implicit prev FEATURE/poll implicit prev FEATURE/externs implicit prev include/builtins.h implicit prev include/test.h implicit prev include/terminal.h implicit prev include/io.h implicit prev ${PACKAGE_ast_INCLUDE}/regex.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/test.c meta test.o %.c>%.o bltins/test.c test prev bltins/test.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/test.c done test.o generated make typeset.o make bltins/typeset.c prev FEATURE/dynamic implicit prev include/variables.h implicit prev include/builtins.h implicit prev include/history.h implicit prev include/name.h implicit prev include/path.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/typeset.c meta typeset.o %.c>%.o bltins/typeset.c typeset prev bltins/typeset.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/typeset.c done typeset.o generated make ulimit.o make bltins/ulimit.c make include/ulimit.h implicit make FEATURE/rlimits implicit meta FEATURE/rlimits features/%>FEATURE/% features/rlimits rlimits make features/rlimits done features/rlimits exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/rlimits done FEATURE/rlimits dontcare generated prev FEATURE/time implicit done include/ulimit.h prev include/name.h implicit prev include/builtins.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done bltins/ulimit.c meta ulimit.o %.c>%.o bltins/ulimit.c ulimit prev bltins/ulimit.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/ulimit.c done ulimit.o generated make umask.o make bltins/umask.c prev include/builtins.h implicit prev include/shell.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done bltins/umask.c meta umask.o %.c>%.o bltins/umask.c umask prev bltins/umask.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/umask.c done umask.o generated make whence.o make bltins/whence.c prev include/builtins.h implicit make include/shlex.h implicit prev include/lexstates.h implicit prev include/shtable.h implicit prev include/shnodes.h implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/cdt.h implicit done include/shlex.h prev include/path.h implicit prev include/name.h implicit prev include/shtable.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/whence.c meta whence.o %.c>%.o bltins/whence.c whence prev bltins/whence.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/whence.c done whence.o generated make main.o make sh/main.c make execargs.h implicit done execargs.h dontcare virtual make nc.h implicit done nc.h dontcare virtual prev FEATURE/externs implicit make FEATURE/execargs implicit meta FEATURE/execargs >FEATURE/% execargs exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : def execargs done FEATURE/execargs generated make FEATURE/pstat implicit meta FEATURE/pstat >FEATURE/% pstat exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : def pstat done FEATURE/pstat generated make FEATURE/setproctitle implicit meta FEATURE/setproctitle >FEATURE/% setproctitle exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : def setproctitle done FEATURE/setproctitle generated prev FEATURE/time implicit make include/timeout.h implicit done include/timeout.h prev include/history.h implicit prev include/shnodes.h implicit prev include/shlex.h implicit prev include/jobs.h implicit prev include/io.h implicit prev include/path.h implicit prev include/variables.h implicit prev include/defs.h implicit make include/fcin.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit done include/fcin.h prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/main.c meta main.o %.c>%.o sh/main.c main prev sh/main.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${SHOPT_TIMEOUT+-DSHOPT_TIMEOUT=${SHOPT_TIMEOUT}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_REMOTE+-DSHOPT_REMOTE=${SHOPT_REMOTE}} ${SHOPT_OLDTERMIO+-DSHOPT_OLDTERMIO=${SHOPT_OLDTERMIO}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -DSH_DICT=${SH_DICT} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/main.c done main.o generated make nvdisc.o make sh/nvdisc.c prev include/shlex.h implicit prev include/io.h implicit prev include/path.h implicit prev include/builtins.h implicit prev include/variables.h implicit prev include/defs.h implicit done sh/nvdisc.c meta nvdisc.o %.c>%.o sh/nvdisc.c nvdisc prev sh/nvdisc.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/nvdisc.c done nvdisc.o generated make nvtype.o make sh/nvtype.c prev include/variables.h implicit prev include/io.h implicit prev include/defs.h implicit done sh/nvtype.c meta nvtype.o %.c>%.o sh/nvtype.c nvtype prev sh/nvtype.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c sh/nvtype.c done nvtype.o generated make arith.o make sh/arith.c prev include/builtins.h implicit prev include/variables.h implicit prev include/streval.h implicit prev include/name.h implicit prev include/lexstates.h implicit prev include/defs.h implicit done sh/arith.c meta arith.o %.c>%.o sh/arith.c arith prev sh/arith.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c sh/arith.c done arith.o generated make args.o make sh/args.c prev include/io.h implicit prev include/shlex.h implicit prev FEATURE/poll implicit prev include/edit.h implicit prev include/terminal.h implicit prev include/builtins.h implicit prev include/jobs.h implicit prev include/path.h implicit prev include/defs.h implicit done sh/args.c meta args.o %.c>%.o sh/args.c args prev sh/args.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/args.c done args.o generated make array.o make sh/array.c prev include/name.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev include/defs.h implicit done sh/array.c meta array.o %.c>%.o sh/array.c array prev sh/array.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/array.c done array.o generated make completion.o make edit/completion.c prev include/history.h implicit prev include/edit.h implicit prev include/io.h implicit prev include/path.h implicit prev include/lexstates.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit prev include/defs.h implicit done edit/completion.c meta completion.o %.c>%.o edit/completion.c completion prev edit/completion.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c edit/completion.c done completion.o generated make defs.o make sh/defs.c prev include/timeout.h implicit prev include/edit.h implicit prev include/shlex.h implicit prev include/jobs.h implicit prev include/defs.h implicit done sh/defs.c meta defs.o %.c>%.o sh/defs.c defs prev sh/defs.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c sh/defs.c done defs.o generated make edit.o make edit/edit.c prev include/shlex.h implicit prev include/edit.h implicit prev include/history.h implicit prev include/terminal.h implicit prev include/io.h implicit prev include/variables.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit make FEATURE/cmds implicit meta FEATURE/cmds features/%>FEATURE/% features/cmds cmds make features/cmds done features/cmds exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/cmds done FEATURE/cmds generated prev FEATURE/time implicit prev FEATURE/options implicit prev include/fault.h implicit prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done edit/edit.c meta edit.o %.c>%.o edit/edit.c edit prev edit/edit.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/edit.c done edit.o generated make expand.o make sh/expand.c prev include/path.h implicit prev include/io.h implicit make ${PACKAGE_ast_INCLUDE}/ast_dir.h implicit make ${PACKAGE_ast_INCLUDE}/dirent.h implicit make ${PACKAGE_ast_INCLUDE}/ast_dirent.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit done ${PACKAGE_ast_INCLUDE}/ast_dirent.h dontcare done ${PACKAGE_ast_INCLUDE}/dirent.h dontcare make dirlib.h implicit done dirlib.h dontcare virtual prev ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/ast_dir.h prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit make ${PACKAGE_ast_INCLUDE}/glob.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/glob.h prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev include/test.h implicit prev include/variables.h implicit prev include/defs.h implicit done sh/expand.c meta expand.o %.c>%.o sh/expand.c expand prev sh/expand.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/expand.c done expand.o generated make regress.o make bltins/regress.c prev ${PACKAGE_ast_INCLUDE}/tmx.h implicit prev include/builtins.h implicit prev include/io.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/defs.h implicit done bltins/regress.c meta regress.o %.c>%.o bltins/regress.c regress prev bltins/regress.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c bltins/regress.c done regress.o generated make fault.o make sh/fault.c prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit prev include/ulimit.h implicit prev include/builtins.h implicit prev include/path.h implicit prev include/jobs.h implicit prev include/variables.h implicit prev include/shlex.h implicit prev include/history.h implicit prev include/io.h implicit prev include/fcin.h implicit prev include/defs.h implicit done sh/fault.c meta fault.o %.c>%.o sh/fault.c fault prev sh/fault.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/fault.c done fault.o generated make fcin.o make sh/fcin.c prev include/fcin.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/fcin.c meta fcin.o %.c>%.o sh/fcin.c fcin prev sh/fcin.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/fcin.c done fcin.o generated make history.o make edit/history.c prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit prev include/history.h implicit prev include/io.h implicit prev include/builtins.h implicit prev include/path.h implicit prev include/variables.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev FEATURE/time implicit prev ${PACKAGE_ast_INCLUDE}/sfio.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done edit/history.c meta history.o %.c>%.o edit/history.c history prev edit/history.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c edit/history.c done history.o generated make init.o make sh/init.c prev ${PACKAGE_ast_INCLUDE}/wctype.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit make include/version.h implicit done include/version.h prev include/lexstates.h implicit prev FEATURE/externs implicit prev FEATURE/dynamic implicit prev FEATURE/time implicit prev include/builtins.h implicit prev include/shlex.h implicit prev include/io.h implicit prev include/jobs.h implicit prev include/edit.h implicit prev include/name.h implicit prev include/fault.h implicit prev include/path.h implicit prev include/variables.h implicit prev ${PACKAGE_ast_INCLUDE}/regex.h implicit prev ${PACKAGE_ast_INCLUDE}/tmx.h implicit prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev include/defs.h implicit done sh/init.c meta init.o %.c>%.o sh/init.c init prev sh/init.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/init.c done init.o generated make io.o make sh/io.c prev ${PACKAGE_ast_INCLUDE}/endian.h implicit prev FEATURE/poll implicit prev FEATURE/dynamic implicit prev FEATURE/externs implicit prev include/timeout.h implicit prev include/edit.h implicit prev include/history.h implicit prev include/shnodes.h implicit prev include/shlex.h implicit prev include/jobs.h implicit prev include/io.h implicit prev include/path.h implicit prev include/variables.h implicit prev ${PACKAGE_ast_INCLUDE}/regex.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev include/fcin.h implicit prev include/defs.h implicit done sh/io.c meta io.o %.c>%.o sh/io.c io prev sh/io.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c sh/io.c done io.o generated make jobs.o make sh/jobs.c prev include/history.h implicit prev include/jobs.h implicit prev include/io.h implicit make ${PACKAGE_ast_INCLUDE}/wait.h implicit make ${PACKAGE_ast_INCLUDE}/ast_wait.h implicit done ${PACKAGE_ast_INCLUDE}/ast_wait.h dontcare prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit done ${PACKAGE_ast_INCLUDE}/wait.h prev include/defs.h implicit done sh/jobs.c meta jobs.o %.c>%.o sh/jobs.c jobs prev sh/jobs.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/jobs.c done jobs.o generated make lex.o make sh/lex.c prev include/shlex.h implicit prev include/io.h implicit prev include/lexstates.h implicit prev include/test.h implicit prev include/argnod.h implicit prev include/shell.h implicit prev include/defs.h implicit prev FEATURE/options implicit prev include/nval.h implicit prev include/fcin.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/lex.c meta lex.o %.c>%.o sh/lex.c lex prev sh/lex.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/lex.c done lex.o generated make macro.o make sh/macro.c prev include/streval.h implicit prev include/national.h implicit prev include/path.h implicit prev include/shnodes.h implicit prev include/jobs.h implicit prev include/io.h implicit prev include/shlex.h implicit prev include/variables.h implicit prev include/name.h implicit prev ${PACKAGE_ast_INCLUDE}/regex.h implicit prev include/fcin.h implicit prev include/defs.h implicit done sh/macro.c meta macro.o %.c>%.o sh/macro.c macro prev sh/macro.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/macro.c done macro.o generated make name.o make sh/name.c prev include/builtins.h implicit prev include/shnodes.h implicit prev include/streval.h implicit prev FEATURE/externs implicit prev include/timeout.h implicit prev include/lexstates.h implicit prev include/path.h implicit prev include/variables.h implicit prev include/defs.h implicit done sh/name.c meta name.o %.c>%.o sh/name.c name prev sh/name.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c sh/name.c done name.o generated make nvtree.o make sh/nvtree.c prev include/lexstates.h implicit prev include/argnod.h implicit prev include/name.h implicit prev include/defs.h implicit done sh/nvtree.c meta nvtree.o %.c>%.o sh/nvtree.c nvtree prev sh/nvtree.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/nvtree.c done nvtree.o generated make parse.o make sh/parse.c prev include/path.h implicit prev include/test.h implicit prev include/builtins.h implicit prev include/history.h implicit prev include/shlex.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/fcin.h implicit prev include/shell.h implicit prev include/defs.h implicit prev include/version.h implicit done sh/parse.c meta parse.o %.c>%.o sh/parse.c parse prev sh/parse.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/parse.c done parse.o generated make path.o make sh/path.c prev FEATURE/time implicit prev ${PACKAGE_ast_INCLUDE}/endian.h implicit make ${PACKAGE_ast_INCLUDE}/ast_vfork.h implicit done ${PACKAGE_ast_INCLUDE}/ast_vfork.h dontcare make exec_attr.h implicit done exec_attr.h dontcare virtual prev FEATURE/externs implicit prev FEATURE/dynamic implicit prev include/test.h implicit prev include/history.h implicit prev include/jobs.h implicit prev include/io.h implicit prev include/path.h implicit prev include/variables.h implicit prev include/nval.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev include/fcin.h implicit prev include/defs.h implicit done sh/path.c meta path.o %.c>%.o sh/path.c path prev sh/path.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/path.c done path.o generated make string.o make sh/string.c prev ${PACKAGE_ast_INCLUDE}/wctype.h implicit prev include/national.h implicit prev include/lexstates.h implicit prev include/shtable.h implicit prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/string.c meta string.o %.c>%.o sh/string.c string prev sh/string.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/string.c done string.o generated make streval.o make sh/streval.c prev include/defs.h implicit prev FEATURE/externs implicit prev ${PACKAGE_ast_INCLUDE}/stak.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev include/streval.h implicit done sh/streval.c meta streval.o %.c>%.o sh/streval.c streval prev sh/streval.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/streval.c done streval.o generated make subshell.o make sh/subshell.c prev include/path.h implicit prev include/variables.h implicit prev include/jobs.h implicit prev include/shlex.h implicit prev include/shnodes.h implicit prev include/fault.h implicit prev include/io.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev include/defs.h implicit done sh/subshell.c meta subshell.o %.c>%.o sh/subshell.c subshell prev sh/subshell.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/subshell.c done subshell.o generated make tdump.o make sh/tdump.c prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev include/io.h implicit prev include/path.h implicit prev include/shnodes.h implicit prev include/defs.h implicit done sh/tdump.c meta tdump.o %.c>%.o sh/tdump.c tdump prev sh/tdump.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/tdump.c done tdump.o generated make timers.o make sh/timers.c prev FEATURE/time implicit prev FEATURE/sigfeatures implicit prev include/defs.h implicit prev include/fault.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sig.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/timers.c meta timers.o %.c>%.o sh/timers.c timers prev sh/timers.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/timers.c done timers.o generated make trestore.o make sh/trestore.c prev ${PACKAGE_ast_INCLUDE}/ccode.h implicit prev include/io.h implicit prev include/path.h implicit prev include/shnodes.h implicit prev include/defs.h implicit done sh/trestore.c meta trestore.o %.c>%.o sh/trestore.c trestore prev sh/trestore.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/trestore.c done trestore.o generated make waitevent.o make sh/waitevent.c prev include/defs.h implicit done sh/waitevent.c meta waitevent.o %.c>%.o sh/waitevent.c waitevent prev sh/waitevent.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/waitevent.c done waitevent.o generated make xec.o make sh/xec.c prev ${PACKAGE_ast_INCLUDE}/ast_vfork.h implicit prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit prev include/streval.h implicit prev FEATURE/locale implicit prev FEATURE/externs implicit prev FEATURE/time implicit prev include/builtins.h implicit prev include/test.h implicit prev include/jobs.h implicit prev include/shnodes.h implicit prev include/io.h implicit prev include/name.h implicit prev include/path.h implicit prev include/variables.h implicit prev include/fcin.h implicit prev include/defs.h implicit done sh/xec.c meta xec.o %.c>%.o sh/xec.c xec prev sh/xec.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/xec.c done xec.o generated make limits.o make data/limits.c prev include/ulimit.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done data/limits.c meta limits.o %.c>%.o data/limits.c limits prev data/limits.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -c data/limits.c done limits.o generated make msg.o make data/msg.c prev FEATURE/cmds implicit prev include/edit.h implicit prev include/jobs.h implicit prev include/builtins.h implicit prev include/history.h implicit prev include/timeout.h implicit prev include/shlex.h implicit prev include/io.h implicit prev include/path.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done data/msg.c meta msg.o %.c>%.o data/msg.c msg prev data/msg.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c data/msg.c done msg.o generated make strdata.o make data/strdata.c make FEATURE/math implicit meta FEATURE/math features/%.sh>FEATURE/% features/math.sh math make features/math.sh make data/math.tab implicit done data/math.tab done features/math.sh dontcare exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/math.sh ${PACKAGEROOT}/src/cmd/ksh93/data/math.tab make ${PACKAGE_ast_INCLUDE}/ast_standards.h implicit done ${PACKAGE_ast_INCLUDE}/ast_standards.h dontcare make ${INSTALLROOT}/src/lib/libast/FEATURE/float implicit make ${INSTALLROOT}/src/lib/libast/FEATURE/standards implicit done ${INSTALLROOT}/src/lib/libast/FEATURE/standards dontcare prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit done ${INSTALLROOT}/src/lib/libast/FEATURE/float dontcare done FEATURE/math generated prev include/streval.h implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/ast_standards.h implicit done data/strdata.c meta strdata.o %.c>%.o data/strdata.c strdata prev data/strdata.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c data/strdata.c done strdata.o generated make testops.o make data/testops.c prev include/test.h implicit prev include/defs.h implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done data/testops.c meta testops.o %.c>%.o data/testops.c testops prev data/testops.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c data/testops.c done testops.o generated make keywords.o make data/keywords.c prev FEATURE/options implicit prev include/shlex.h implicit prev include/shell.h implicit done data/keywords.c meta keywords.o %.c>%.o data/keywords.c keywords prev data/keywords.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c data/keywords.c done keywords.o generated make options.o make data/options.c prev include/shtable.h implicit prev include/name.h implicit prev include/defs.h implicit done data/options.c meta options.o %.c>%.o data/options.c options prev data/options.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c data/options.c done options.o generated make signals.o make data/signals.c prev include/jobs.h implicit prev include/defs.h implicit done data/signals.c meta signals.o %.c>%.o data/signals.c signals prev data/signals.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c data/signals.c done signals.o generated make aliases.o make data/aliases.c prev FEATURE/dynamic implicit prev FEATURE/options implicit prev include/defs.h implicit done data/aliases.c meta aliases.o %.c>%.o data/aliases.c aliases prev data/aliases.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c data/aliases.c done aliases.o generated make builtins.o make data/builtins.c prev FEATURE/cmds implicit prev include/jobs.h implicit prev include/builtins.h implicit prev include/version.h implicit prev include/name.h implicit prev include/ulimit.h implicit prev include/shtable.h implicit prev include/defs.h implicit done data/builtins.c meta builtins.o %.c>%.o data/builtins.c builtins prev data/builtins.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -DSH_DICT=${SH_DICT} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c data/builtins.c done builtins.o generated make variables.o make data/variables.c prev include/builtins.h implicit prev include/variables.h implicit prev include/defs.h implicit prev include/name.h implicit prev include/shtable.h implicit prev include/shell.h implicit prev FEATURE/dynamic implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done data/variables.c meta variables.o %.c>%.o data/variables.c variables prev data/variables.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c data/variables.c done variables.o generated make lexstates.o make data/lexstates.c prev include/lexstates.h implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done data/lexstates.c meta lexstates.o %.c>%.o data/lexstates.c lexstates prev data/lexstates.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -c data/lexstates.c done lexstates.o generated make emacs.o make edit/emacs.c prev include/terminal.h implicit prev include/edit.h implicit prev include/history.h implicit prev include/io.h implicit prev include/defs.h implicit prev FEATURE/cmds implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done edit/emacs.c meta emacs.o %.c>%.o edit/emacs.c emacs prev edit/emacs.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/emacs.c done emacs.o generated make vi.o make edit/vi.c prev include/lexstates.h implicit prev FEATURE/time implicit prev include/terminal.h implicit prev include/edit.h implicit prev include/history.h implicit prev include/io.h implicit prev FEATURE/options implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit prev include/defs.h implicit done edit/vi.c meta vi.o %.c>%.o edit/vi.c vi prev edit/vi.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c edit/vi.c done vi.o generated make hexpand.o make edit/hexpand.c prev include/edit.h implicit prev include/defs.h implicit done edit/hexpand.c meta hexpand.o %.c>%.o edit/hexpand.c hexpand prev edit/hexpand.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c done hexpand.o generated exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o deparse.o enum.o getopts.o hist.o misc.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o exec - (ranlib libshell.a) >/dev/null 2>&1 || true done libshell.a generated bind -lshell prev +ljobs prev +li prev ${mam_libsocket} prev ${mam_libsecdb} exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o ksh pmain.o ${mam_libshell} ${mam_libnsl} ${mam_libast} done ksh generated make shcomp make shcomp.o make sh/shcomp.c prev include/terminal.h implicit prev include/shnodes.h implicit prev include/path.h implicit prev include/defs.h implicit prev include/shell.h implicit prev include/version.h implicit done sh/shcomp.c meta shcomp.o %.c>%.o sh/shcomp.c shcomp prev sh/shcomp.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSH_DICT=${SH_DICT} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/shcomp.c done shcomp.o generated prev libshell.a archive prev +ljobs prev +li prev ${mam_libsocket} prev ${mam_libsecdb} exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o shcomp shcomp.o ${mam_libshell} ${mam_libnsl} ${mam_libast} done shcomp generated make suid_exec make suid_exec.o make sh/suid_exec.c prev include/version.h implicit prev ${PACKAGE_ast_INCLUDE}/error.h implicit prev ${PACKAGE_ast_INCLUDE}/sig.h implicit prev ${PACKAGE_ast_INCLUDE}/ls.h implicit prev FEATURE/externs implicit prev ${PACKAGE_ast_INCLUDE}/ast.h implicit done sh/suid_exec.c meta suid_exec.o %.c>%.o sh/suid_exec.c suid_exec prev sh/suid_exec.c prev SHOPT.sh exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DERROR_CONTEXT_T=Error_context_t -D_API_ast=20100309 -D_PACKAGE_ast -c sh/suid_exec.c done suid_exec.o generated prev +ljobs prev +li prev ${mam_libsocket} prev ${mam_libsecdb} exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS} -lm ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o suid_exec suid_exec.o ${mam_libast} ${mam_libnsl} ${mam_libast} done suid_exec generated make shell prev libshell.a archive done shell virtual prev libshell.a archive make ${INSTALLROOT}/bin exec - if silent test ! -d ${INSTALLROOT}/bin exec - then mkdir -p ${INSTALLROOT}/bin exec - fi done ${INSTALLROOT}/bin generated make ${INSTALLROOT}/bin/ksh prev ${INSTALLROOT}/bin prev ksh exec - test '' = 'ksh' || ${STDCMP} 2>/dev/null -s ksh ${INSTALLROOT}/bin/ksh || { ${STDMV} ${INSTALLROOT}/bin/ksh ${INSTALLROOT}/bin/ksh.old 2>/dev/null || true; ${STDCP} ksh ${INSTALLROOT}/bin/ksh ;} done ${INSTALLROOT}/bin/ksh generated make ${INSTALLROOT}/man/man1 exec - if silent test ! -d ${INSTALLROOT}/man/man1 exec - then mkdir -p ${INSTALLROOT}/man/man1 exec - fi done ${INSTALLROOT}/man/man1 generated make ${INSTALLROOT}/man/man1/sh.1 prev ${INSTALLROOT}/man/man1 make sh.1 done sh.1 exec - test '' = 'sh.1' || ${STDCMP} 2>/dev/null -s sh.1 ${INSTALLROOT}/man/man1/sh.1 || { ${STDMV} ${INSTALLROOT}/man/man1/sh.1 ${INSTALLROOT}/man/man1/sh.1.old 2>/dev/null || true; ${STDCP} sh.1 ${INSTALLROOT}/man/man1/sh.1 ;} done ${INSTALLROOT}/man/man1/sh.1 generated make ${INSTALLROOT}/lib exec - if silent test ! -d ${INSTALLROOT}/lib exec - then mkdir -p ${INSTALLROOT}/lib exec - fi done ${INSTALLROOT}/lib generated make ${INSTALLROOT}/lib/libshell.a archive prev ${INSTALLROOT}/lib prev libshell.a archive exec - test '' = 'libshell.a' || ${STDCMP} 2>/dev/null -s libshell.a ${INSTALLROOT}/lib/libshell.a || { ${STDMV} ${INSTALLROOT}/lib/libshell.a ${INSTALLROOT}/lib/libshell.a.old 2>/dev/null || true; ${STDCP} libshell.a ${INSTALLROOT}/lib/libshell.a ;} exec - (ranlib ${INSTALLROOT}/lib/libshell.a) >/dev/null 2>&1 || true done ${INSTALLROOT}/lib/libshell.a generated make ${INSTALLROOT}/man/man3 exec - if silent test ! -d ${INSTALLROOT}/man/man3 exec - then mkdir -p ${INSTALLROOT}/man/man3 exec - fi done ${INSTALLROOT}/man/man3 generated make ${INSTALLROOT}/man/man3/shell.3 prev ${INSTALLROOT}/man/man3 make shell.3 done shell.3 exec - test '' = 'shell.3' || ${STDCMP} 2>/dev/null -s shell.3 ${INSTALLROOT}/man/man3/shell.3 || { ${STDMV} ${INSTALLROOT}/man/man3/shell.3 ${INSTALLROOT}/man/man3/shell.3.old 2>/dev/null || true; ${STDCP} shell.3 ${INSTALLROOT}/man/man3/shell.3 ;} done ${INSTALLROOT}/man/man3/shell.3 generated make ${INSTALLROOT}/man/man3/nval.3 make nval.3 done nval.3 exec - test '' = 'nval.3' || ${STDCMP} 2>/dev/null -s nval.3 ${INSTALLROOT}/man/man3/nval.3 || { ${STDMV} ${INSTALLROOT}/man/man3/nval.3 ${INSTALLROOT}/man/man3/nval.3.old 2>/dev/null || true; ${STDCP} nval.3 ${INSTALLROOT}/man/man3/nval.3 ;} done ${INSTALLROOT}/man/man3/nval.3 generated make ${INSTALLROOT}/lib/lib exec - if silent test ! -d ${INSTALLROOT}/lib/lib exec - then mkdir -p ${INSTALLROOT}/lib/lib exec - fi done ${INSTALLROOT}/lib/lib generated make ${INSTALLROOT}/lib/lib/shell prev ${INSTALLROOT}/lib/lib prev shell.req exec - test '' = 'shell.req' || ${STDCMP} 2>/dev/null -s shell.req ${INSTALLROOT}/lib/lib/shell || { ${STDMV} ${INSTALLROOT}/lib/lib/shell ${INSTALLROOT}/lib/lib/shell.old 2>/dev/null || true; ${STDCP} shell.req ${INSTALLROOT}/lib/lib/shell ;} done ${INSTALLROOT}/lib/lib/shell generated make ${PACKAGE_ast_INCLUDE} exec - if silent test ! -d ${PACKAGE_ast_INCLUDE} exec - then mkdir -p ${PACKAGE_ast_INCLUDE} exec - fi done ${PACKAGE_ast_INCLUDE} generated make ${PACKAGE_ast_INCLUDE}/nval.h prev ${PACKAGE_ast_INCLUDE} prev include/nval.h exec - proto -p -s include/nval.h > 1.${COTEMP}.x exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/nval.h 1.${COTEMP}.x exec - then rm -f 1.${COTEMP}.x exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/nval.h exec - fi done ${PACKAGE_ast_INCLUDE}/nval.h generated make ${PACKAGE_ast_INCLUDE}/shell.h prev include/shell.h exec - proto -p -s include/shell.h > 1.${COTEMP}.x exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/shell.h 1.${COTEMP}.x exec - then rm -f 1.${COTEMP}.x exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/shell.h exec - fi done ${PACKAGE_ast_INCLUDE}/shell.h generated make ${PACKAGE_ast_INCLUDE}/history.h prev include/history.h exec - proto -p -s include/history.h > 1.${COTEMP}.x exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/history.h 1.${COTEMP}.x exec - then rm -f 1.${COTEMP}.x exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/history.h exec - fi done ${PACKAGE_ast_INCLUDE}/history.h generated make ${INSTALLROOT}/bin/suid_exec prev suid_exec exec - test '' = 'suid_exec' || ${STDCMP} 2>/dev/null -s suid_exec ${INSTALLROOT}/bin/suid_exec || { ${STDMV} ${INSTALLROOT}/bin/suid_exec ${INSTALLROOT}/bin/suid_exec.old 2>/dev/null || true; ${STDCP} suid_exec ${INSTALLROOT}/bin/suid_exec ;} done ${INSTALLROOT}/bin/suid_exec generated make ${INSTALLROOT}/bin/shcomp prev shcomp exec - test '' = 'shcomp' || ${STDCMP} 2>/dev/null -s shcomp ${INSTALLROOT}/bin/shcomp || { ${STDMV} ${INSTALLROOT}/bin/shcomp ${INSTALLROOT}/bin/shcomp.old 2>/dev/null || true; ${STDCP} shcomp ${INSTALLROOT}/bin/shcomp ;} done ${INSTALLROOT}/bin/shcomp generated make ${INSTALLROOT}/fun exec - if silent test ! -d ${INSTALLROOT}/fun exec - then mkdir -p ${INSTALLROOT}/fun exec - fi done ${INSTALLROOT}/fun generated make ${INSTALLROOT}/fun/dirs prev ${INSTALLROOT}/fun make fun/dirs done fun/dirs exec - test '' = 'fun/dirs' || ${STDCMP} 2>/dev/null -s fun/dirs ${INSTALLROOT}/fun/dirs || { ${STDMV} ${INSTALLROOT}/fun/dirs ${INSTALLROOT}/fun/dirs.old 2>/dev/null || true; ${STDCP} fun/dirs ${INSTALLROOT}/fun/dirs && chmod ugo+x ${INSTALLROOT}/fun/dirs ;} done ${INSTALLROOT}/fun/dirs generated make ${INSTALLROOT}/fun/popd make fun/popd done fun/popd exec - test '' = 'fun/popd' || ${STDCMP} 2>/dev/null -s fun/popd ${INSTALLROOT}/fun/popd || { ${STDMV} ${INSTALLROOT}/fun/popd ${INSTALLROOT}/fun/popd.old 2>/dev/null || true; ${STDCP} fun/popd ${INSTALLROOT}/fun/popd && chmod ugo+x ${INSTALLROOT}/fun/popd ;} done ${INSTALLROOT}/fun/popd generated make ${INSTALLROOT}/fun/pushd make fun/pushd done fun/pushd exec - test '' = 'fun/pushd' || ${STDCMP} 2>/dev/null -s fun/pushd ${INSTALLROOT}/fun/pushd || { ${STDMV} ${INSTALLROOT}/fun/pushd ${INSTALLROOT}/fun/pushd.old 2>/dev/null || true; ${STDCP} fun/pushd ${INSTALLROOT}/fun/pushd && chmod ugo+x ${INSTALLROOT}/fun/pushd ;} done ${INSTALLROOT}/fun/pushd generated done install virtual make test make test.ksh prev ${INSTALLROOT}/bin/ksh prev ksh make tests/shtests done tests/shtests exec - silent cmp 2>/dev/null -s ${INSTALLROOT}/bin/ksh ksh 2>/dev/null || exec - echo "make install to run the tests on the latest ksh" >&2 exec - cd exec - SHELL=${INSTALLROOT}/bin/ksh ${INSTALLROOT}/bin/ksh shtests done test.ksh virtual done test dontcare virtual ksh-1.0.0-beta.2/src/cmd/ksh93/OBSOLETE000066400000000000000000000055561415700074400170150ustar00rootroot00000000000000.sp 3 .tl ''Ksh Features That Are Obsolete in Ksh93'' .sp 2 .AL 1 .LI Using a pair of grave accents \^\fB\(ga\fR ... \fB\(ga\fR\^ for command substitution. Use \fB$(\fR ... \fB)\fR instead. .LI .B FCEDIT is an obsolete name for the default editor name for the .B hist command. .B FCEDIT is not used when .B HISTEDIT is set. Use .B HISTEDIT instead. .LI The newtest (\fB[[\fR ... \fB]]\fR) operator \fB\-a\fP \fIfile\fP is obsolete. Use \fB\-e\fP instead. .LI The newtest (\fB[[\fR ... \fB]]\fR) operator .BR = , as used in \fIstring\fP \fB=\fP \fIpattern\fP is obsolete. Use \fB==\fP instead. .LI The following obsolete arithmetic comparisons are also permitted: .in +5 .VL 20 .LI "\fIexp1\fP \fB\-eq\fP \fIexp2\fP" True, if .I exp1 is equal to .IR exp2 . .LI "\fIexp1\fP \fB\-ne\fP \fIexp2\fP" True, if .I exp1 is not equal to .IR exp2 . .LI "\fIexp1\fP \fB\-lt\fP \fIexp2\fP" True, if .I exp1 is less than .IR exp2 . .LI "\fIexp1\fP \fB\-gt\fP \fIexp2\fP" True, if .I exp1 is greater than .IR exp2 . .LI "\fIexp1\fP \fB\-le\fP \fIexp2\fP" True, if .I exp1 is less than or equal to .IR exp2 . .LI "\fIexp1\fP \fB\-ge\fP \fIexp2\fP" True, if .I exp1 is greater than or equal to .IR exp2 . .LE \" End .VL .in -5 .LI Using test -t or [ -t ] without specifying the file unit number. .LI The .B \-k option to the \fBset\fR builtin is obsolete. It causes .I all\^ variable assignment arguments are placed in the environment, even if they occur after the command name. The following first prints .B "a=b c" and then .BR c : There is no alternative. .LI The obsolete .B \-xf option of the .B typeset command allows a function to be exported to scripts that are executed without a separate invocation of the shell. Functions that need to be defined across separate invocations of the shell should be placed in a directory and the .B FPATH variable should contains the name of this directory. They may also be specified in the .B ENV file with the .B \-xf option of .BR typeset . .LI The shell environment variable .B FCEDIT is obsolete. Use .B HISTEDIT instead. .LI In the .B \-s option (to \fBfc\fR or \fBhist\fR command???) ( and in obsolete versions, the editor name .B \- ) is used to skip the editing phase and to re-execute the command. .LI The .B \-t option to \fBalias\fR builtin is obsolete. It is used to set and list tracked aliases. There is no replacement. .LI The shell command line option .B \-t is obsolete. This option causes the shell to exit after reading and executing one command. The is no replacement (although ending \&"command" with the exit builtin should have the same effect). .LI As an obsolete feature of the "set" builtin, if the first .I arg\^ is .B \- then the .B \-x and .B \-v options are turned off and the next .I arg is treated as the first argument. Using .B \+ rather than .B \- causes these options to be turned off. These options can also be used upon invocation of the shell. .LE ksh-1.0.0-beta.2/src/cmd/ksh93/PROMO.mm000066400000000000000000000133031415700074400170720ustar00rootroot00000000000000.H 1 ksh93 KSH-93 is the most recent version of the KornShell Language described in "The KornShell Command and Programming Language," by Morris Bolsky and David Korn of AT&T Bell Laboratories, ISBN 0-13-182700-6. The KornShell is a shell programming language, which is upward compatible with "sh" (the Bourne Shell), and is intended to conform to the IEEE P1003.2/ISO 9945.2 Shell and Utilities standard. KSH-93 provides an enhanced programming environment in addition to the major command-entry features of the BSD shell "csh". With KSH-93, medium-sized programming tasks can be performed at shell-level without a significant loss in performance. In addition, "sh" scripts can be run on KSH-93 without modification. .P The code should conform to the IEEE POSIX 1003.1 standard and to the proposed ANSI C standard so that it should be portable to all such systems. Like the previous version, KSH-88, it is designed to accept eight bit character sets transparently, thereby making it internationally compatible. It can support multi-byte characters sets with some characteristics of the character set given at run time. .P KSH-93 provides the following features, many of which were also inherent in KSH-88: .BL .LI Enhanced Command Re-entry Capability: The KSH-93 history function records commands entered at any shell level and stores them, up to a user-specified limit, even after you log off. This allows you to re-enter long commands with a few keystrokes - even those commands you entered yesterday. The history file allows for eight bit characters in commands and supports essentially unlimited size histories. .LI In-line Editing: In "sh", the only way to fix mistyped commands is to backspace or retype the line. KSH-93 allows you to edit a command line using a choice of EMACS-TC or "vi" functions. You can use the in-line editors to complete filenames as you type them. You may also use this editing feature when entering command lines from your history file. A user can capture keystrokes and rebind keys to customize the editing interface. .LI Extended I/O Capabilities: KSH-93 provides several I/O capabilities not available in "sh", including the ability to: .BL .LI specify a file descriptor for input and output .LI start up and run co-processes .LI produce a prompt at the terminal before a read .LI easily format and interpret responses to a menu .LI echo lines exactly as output without escape processing .LI format output using printf formats. .LI read and echo lines ending in "\e". .LE .LI Improved performance: KSH-93 executes many scripts faster than the System V Bourne shell. A major reason for this is that many of the standard utilities are built-in. To reduce the time to initiate a command, KSH-93 allows commands to be added as built-ins at run time on systems that support dynamic loading such as System V Release 4. .LI Arithmetic: KSH-93 allows you to do integer arithmetic in any base from two to sixty-four. You can also do double precision floating point arithmetic. Almost the complete set of C language operators are available with the same syntax and precedence. Arithmetic expressions can be used to as an argument expansion or as a separate command. In addition there is an arithmetic for command that works like the for statement in C. .LI Arrays: KSH-93 supports both indexed and associative arrays. The subscript for an indexed array is an arithmetic expression, whereas, the subscript for an associative array is a string. .LI Shell Functions and Aliases: Two mechanisms - functions and aliases - can be used to assign a user-selected identifier to an existing command or shell script. Functions allow local variables and provide scoping for exception handling. Functions can be searched for and loaded on first reference the way scripts are. .LI Substring Capabilities: KSH-93 allows you to create a substring of any given string either by specifying the starting offset and length, or by stripping off leading or trailing substrings during parameter expansion. You can also specify attributes, such as upper and lower case, field width, and justification to shell variables. .LI More pattern matching capabilities: KSH-93 allows you to specify extended regular expressions for file and string matches. .LI KSH-93 uses a hierarchical name space for variables. Compound variables can be defined and variables can be passed by reference. In addition, each variable can have one or more disciplines associated with it to intercept assignments and references. .LI Improved debugging: KSH-93 can generate line numbers on execution traces. Also, I/O redirections are now traced. There is a DEBUG trap that gets evaluated before each command so that errors can be localized. .LI Job Control: On systems that support job control, including System V Release 4, KSH-93 provides a job-control mechanism almost identical to that of the BSD "csh", version 4.1. This feature allows you to stop and restart programs, and to move programs between the foreground and the background. .LI Added security: KSH-93 can execute scripts which do not have read permission and scripts which have the setuid and/or setgid set when invoked by name, rather than as an argument to the shell. It is possible to log or control the execution of setuid and/or setgid scripts. The noclobber option prevents you from accidentally erasing a file by redirecting to an existing file. .LI KSH-93 can be extended by adding built-in commands at run time. In addition, KSH-93 can be used as a library that can be embedded into an application to allow scripting. .LE Documentation for KSH-93 consists of an "Introduction to KSH-93", "Compatibility with the Bourne Shell" and a manual page and a README file. In addition, the "New KornShell Command and Programming Language" book is available from Prentice Hall. ksh-1.0.0-beta.2/src/cmd/ksh93/README000066400000000000000000000312521415700074400165260ustar00rootroot00000000000000This directory, and its subdirectories contain the source code for ksh-93; the language described in the second edition of the book, "The KornShell Command and Programming Language," by Morris Bolsky and David Korn which is published by Prentice Hall. ksh-93 has been compiled and run on several machines with several operating systems. The end of this file contains a partial list of operating systems and machines that ksh-93 has been known to run on. Most of the source code for ksh is in the src/cmd/ksh93/sh directory. For information on what's where, see the file DESIGN. #### COMPILE-TIME OPTIONS #### The SHOPT.sh file contains several compilation options that can be set before compiling ksh. Options are of the form SHOPT_option and become #define inside the code. These options are set to their recommended value and some of these may disappear as options in future releases. A value of 0 represents off, 1 represents on, no value means probe. For options where no feature probe is available, probe is the same as off. The options have the following defaults and meanings: 2DMATCH on Two-dimensional ${.sh.match} for ${var//pat/str}. ACCT off Shell accounting. ACCTFILE off Enable per user accounting info. AUDIT off For auditing specific users AUDITFILE "/etc/ksh_audit" BGX on Enables background job extensions. Noted by "J" in the version string when enabled. (1) JOBMAX=n limits the number of concurrent background jobs to n; the (n+1)th background job will block until a running background job completes. (2) SIGCHLD traps are queued so that each completing background job gets its own trap; $! is set to the job pid and $? is set to the job exit status at the beginning of the trap. BRACEPAT on Brace expansion. Expands abc{d,e}f to abcdf abcef. This feature was inspired by the C shell. CMDLIB_HDR "" The header in which you can provide a custom list of libcmd commands to provide as path-bound built-ins. CMDLIB_DIR "\"/opt/ast/bin\"" The default virtual directory prefix for path-bound built-ins. The value must include double quotes. CRNL off treated as in shell grammar. DEVFD Use the more secure /dev/fd mechanism instead of FIFOs for process substitutions. On by default on OSs with /dev/fd. DYNAMIC on Dynamic loading of builtins. (Requires dlopen() interface.) ECHOPRINT off Make echo equivalent to print. EDPREDICT off Enables history pattern search menu. As you begin a line with a #, the following characters are treated as a shell pattern and cause matching lines from the history file to be displayed as a numbered list as you type. You can scroll up and down this list or you can use nTAB to make this the current line (n defaults to 1 if omitted). Experimental. Bugs: https://github.com/ksh93/ksh/issues/233 ESH on Compile with emacs command line editing. The original emacs line editor code was provided by Mike Veach at IH. FILESCAN on Experimental option that allows fast reading of files using while < file;do ...; done and allowing fields in each line to be accessed as positional parameters. FIXEDARRAY on When using typeset, a name in the format NAME[N] creates a fixed-size array and any attempt to access a subscript N or higher is an error. Multidimensional fixed-size arrays NAME[N1][N2]... are also supported. GLOBCASEDET Adds the 'globcasedetect' shell option. When this shell option is turned on, pathname expansion (globbing) and file name listing and completion automatically become case-insensitive on file systems where the difference between upper- and lowercase is ignored for file names. This compile-time option is enabled by default on operating systems that can support case-insensitive file systems. HISTEXPAND on Enable !-style history expansion similar to csh(1). KIA off Allow generation of shell cross-reference database with -R. As of 2021-05-10, no tool that can parse this database is known. If you know of any, please contact us. MULTIBYTE on Multibyte character handling. Requires mblen() and mbctowc(). NAMESPACE on Adds a 'namespace' reserved word that allows defining name spaces. Variables and functions defined within a block like namespace ExampleSpace { commandlist; } all have their names automatically prefixed with '.ExampleSpace.' when defining or using them, creating a separate space of names unique to the block. Outside of the namespace block, they can be accessed using .ExampleSpace.function or ${.ExampleSpace.variable}. Name spaces within name spaces are also supported. NOECHOE off Disable the '-e' option to the 'echo' command, unless SHOPT_ECHOPRINT is enabled. OLDTERMIO off Use either termios or termio at runtime. OPTIMIZE on Optimize loop invariants for with for and while loops. PFSH off Compile with support for profile shell. (Solaris; obsolete) P_SUID off If set, all real uids, greater than or equal to this value will require the -p flag to run suid/sgid scripts. RAWONLY on Turn on if the vi line mode doesn't work right unless you do a set -o viraw. REGRESS off Enable the __regress__ built-in command and instrumented intercepts for testing. REMOTE off Set --rc (read profile scripts) even if ksh was invoked with standard input on a socket, i.e. as a remote shell. SPAWN on Use posix_spawn(3) as combined fork/exec if job control is not active. Improves speed. STATS on Add .sh.stats compound variable. SUID_EXEC on Execute /etc/suid_exec for setuid, setgid script. SYSRC Source /etc/ksh.kshrc on initializing an interactive shell. This is on by default if /etc/ksh.kshrc or /etc/bash.bashrc exists at compile time. TEST_L Add 'test -l' as an alias for 'test -L'. This is on by default if the OS's external 'test' command supports it. TIMEOUT off Set this to the number of seconds for timing out and exiting the shell when you don't enter a command. If non-zero, TMOUT can not be set larger than this value. TYPEDEF on Enable typeset type definitions. VSH on Compile with vi command line editing. The original vi line editor code was provided by Pat Sullivan at CB. #### BUILDING KSH 93U+M #### To build ksh (as well as libcmd and libast libraries on which ksh depends), cd to the top directory and run: bin/package make The compiled binaries are stored in the arch directory, in a subdirectory that corresponds to your architecture. The command 'bin/package host type' outputs the name of this subdirectory. If you have trouble or want to tune the binaries, you may pass additional compiler and linker flags. It is usually best to export these as environment variables before running bin/package as they could change the name of the build subdirectory of the arch directory, so exporting them is a convenient way to keep them consistent between build and test commands. Note that this system uses CCFLAGS instead of the usual CFLAGS. An example that makes Solaris Studio cc produce a 64-bit binary: export CCFLAGS="-m64 -O" LDFLAGS="-m64" bin/package make Alternatively you can append these to the command, and they will only be used for that command. You can also specify an alternative shell in which to run the build scripts this way. For example: bin/package make SHELL=/bin/bash CCFLAGS="-O2 -I/opt/local/include" \ LDFLAGS="-L/opt/local/lib" For more information, run: bin/package help Many other commands in this repo self-document via the --help, --man and --html options; those that do have no separate manual page. Automated installation is not supported yet. To install manually: cp arch/$(bin/package host type)/bin/ksh /usr/local/bin/ cp src/cmd/ksh93/sh.1 /usr/local/share/man/man1/ksh.1 (adapting the destination directories as required). The build should also generate shcomp, a program that will precompile a script. ksh93 is able to recognize files in this format and process them as scripts. You can use shcomp to send out scripts when you don't want to give away the original script source. To be able to run setuid/setgid shell scripts, or scripts without read permission, the SUID_EXEC compile option must be on, and ksh must be installed in the /bin directory, the /usr/bin directory, the /usr/lbin directory, or the /usr/local/bin directory and the name must end in sh. The program suid_exec must be installed in the /etc directory, must be owned by root, and must be a suid program. If you must install ksh in some other directory and want to be able to run setuid/setgid and execute only scripts, then you will have to change the source code file sh/suid_exec.c explicitly. If you do not have ksh in one of these secure locations, /bin/sh will be invoked with the -p options and will fail when you execute a setuid/setgid and/or execute only script. Note that ksh does not read the .profile or $ENV file when the real and effective user/group IDs are not equal. #### TESTING KSH #### The tests subdirectory contains a number of regression tests for ksh. To run all these tests with the shell you just built, run the command bin/shtests For help and more options, type bin/shtests --man #### OTHER DOCUMENTATION #### The file PROMO.mm is an advertisement that extolls the virtues of ksh. The file sh.1 contains the troff (man) description of this Shell. The file nval.3 contains the troff (man) description of the name-value pair library that is needed for writing built-ins that need to access shell variables. The file sh.memo contains a draft troff (mm) memo describing ksh. The file builtins.mm is a draft troff (mm) memo describing how to write built-in commands that can be loaded at run time. The file NEWS in the top-level directory contains bug fixes and other changes made in the ksh 93u+m fork and supporting libraries. The file COMPATIBILITY contains a list of potential incompatibilities. #### TESTED SYSTEMS #### ksh 93u+m 1.0.0.beta-1 has been compiled and tested on the following. An asterisk signifies minor regression test failures (one or two minor things amiss), two asterisks signify moderate regression test failures (some functionality does not work), and three asterisks signify serious failures (crashes, and/or important functionality does not work). * AIX 7.1 on RISC (PowerPC) * DragonFly BSD 5.8 on x86_64 FreeBSD 12.2 on x86_64 FreeBSD 12.2 on arm64 (thanks to hyenias for donating access to a Pi) GNU/Linux: Alpine 3.12.3 (musl C library) on x86_64 GNU/Linux: CentOS 8.2 on x86_64 GNU/Linux: Debian 10.7 on x86_64 GNU/Linux: Gentoo 2.7 on i386 GNU/Linux: NixOS 19.09 on x86_64 GNU/Linux: Slackware 14.2 on x86_64 GNU/Linux: Ubuntu 16.04 on x86_64 GNU/Linux: Ubuntu 18.04 on armv7l (32-bit) GNU/Linux: Ubuntu 20.04 on arm64 GNU/Linux: Void Linux (musl C library) on x86_64 *** HP-UX B.11.11 on pa-risc * illumos: OmniOS 2020-08-19 (gcc) on x86_64 macOS 10.13.6 (High Sierra) on x86_64 macOS 10.14.6 (Mojave) on x86_64 * macOS 12.0.1 (Monterey) on arm64 * NetBSD 8.1 on x86_64 * NetBSD 9.2 on x86_64 * OpenBSD 6.8 on x86_64 ** QNX 6.5.0 on i386 * Solaris 11.4 (gcc) on x86_64 Solaris 11.4 (Solaris Studio 12.5 cc) on x86_64 * UnixWare 7.1.4 on x86 *** Windows 7 using Cygwin on x86 *** Windows 10 using Cygwin on x86_64 *** Windows 11 using Cygwin on x86_64 #### REPORTING BUGS #### Please report any problems or suggestions by opening an issue at: https://github.com/ksh93/ksh Alternatively, email martijn@inlv.org (timely response *not* promised). Good luck!! The ksh 93u+m contributors https://github.com/ksh93/ksh Originally written by: David Korn dgk@research.att.com ksh-1.0.0-beta.2/src/cmd/ksh93/RELEASE000066400000000000000000005430021415700074400166520ustar00rootroot00000000000000This file is of historic interest. For recent changes in both ksh 93u+m and the accompanying libraries, see the file NEWS in the top-level directory. ____ 12-08-01 --- Release ksh93u+ --- 12-08-01 A bug that ignored interrupts for some builtins (e.g. cmdtst::grep) that read from stdin has been fixed. 12-08-01 A bug that interpreted "cd .foo" as "cd foo" has been fixed. 12-07-30 Added automatic restart for EINTR for ioctl, tcgetattr, and tcsetattr. 12-07-23 A scoping error with namrefs to compound associative arrays has been fixed. 12-07-20 A bug where builtin -d /path/foo deleted foo has been fixed. 12-07-18 A bug in which /dev/stdout did not work in command substitution on some systems has been fixed. 12-07-17 A bug in which the restricted option set in a subshell prevented some variables from getting restored when the subshell completed has been fixed. 12-07-09 A bug in which the directory is not restored after a subshell changes the name of the directory for subshells executed in the same process has been fixed. 12-07-09 A bug in which file descriptors created with {n}< file were not being closed has been fixed. 12-07-09 The 12-04-04 fix for cd .. was not correct causing cd /etc;cd .. to remain in /etc. This has been fixed. 12-07-02 A bug in which builtin name did now work for builtins found in a library added by builtin -f lib has been fixed. 12-07-02 A bug in the edit modes which after a directory did not refresh the input line has been fixed. 12-07-02 A bug in which an exit status > 256 corresponding to a signal was not returned by a function to indicate a signal exit has been fixed. 12-06-28 Fix ulimit -a to list (Kibytes) instead of (kbytes). 12-06-27 Fix uninitialized data reference for as first char in --vi mode. 12-06-26 The formatting of printf "%q" for multibyte locales has changed to output using \u[xxx] format for valid wide characters. 12-06-25 The size limit for read -N and read -n has been raised to INT_MAX. 12-06-22 A bug in which an exit trap set in a subshell might not be triggered when the last command was a simple executable has been fixed. 12-06-22 A bug which could cause the shell to hang when a coprocess exits while a command inside a command substitution is reading from it has been fixed. 12-06-21 +ksh new accepts for commands of the form for i; do;...;done 12-06-19 Tab completion after a / when there is only one match not completes with that match rather than generating a menu of matches. 12-06-19 A bug in which patterns containing {...} where not processed correctly inside ${var/pattern/string} has been fixed. 12-06-18 Code modified to eliminate fts_notify variable. 12-06-15 Change the .paths plugin/builtin library variable name from BUILTIN_LIB to PLUGIN_LIB to prevent new plugin_version() aware -lcmd from causing older non-plugin_version() aware ksh to dump core. 12-06-14 builtin without argument no longer lists .sh.tilde as a built-in. 12-06-12 For assignments if the form x=(foo bar), foo is only check for an alias if it is float, integer, compound, or nameref. 12-06-12 +The shell supports 64 bit i-nodes even for 32 bit binaries. 12-06-11 A bug with >; redirection systems for which vfork() was the same a fork() has been fixed. 12-06-11 A bug in path lookup that ignored buffer boundaries has been fixed. 12-06-08 typeset -a var and typeset -A var, first unset var when var is a compound variable. 12-06-08 A bug in which running shcomp on a program containing namespace could core dump has been fixed. 12-06-06 A bug in which unset of an associative array of compound variables did not completely unset the variable has been fixed. 12-06-06 A bug in which exporting left or right justified fields could lose the field width has been fixed. 12-06-06 A bug on Solaris 11 in which >; did not work for /dev/null was fixed. 12-06-05 A race condition which occurred when stopping a builtin command invoked from a subshell has been fixed. 12-06-05 A bug with appending elements to an empty indexed array has been fixed. 12-06-04 A bug in which continuing a stopped builtin could cause it to terminate has been fixed. 12-06-04 By default, builtins added at runtime will restore the current directory if they are killed or stopped. 12-06-04 A bug in handling \\ in read has been fixed. 12-05-31 Use getrlimit64/setrlimit64 on systems that support it. 12-05-31 Fix 64 bit big-endian arithmetic bug that mishandled NaN and Inf. 12-05-31 Handle ECONNRESET like EPIPE. 12-05-31 Change .paths parse to use only the last BUILTIN_LIB from the top and treat BUILTIN_LIB value as a ':' separated list of lib names. 12-05-29 Fix BUILTIN_LIB binding bug that ignored subsequent lookups. 12-05-29 shtests: --nocompile omits the compile test and --compile does only the compile test. 12-05-25 A command substitution containing a here-document that itself contains a here-document no longer hangs. 12-05-24 When the redirection operator >; is directed to a symlink, it now overwrites the file named by the link rather than the link. 12-05-21 +Added printf formats %(type)q where type can be html, url, pattern, ere, or csv. 12-05-18 A bug with appending elements to an indexed array has been fixed. 12-05-18 The exit status from getopts --man interactively was 0 instead of 2 and has been fixed. 12-05-18 Another bug with SHOPT_EDPREDICT which could cause a core dump has been fixed. 12-05-17 A bug with fixed size arrays which could cause a core dump has been fixed. 12-05-17 A bug in which the here-document <<< $(^V, the terminal was not restored to insert mode after a character is entered has been fixed. 12-04-27 A bug in which old attributes were not cleared when assigning a value using typeset has been fixed. 12-04-26 +Enabled multiline editing by default. set +o multiline can disable. 12-04-25 The 12-04-17 PATH fix created a new bug which was fixed. 12-04-25 Fixed a big memory leak problem in which unsetting compound variables did not free all the space. 12-04-25 A bug in which test ! ! ! was treated as an error has been fixed. 12-04-24 A bug with print -v for a compound variable that contained fixed arrays which prevented the output from being used again as input has been fixed. 12-04-23 +kill provides the STKFLT signal on systems that support it. 12-04-23 +The -L option was added to kill. The -L option is the same as -l except that without arguments the output format is in the form of a select menu. 12-04-23 A bug in which the exit status for an interactive shell was always 0 has been fixed. 12-04-20 Entering blank lines interactively no longer resets the exit status. 12-04-18 A bug in file completion in which the second tab completion on a file would list the completion rather than inserting the completion has been fixed. 12-04-18 A bug in which "${arr[@]:i:j}" and "${@:i:j}" generated the empty string when i was a valid subscript and j was <=0 rather than generating nothing has been fixed. 12-04-17 A bug in which read -d delim from a terminal did not respond to interrupt and did not terminate when the delimiter was entered has been fixed. 12-04-17 A bug in which a directory in PATH containing a .paths file that contains a line with FPATH=dir, where dir does not exist could cause the path search to fail has been fixed. 12-04-16 A bug in which $(trap -p) did not display traps such as ERR and DEBUG that are not associated with signals has been fixed. 12-04-11 A bug in which unsetting a variable did not unset attributes when the variable did not have a value has been fixed. 12-04-11 A bug in which read -A for an array whose index is an enumeration type, lost the enumeration type has been fixed. 12-04-10 Shared libraries loaded from a library named by a BUILTIN_LIB= found in a .paths file found in a directory on PATH now add builtins that are associated with the directory in PATH containing the .paths file. 12-04-09 Increased I/O buffer sizes for better performance. 12-04-09 A bug in which the leading 0 was stripped from $x, when $x contained a hexadecimal constant inside an arithmetic expression inside a for or while loop. 12-04-06 Modified namespaces to hand variables FPATH, PATH, and OPTIND that are defined in name spaces appropriately. This also fixed OPTIND and OPTARG processing for functions. 12-04-04 A bug in which cd .. fails when the current directory has been renamed has been fixed. 12-04-02 Made some namespace changes and added a regression test. 12-03-30 A bug with namespaces in which PATH and FPATH set in a namespace was not restored when leaving the namespace has been fixed. 12-03-29 A bug in which appending an indexed array onto an array without elements caused the first element to be 1 rather than 0 has been fixed. 12-03-29 A bug which could cause a core dump when copying a large indexed array has been fixed. 12-03-28 The shell now generates an error message when the sizes with L, Z, and R are > 32767 on 32 bit binaries instead of generating a core dump. 12-03-28 A bug in left and right justification in which the width of invalid characters was not taken as zero has been fixed. 12-03-26 A bug in which typeset -p ref, when ref is a reference to an index array element did not display the subscript has been fixed. 12-03-23 A bug in lowercase and uppercase fields when expanding ${name:=val} when name is the empty string has been fixed. 12-03-22 A namespace bug in which a type t defined in namespace foo could not be referenced outside the namespace as .foo.t has been fixed. 12-03-22 A bug in name reference scoping in which a name function called from another function is pass a name reference to a compound variable instance to be created and the compound variable is in the global scope. 12-03-22 A bug in which ${ref[@}} did not behave like ${arr[i][@]} when ref is a name reference to arr[i] has been fixed. 12-03-21 A bug in which assigning a compound variable into arr[i], where arr[i] is an array variable did not work correctly has been fixed. 12-03-21 A bug with multidimensional indexed arrays in which ${arr[i][j]} could generate a bogus error message when i was > 9 has been fixed. 12-03-21 A bug in which typeset v=foo, typeset -p v[0] generated a core dump has been fixed. 12-03-20 A bug in vi edit mode in which the sequence bar0il left the cursor on the b rather than the a has been fixed. 12-03-20 A bug which caused a core dump when defining a type with a field as ' integer -a data=([0]=0)' has been fixed. 12-03-19 Using typeset -a array when array is an associative array not generated an error message. 12-03-19 typeset +a, typeset +A, and typeset +C not displays the variables with the attributes a, A, and C respectively instead of an error. 12-03-19 A bug in which typeset -pC, typeset -pa, and typeset -pA output all variables rather than those of type C, a, or A only has been fixed. 12-03-18 A bug in which unset foo where foo is a name reference to a compound variable defined inside a function is not unset has been fixed. 12-03-18 A bug with SHOPT_EDPREDICT which could cause a core dump when the list of matches became empty has been fixed. 12-03-15 The assignment, typeset -C foo=(a b c) now generates a syntax error since a is not an assignment command. 12-03-16 A bug in which an unset discipline from a variable defined in a subshell is not invoked in the subshell has been fixed. 12-03-08 The assignment typeset -a (x=1 y=2) now creates an indexed array of two elements rather than an array of one element which is a compound variable. 12-03-02 +The vi and emacs edit modes now list all the entries in a directory when entering a for completion after a /. 12-03-02 A bug in which a program that exits with value 12 when called from a command substitution in which standard output has been redirected caused the shell to hang has been fixed. 12-03-01 A bug in which the shell could not parse [[ ']' == ~(E)[]] ]] has been fixed. 12-02-29 --- Release ksh93u+ --- 12-02-29 A bug in which ~user expanded first in a subshell prevented it from expanding later in a program has been fixed. 12-02-29 A bug which could lead to a core dump when more than four shared libraries were added with the builtin command has been fixed. 12-02-29 Fixed a few bugs which caused SIGCHLD to be blocked preventing background jobs from being reaped until a foreground job was run. 12-02-27 A bug in which sh -c for a simple command caused a fork() has been fixed. 12-02-27 A timing bug on systems such as AIX that doesn't support vfork() that could cause the exist status to get lost has been fixed. 12-02-22 A private file descriptor that was not close-on-exec for a command substitution and has been fixed. 12-02-14 A bug in which ^Z did not stop a pipeline when the last component was a shell built-in has been fixed. 12-02-14 getconf("PATH") used to initialize ed(1) path. 12-02-13 +In earlier version read from standard input would fail when called from the KEYBD trap. Now read options -N, -n, and -t should work when called from a KEYBD trap. 12-02-13 If FCEDIT is not set and fc is invoked without the -e option, ed will be invoked if found instead of /bin/ed. 12-02-10 Another bug in the saving and restoring of IFS in a subshell that caused a core dump has been fixed. 12-02-08 A bug in which .sh.fun disciplines could be cleared after a function completes has been fixed. 12-02-08 A bug in job control in which the foreground process group was not set correctly after restarting a stopped pipeline has been fixed. 12-02-07 A bug in which numbers with leading zeros could be treated as octal constants outside of ((...)) has been fixed. 12-02-06 A bug in arithmetic with compound variables containing multiple array elements has been fixed. 12-02-02 A bug in the ulimit option table was fixed. 12-01-26 A bug in which a set command that did not change monitor could affect the behavior of the monitor when monitor mode is on is fixed. 12-01-21 +You can now test whether the shell implements a math function using typeset -f .sh.math.name, where name is the name of the function. 12-01-21 A bug in which typeset -L and typeset -R did not handle multibyte characters correctly has been fixed. 12-01-20 A bug that could cause the shell to hang waiting for an incorrect job pid has been fixed. 12-01-19 A memory leak which occurred for a nested command substitution has been fixed. 12-01-17 A bug in which typeset -u PS1 could enable the uppercase attribute for some other variables, for example, HISTFILE has been fixed. 12-01-16 A bug in which .sh.match was not correct after a substring match when the replacement string contained a substring match has been fixed. 12-01-12 +Files that are sourced from profile files are now read and executed one command at a time so that alias definitions take effect as they do for profile files. 12-01-12 A bug in which whence -p would find a function if one existed and there was no command of that name on PATH. 12-01-11 Change b_* prototype (int, char**, void*) => (int, char**, Shbltin_t*). 12-01-05 A bug in which read was not terminating for a signal that had a trap set has been fixed. 12-01-01 A timing problem with >; has been fixed. 12-01-01 A macro expansion memory leak has been fixed. 11-12-26 A bug in array assignments of the form arr=( $arr[i] ...) in which arr was not unset before the assignment has been fixed. 11-12-20 A number of code changes were made based on the results of errors indicated by static code analysis. 11-12-13 In vi edit mode a literal can now be entered by preceding it with a backslash. 11-12-13 When tab is entered for completion after a ' or ", the ' and " characters are no longer deleted. 11-12-07 A bug in which a program in the current directory with a . in the name could fail to execute when both PATH and FPATH end with :. has been fixed. 11-12-07 I fixed a bug in which a variable expansion in a large here-document could be expanded to a null string. 11-12-06 An optimization to read was added in the case the read command was redirected from a file. 11-12-06 Changes were made to make the line limit for read unlimited by default. 11-12-05 A bug in which unsetting an array variable did not completely clear the variable in some cases has been fixed. 11-12-02 +The printf alternative character # when applied to the %q format will quote argument in a form suitable for a field in a .csv format file. 11-12-02 +A -S option was added to read to be able to read .csv format files. 11-11-28 A bug in which redirection of standard error in a function called from command substitution caused standard error to be lost has been fixed. 11-11-21 [[ (-n foo) ]] no longer requires a space before (. 11-11-11 The readonly attribute for a variable now applies to compound assignments to that variable. 11-11-07 Changes were made to reduce the stack size to allow deeper function recursion. 11-10-10 +Added alternate flag to printf %H for encoding of URI's. 11-10-10 A bug which could lead to a core dump when the shell was invoked with more than twenty-five open files has been fixed. 11-10-06 A bug in the scoping of name references in functions called by other functions has been fixed. 11-10-05 A bug in which wait on a pid may return the exit status of an earlier background job with that pid instead has been fixed. 11-09-22 A bug in which a read timed out with TMOUT did not always restore the terminal state has been fixed. 11-09-21 An optimization that allowed the last command in a script to use the same process id as the script has been eliminated. 11-09-21 Added letoctal option that enables the let command to recognize octal constants starting with 0. 11-09-20 A bug in which ${var.} could cause a core dump has been fixed. 11-09-20 A bug with SHOPT_EDPREDICT when neither vi nor emacs was enabled for lines beginning with # when in a multibyte locale has been fixed. 11-09-20 A bug in emacs edit mode with SHOPT_EDPREDICT that would cause history searches matching comments lines to generate predictions has been fixed. Only user typed comment lines generate predictions. 11-09-20 A bug in emacs edit mode with a search that matches a comment line that could cause a core dump has been fixed. 11-09-16 A bug in which a command name ending in .. could cause the shell to abort has been fixed. 11-09-16 The characters ! + - % and @ in file names are no longer escaped with file name completion. 11-09-13 The let command no longer treats numbers starting with 0 as octal constants. 11-09-08 A bug in which printf "%R" could cause a core dump for invalid shell patterns has been fixed. 11-08-09 With set -u, ${var#pattern} reported that var was unset for special variables. 11-08-03 A bug in which the shell did not preserve the exit status for a coprocess has been fixed. 11-08-02 A bug in the saving and restoring of IFS in command substitution that caused a core dump has been fixed. 11-07-21 Modified the 10-08-27 bug fix so that background jobs started in for and while loops created interactively generate completion messages. 11-07-20 I fixed a bug in here documents in which multi-byte characters that crossed buffer boundaries were not processed correctly. 11-06-22 The shell compiler now supports process substitution. 11-06-22 +Added code to support process substitution on systems that do not supply the /dev/fd directory. 11-06-21 Fixed extraneous jobs Done messages when builtin is at the end of a pipeline. 11-06-20 Fixed two regression tests. 11-06-20 Fixed a bug introduced on last update. 11-06-14 A bug with pipefail in which the shell would wait for background jobs to complete has been fixed. 11-06-09 A bug which caused the options.sh regression test to fail on OS390 Linux has been fixed. The bug could also have affected other systems. 11-06-07 +A number of changes to support the still undocumented namespace option have been added. 11-06-06 A bug in which command substitution of eval would hang when it had standard error redirected to standard output has been fixed. 11-06-01 A bug in case statement fall through (;&) ignoring set -e was fixed. 11-06-01 A bug in which creating a left or right justified upper or lowercase variable with an empty string has been fixed. 11-06-01 A bug in which the .paths directory wasn't read when a subshell was executed before any other command has been fixed. 11-05-31 The shell now gives an error when a type variable is assigned to an array instance when the array has been declared a compound variable array. 11-05-31 A bug in which typeset -m of an array instance did not remove the original instance has been fixed. 11-05-28 A bug in which typeset -m dest=src fails when src and are passed as name references was fixed. 11-05-28 A bug in which typeset -m "c.board[1][i]=el", where el is a compound variable core dumps has been fixed. 11-05-28 Two bugs in the display of arrays of compound variables with print -v have been fixed. 11-05-27 A bug with command substitution in the Shift JIS locale has been fixed. 11-05-25 A bug in which unset -f foo, called within function foo could cause the shell to core dump has been fixed. 11-05-24 A bug in unsetting arrays of compound variables that could lead to a core dump has been fixed. 11-05-24 A scoping bug in with typeset -m for variables passed as references has been fixed. 11-05-09 A bug in which 'typeset +p array[$i]' in a subshell could cause an exception has been fixed. 11-05-03 Two more scoping bugs with name references and read -C were fixed. 11-05-03 A potential race condition which occurs when here-documents are processed in asynchronous blocks has been eliminated. 11-05-02 Another scoping bug with name references defined in a function has been fixed. 11-05-02 A bug in which the shell discards saved exit status of a job if it is followed by a subshell execution has been fixed. 11-04-28 The shell now checks for numerical overflows with process ids. 11-04-28 Another scoping bug with compound variables defined by name references inside a function has been fixed. 11-04-28 A bug which caused a core dump on 32 bit systems with the basic.sh regression test has been fixed. 11-04-27 A scope binding error for name references has been fixed. 11-04-27 Assignment of compound variable to compound array element by name is now working. 11-04-26 I fixed a bug with SHOPT_FIXEDARRAY compilation that could cause an a core dump for not fixed arrays. 11-04-25 A bug in the references to two dimensional compound arrays has been fixed. 11-04-20 A bug in which a name reference to a multidimensional indexed array index, nameref x=foo[3][4], did not work correctly has been fixed. 11-04-18 Changes were added to allow fixed size arrays of variable sized objects when the SHOPT_FIXEDARRAY compile option defined on 10-09-28. 11-04-18 A bug in which name references to array elements could fail has been fixed. 11-04-15 +A compile option, SHOPT_2DMATCH, has been added which causes .sh.match to be a two dimensional array after ${var//pat/str} where the first dimension is the pattern number and the second is the match instance. 11-04-11 A bug in which readonly var, where var is exported could cause var to be unset has been fixed. 11-04-06 A tokenizer bug in which ${x/{3}(\d)/ } would cause an infinite loop has been fixed. 11-04-05 A bug in which ${!x.} could cause a core dump has been fixed. 11-04-04 A bug in which cleaning out the history file could terminate before keeping all the recent history events has been fixed. 11-03-29 A bug in which ${#array[@]} was 1 rather than 0 after issuing typeset array[7] has been fixed. 11-03-29 The subscript out or range message for fixed arrays has been fixed. 11-03-29 A bug in which suspend could cause a core dump has been fixed. 11-03-24 For the showme option added 09-09-09, commands beginning with a ; inside an arithmetic for loop, no longer produce syntax errors. 11-03-18 A bug in _WINIX ~domain/user expansion has been fixed. 11-03-16 A bug in the pipefail option which could cause a script to hang has been fixed. 11-03-12 The shell no longer treats ${##pattern} as a syntax error. 11-03-11 A bug in typeset -u on systems that don't supply the towctrans() function has been fixed. 11-03-11 A bug in which a compound assignment of the form var[sub]=(...) would evaluate sub for each assignment has been fixed. 11-03-07 A bug in which reassigning a compound variable to an associative array index could incorrectly increase the count of the number of elements has been fixed. 11-03-04 +The tilde expansion on Windows has been modified to handle user names of the form domain/user so that ~domain/user now expands to the home directory of that domain user. 11-03-03 A bug in which the width of the prompt was calculated incorrectly which cause the wrong line length for edit commands has been fixed. 11-03-02 A bug in which a global variables set from within a function inside a subshell can leave side effects in parent shell has been fixed. 11-03-01 A bug in which whence -a could dump core when the first match was due to : in PATH and the program was in the current directory. 11-02-28 A bug in emacs mode with SHOPT_EDPREDICT (added on 10-05-20) which disabled prediction on a line starting with # when the cursor was not at the end of line has been fixed. 11-02-28 The output format for compound variables with set has been fixed. 11-02-25 A bug which could lead to a core dump occurred when a shell script without #! is invoked by name from a parent shell that has name references defined and the script creates name references of the same name. 11-02-21 The shell now fails with a syntax error when a here-document in a command substitution is not completed before the closing ), for example, $( foobar <&- doesn't work has been fixed. 11-02-07 A bug on some systems for which a command substitution could hang has been fixed. 11-01-28 A bug in file name completion for files containing both multibyte characters shell special characters has been fixed. 11-01-18 The .sh.match variable now shows elements that do not match as as not set rather than an empty string. 11-01-18 A bug with typeset -m of an array into an element of an indexed array has been fixed. 11-01-13 A bug in handling of arrays of compound variables inside ((...)) which reported a syntax error been fixed. 11-01-10 A bug in arithmetic assignment operators of the form op= for array variables when the same array was referenced on the left and the right hand side with different indices has been fixed. 11-01-10 A bug in which the output of time was lost when { time...;} 2>&1 occurred inside command substitution has been fixed. 11-01-07 [[ -v sh.match[i] ]] was returning false when sh.match[i] was set. 11-01-05 Added and modified warning messages with sh -n. 11-01-02 Fixed bugs with typeset -l/-u/-M and arrays. 10-12-28 Fixed a bug with typeset -l/-u/-M values in arithmetic expressions. 10-12-26 Fixed a time parsing bug in sleep and localeconv() initialization. 10-12-23 Prevented the shell from generating a core dump when it sends itself a termination signal because the last command terminated with that signal. This prevents a core dump to be overwritten by the shell. 10-12-22 A bug in the expansion of ${A[@]} ${B[@]}, introduced in 10-12-01 when A="" B=B has been fixed. 10-12-21 +Use MS_3D in b_vpath() for setting Win32 WoW mount defaults. 10-12-17 A bug in the expansion of ${var:i:j} which caused a core dump when i > ${#var} has been fixed. 10-12-16 +sleep now treats . as decimal point even in locales that use comma. 10-12-16 +typeset -M mapname was added to generalize on toupper and tolowwer mapping as provided with wctrans(). 10-12-10 A bug in which typeset -l displayed namespaces as well as lower case variables has been fixed. 10-12-06 A bug in which a pipeline could terminate prematurely for a pipeline whose right hand side is a builtin, and whose left hand side ends in a simple command that has standard output redirected has been fixed. 10-12-06 A bug in hexfloat assignments when the right hand side is a string variable starting with 0x has been fixed. 10-12-01 A bug in the expansion of ${$1+"$@"} which causes the last positional parameter to disappear when it is empty has been fixed. 10-12-01 A number of changes were made to reduce the startup time. 10-11-29 When wait is interrupted by a signal that is caught, it now exits with a non-zero exit status. 10-11-29 When a variable is used directly in an arithmetic expression, leading zeros no longer cause the value to be treated as an octal constant. This was true in previous versions for justified variables. 10-11-29 An incorrect warning message was eliminated with the -n option for arithmetic expressions with associative arrays. 10-11-29 Some changes were made to slightly reduce startup time. 10-11-24 A bug in which a name reference is make to arr[0] when arr is not an array has been fixed. 10-11-23 If a type definition is made without a compound variable assignment it produces an error message and no longer shows up as a defined type. 10-11-22 The handling of \ inside [...] for shell and ~(E) patterns has been fixed. 10-11-22 A patch was made to pfsh to handle an error case. 10-11-22 +Modified types defined in namespace so that they do not clash with types in other namespaces. Types can be referenced using .namespace.typename. 10-11-22 A bug which caused functions addressed as .namespace.funct to not work has been fixed. 10-11-22 A bug in which if nr was a name reference to an unset associative array subscript, then ${!nr} did not output the subscript correctly has been fixed. 10-11-18 A bug in which shcomp -n was not processing double quotes correctly has been fixed. 10-11-18 Fixed a bug in which typeset -T foo; typeset -T could cause a core dump. 10-11-17 Fixed a bug in which the error message for set -u could come out garbled. 10-11-17 Modified the parser so that typeset -a var=(...) no longer checks the first index for aliases and reserved words. 10-11-17 A bug in which a subshell command consisted of only a for or until command has been fixed. 10-11-16 Fixed a bug in which typeset -u would display namespace variables as well as upper case variables. 10-11-16 A bug which could cause a core dump when unsetting a type variable when there are references to type elements has been fixed. 10-11-15 A bug which could cause a core dump when unsetting a compound array variable when there are references to array subscripts has been fixed. 10-11-15 A bug in which using typeset -m to move an indexed array instance to another array could cause the array to display incorrectly has been fixed. 10-11-12 A bug in which the unset discipline function for a type is called when the type is initialized has been fixed. 10-11-12 The sequences \< and \> are now preserved after patterns containing ~(E) in ${var/pattern/string} expansions. 10-11-11 A bug in typeset -m when the variables were compound array instances has been fixed. 10-11-10 A bug in output of a compound variable with types containing types has been fixed. 10-11-10 Fixed ``name=value export [-p]'' to list environment. 10-11-09 shtests resets SIGPIPE to SIG_DFL for all tests. 10-11-09 Fixed a bug in expansion of $"..." when used in assignments. 10-11-09 Fixed a getaddrinfo() memory leak that didn't call freeaddrinfo() after an interrupt. 10-11-08 Modified the behavior of set -u so that the shell terminates with error message when when var is unset with ${!var} and ${#var}. 10-11-02 Fix a bug in which a signal received while in a subshell could be ignored. 10-10-26 Fix a bug where terminal interrupt was ignored while in vi/emacs edit search mode. 10-10-26 Fix $'a\0b'c to expand to 'ac'. 10-10-26 Provide user defined round() if not in . 10-10-26 Fix bug where $((undefined_function(1))) dumped core. 10-10-22 Provide user defined iszero() if not in . 10-10-22 Fixed a bug with BGX compile option that could cause the shell to hang. 10-10-22 Fixed a bug with user define math function on systems for which char is unsigned. 10-10-21 A bug in which function autoloaded in a function leaves a file open has been fixed. 10-10-20 Modified the behavior of set -u so that the shell terminates when when var is unset with ${var op string} when op is #, % or /. 10-10-20 Fixed a bug with the AUDIT option in which the audit file was not not close-on-exec. 10-10-20 +Made a number of changes and fixes for the NAMESPACE compile option which as added on 10-06-09 but some problems still remain. 10-10-15 Fixed a bug in which arithmetic functions (added on 10-03-24) did not work when the function definition was in the same compound command in which the function was referenced. 10-10-13 A bug in which creating an associative array of compound variables with no members as an element of a compound variable did not work has been fixed. 10-10-08 A bug in which killing the last command in a function defined with function name, terminated the calling script has been fixed. 10-10-08 A bug which could cause a core dump if IFS is unset inside a function has been fixed. 10-10-07 +To reduce unwanted side effects, invoking typeset without the export option and without an assignment now causes the variables to be unset if the variable is inherited from the environment. 10-10-06 The closing brace for ${ command } is now a token no matter what character follows it. 10-10-04 The change for $'...' expansion on 10-08-09 did not expand parameters contained in the error message and this has been fixed. 10-10-04 A bug in which a declaration of indexed array (-a) in a type definition would be displayed as a compound indexed array (-C -a) has been fixed. 10-09-30 The C99 math function ldexp has been added. 10-09-30 A bug with two dimensional arrays with expansion of the form ${ref[0..5]} where ref is a nameref to array[i] has been fixed. 10-09-29 A bug in which an eval with redirections invoked from a dot script would not restore the file has been fixed. 10-09-29 A bug in which loading a function from FPATH could leave a file descriptor open has been fixed. 10-09-28 +A new compile option SHOPT_FIXEDARRAY has been added and is being evaluated. It allows fixed sized indexed arrays be to defined using "typeset array[dim1][dim2]...[dimn]". Fixed sized arrays are used the same way indexed arrays are. Currently, only fixed arrays of fixed objects (float, int, and justified objects) are supported. 10-09-22 A bug which could cause an exception when a function with static variables was redefined has been fixed. 10-09-21 A bug in the processing of (command&) which created a job in the parent process has been fixed. 10-09-21 A for loop optimization bug with arithmetic expression evaluation has been fixed. 10-09-21 A bug in which a recursive function containing a pipeline could lead to an exception fixed after 8 levels of recursion has been fixed. 10-09-18 A bug in which the count of elements in an array was wrong leading to an exception has been fixed. 10-09-13 A bug which occurred when both xtrace and showme options where specified in which the xtrace option disabled showme has been fixed. 10-09-13 A bug in which creating a reference to an array variable with any elements could cause subsequent array elements to be treated as compound variables has been fixed. 10-09-09 A bug which caused ((c.ar[x][y])) to be treated as a syntax error has been fixed. 10-09-08 A bug in the processing of references to multidimensional arrays in arithmetic expressions has been fixed. 10-09-08 A bug in the handling of multidimensional arrays which caused the number of elements in each dimension to be incorrect has been fixed. 10-09-07 The change for messages on 10-08-09 did not handle message in assignments and this has been fixed. 10-09-07 A bug in the indentation of compound variables in arrays when output with print -v has been fixed. 10-09-07 A rare bug with indexed arrays when assigned a null string that could cause a core dump has been fixed. 10-09-03 A number of changes were made for jobs pools. 10-08-31 typeset -p was modified to output name references after other variables so that the output could be used as input. 10-08-31 A bug with typeset -p in which variables with attributes but without attributes were not displayed correctly has been fixed. 10-08-27 +When running a subshell, the current pool is unset. 10-08-27 A bug in which jobs started from within for or while lists in interactive shells could generate completion messages has been fixed. 10-08-25 Fixed a couple of bugs related to job pools. 10-08-24 +[[ -e /dev/xxx/ ]] can be used to check whether special files of those names are handled by the shell. 10-08-24 A bug in the running of a compiled dot script in which only the first command was executed has been fixed. 10-08-23 A bug which sometimes caused a core dump with a configure script has been fixed. 10-08-20 A bug in command substitution which caused a configure script to hang has been fixed. 10-08-19 Eliminated unnecessary ; from output of compound variable with typeset -p. 10-08-17 Fixed a bug in command substitution in which under certain circumstances a file whose size is a power of 2 plus one, and the last character was not a new-line, could cause memory corruption. 10-08-13 +Added static discipline functions to type similar to C++ static class functions. 10-08-11 A bug in time when applied to a pipeline in which the shell did not wait for all elements of the pipeline to complete has been fixed. 10-08-11 Restored sh_fmtq() quoting to not quote NAME= in NAME=VALUE. 10-08-09 +Modified the expansion of message strings, $"...", so that they are expanded each time they are referenced rather than expanding them when the script is compiled or read in. 10-08-06 +The process id for jobs in job pools is now of the form poolname.n where n is the jobid in that pool. Commands that accept job names or numbers now understand names in this format. 10-08-05 A bug in which an assignment from within an arithmetic expression inside a function would create a local variable has been fixed. 10-08-04 A bug in the expanding of variables whose names contain multibyte characters has been fixed. 10-08-04 A bug which caused an exception when processing scripts compiled with shcomp -n has been fixed. 10-08-02 Tests using very small buffer sizes uncovered a number of bug most connected with here documents which have been fixed. 10-07-27 The format modifier , used for digit grouping with d and f formats has been documented. 10-07-26 cd '' now produces and error rather than changing to the current directory. 10-07-26 A bug in multi-byte locales which the last character of a multi-byte character is a \ or pattern character which could occur when the character was the last character of a command substitution has been fixed. 10-07-23 Another bug in the processing of ${var:offset;len} in multi-byte locales when len is larger than the number of characters has been fixed. 10-07-23 Many coding changes have been made to eliminate most of the uses of global variables in the shell code. 10-07-22 Fixed a bug in which discipline functions were not being invoked when it was invoked as ref.discipline where ref was a name reference to an array instance. 10-07-22 Fixed a bug in which discipline functions were not being invoked it was invoked on a two dimensional array, i.e., arr[5][9].discipline. 10-07-19 Fixed a buffering problem which occurred when running a script with ssh and the parent ssh process is killed. 10-07-14 Modified the parser to treat ((...)) inside [[ ... ]] as ( (...) ) so that it is a nested (...). 10-07-09 A bug in the handling of process substitution inside command substitution as part of a pipeline has been fixed. 10-07-07 A bug in the output for compound variables containing multidimensional arrays has been fixed. 10-07-06 ksh now recovers from changes made by bash to the history file without losing history commands. 10-06-25 A bug in which a large here document containing command substitutions of a dynamically loaded function that contained a here document could get truncated has been fixed. 10-06-24 If after executing a script found in FPATH, if a function, builtin, or type name corresponding to that script is not defined, the shell now outputs an error message and returns value 126. 10-06-23 Floating point functions that happened to return integer values were being treated as if the function returned integers so that integer division could be used instead of floating point division. 10-06-22 Fixed a bug in earlier ksh93u in which an arithmetic assignment to a variable in the global scope would instead create a local variable if the variable had an attribute but did not have a value. 10-06-18 Modified trap handling so that if the same signal is received when executing the handler, it is deferred until the handler completes. 10-06-16 Fixed a bug in which ulimit -v was setting the CPU limit on Linux. 10-06-14 +The command 'typeset -T' now generates the list of type definitions in a format that can be used as input to the shell. 10-06-09 Put in patch from Solaris for output quoting with %q. 10-06-09 +Made changes to the NAMESPACE compile option so that it now seems to work. With this option, namespace { command;} will run command in the namespace .name so that all variables and functions created by command are accessible outside the name space via .name.var and .name.fun. Variables and functions that are not in the namespace are not modified when running command. 10-06-07 Change most internal interfaces to take Sh_t* argument. 10-06-03 +Types can be loaded on first reference by putting definitions in PFPATH. 10-06-03 +The shell is now able to parse commands which use type statements before the typeset -T command to define the type executes. 10-06-03 A bug in the quoting for name reference declarations which did not properly handle [ and ] in subscripts for associative arrays. 10-06-02 A bug in which a discipline function defined by a type instance to override the default was not being registered has been fixed. 10-06-02 A bug in which read -C of an associative array of compound variables was not working has been fixed. 10-06-02 A bug in which the error message for an unset parameter with set -u did not contain the name of the variable has been fixed. 10-06-01 A bug in typeset -m for moving an indexed array instance to a variable has been fixed. 10-06-01 A bug in which caused memory to be freed twice when unset was called for an indexed array that had get or set disciplines has been fixed. 10-06-01 A bug in which the %b format of printf was not preserving NUL bytes with \0 has been fixed. 10-06-01 A bug in the handling of name references to array variables in arithmetic expressions has been fixed. 10-05-28 Fixed bugs in changing attributes for two dimensional arrays. 10-05-28 Eliminated a few unreferenced variables and a reference to uninitialized memory. 10-05-27 Rewrote the subshell code to avoid using pipes an many cases. 10-05-24 Fixed a bug which cause an exception when both -l and -s were specified with typeset -i. 10-05-21 Inputting of three dimensional indexed arrays with ( ( (...)...)...) was not working and has been fixed. 10-05-21 A bug in which adding the attributes -Ai to a variable via a name reference could cause the value to display incorrectly has been fixed. 10-05-21 A bug in which using $var inside ((...)) did not work when var was a hex float variable. 10-05-20 +The compile option SHOPT_EDPREDICT has been added. When this option is on, as you type a line beginning with a # the following characters are treated as a shell pattern and cause matching lines from the history file to be displayed as a numbered list as you type. You can scroll up and down this list or you can use nTAB to make this the current line (n defaults to 1 of omitted) or n to execute. 10-05-20 A bug which caused an exception when multiple levels of composite functions in arithmetic expressions has been fixed. 10-05-19 <<< with an empty string no longer gives an error. 10-05-19 A bug in arithmetic evaluation when a name reference to an array instance was used has been fixed. 10-05-14 A bug in which the shell treats a valid indexed array assignment, typeset -a x=(foo (x=3;y=4) bar) as a syntax error has been fixed. 10-05-13 A bug in creating name references to associative array variable after a lookup of one of its elements has been fixed. 10-05-12 Two bugs in the handling of function static type variables in subshells have been fixed. One could cause an exception and the other would leave side effects in the parent shell. 10-05-10 A bug in which static variables in functions were not being saved and restored properly when running subshells has been fixed. 10-05-05 A bug in which print -v did not work correctly when an operand was an indexed array element referring to a compound variable has been fixed. 10-05-05 A change to improve performance by special casing empty string assignments to avoid repeated malloc() and free(). 10-05-05 A bug in which creating a name reference to a non-existent associative array element would create the array element has been fixed. 10-05-04 A bug in which name references to static variables in the static scope were not found has been fixed. 10-04-30 Do not use socketpair() on systems that implement ioctl(I_PEEK) on pipes. 10-04-29 +When the current job pool is set, coprocess are run in a job pool. 10-04-28 A type defined with a member foo that is an associative array without elements followed by an expansion ${bar.foo[a]} and an assignment bar.foo[a]=b, no longer indicates that ${#bar.foo[@]} has 0 members. 10-04-27 Another bug in which a nested command substitution could hang if it generated too much data has been fixed. 10-04-26 A type defined with a member that is an indexed array without elements would behave as if the 0th element of each instance was defined after a non-zero element was specified and this has been fixed. 10-04-26 A bug in which types defined in a subshell were not undefined when the subshell completed has been fixed. 10-04-23 For file completion in command line editing, file names starting with # are now escaped so that they are not treated as comments. 10-04-23 A bug in which ${t.var:=value}, where t is an instance of a type variable, could assign value to the type variable rather than to the type instance has been fixed. 10-04-23 +Added &| which can be used in place of | to have portions of a pipeline executed in the pool. 10-04-22 +The .sh.pool variable was added for use with job pools. 10-04-22 A bug in which a nested command substitution could hang if it generated too much data has been fixed. 10-04-20 A bug which corrupted one byte of memory when read was called with reads that did not use a delimiter has been fixed. 10-04-19 The display of a compound variable with an embedded array with attributes was sometimes not working correctly and has been fixed. 10-04-16 A bug in which attributes were not be propagated to elements in an associative array has been fixed. 10-04-15 A bug which caused scripts containing user defined math functions to fail to compile with shcomp has been fixed. 10-04-15 +Job pools have been added with the SHOPT_COSHELL compilation option. A job pool allows a collection of background jobs to run either locally or remotely and to be managed as a unit. The command '& name ...' creates or uses a named job pool for subsequent background jobs. kill, wait, and jobs allow the pool name as operands. 10-04-14 A bug in which a coprocess connection could terminate prematurely when running a nested subshell has been fixed. 10-04-12 +Enumeration constants can be used in arithmetic expressions with the ==, != and = operators when the left hand side is an enum variable and the right hand side is an enumeration constant. 10-04-07 A bug in which setting the trap on CHLD to ignore could cause an incorrect exit status has been fixed. 10-04-06 A bug in which LINENO was not incremented for a here-document when the here-document word was followed by a comment has been fixed. 10-04-06 The optimization that execs the last process of a script rather than creating a new process has been removed when a trap on interrupt has been set. 10-04-06 Unsetting the 'C', 'A' or 'a' typeset attribute now produces an error message rather than generating an exception. 10-04-06 A bug in which .sh.name contained the subscript and .sh.subscript was empty in some cases with discipline functions on array instances has been fixed. 10-04-05 A bug in the edit modes where preceding the interrupt character with the literal next character did not work has been fixed. 10-04-05 A bug in the creation of type instances of arrays which could cause an exception has been fixed. 10-03-30 A bug in the display of a compound variable containing an indexed array of compound variables has been fixed. 10-03-24 +Arithmetic functions can be defined using the shell function syntax, 'function .sh.math.name x y z{...}' , where name is the function name invoked within ((...)) and x y z are long double arguments passed as name references. y and z are used for functions with two and three arguments respectively. The value of the function is the value of the long double .sh.value variable when the function returns. 10-03-24 A bug in which integer division was mistakenly used when the numerator was a binary operator with the first operand floating point and the second integer, e.g. (.1**3)/3, has been fixed. 10-03-24 The >; file operator was modified so that the temporary file is created in the same physical directory as file. 10-03-23 A warning message was added to sh -n when $var was used inside ((...)) instead of var. 10-03-19 fmin was added to the list of math function on the man page. 10-03-19 Fixed the return value for unalias when the alias did not exist. 10-03-19 A bug in which the SHLVL variable exported the value it had on input rather than the incremented value has been fixed. 10-03-19 A bug which causes whence -q to go into an infinite loop has been fixed. 10-03-19 Removed space between Stopped message and (SIGTTIN) and (SIGTTOUT). 10-03-17 Modified profile shell execution so that when builtins that correspond to executable have extended attributes, they are executed by pfksh instead of being treated as built-ins. 10-03-16 A bug in whence -a which produced duplicate lines of output has been fixed. 10-03-16 A bug in the handling of process groups in monitor mode for command substitutions has been fixed. 10-03-15 Fixed a bug in which read -u[fd] could cause the shell to core dump when fd was greater than open_max. 10-03-15 +Modified the shell I/O so that the shell will not fail if the ulimit for open_max is increased as part of the script. 10-03-12 A bug in which a here-document containing command substitutions that contained here-documents did not process correctly has been fixed. 10-03-12 A bug in which the terminal is not restored to canonical mode after read times out when in a multibyte locale with no edit mode enabled has been fixed. 10-03-05 --- Release ksh93t+ --- 10-03-05 A variable unset memory leak has been fixed and tests/leaks.sh has been added to verify the fix. 10-03-04 Documentation, comment, and diagnostic spelling typos corrected. 10-02-14 Fix sh_getenv() initialization to cooperate with the 3d fs. 10-02-12 A bug in which the get discipline function was not invoked for associative array subscripts for unset array elements has been fixed. 10-02-12 A bug which could occur if the last line of a script was an eval that executed multiple commands has been fixed. 10-02-02 A buffer overflow in read and another in binary type base64 encoding were fixed. 10-01-20 A bug in the evaluation of arithmetic expression in which the subscript was evaluated twice for $((foo[x++]++)) has been fixed. 10-01-19 A workaround for a double-free of a trap in both a subshell and its parent has been added. 10-01-18 A bug in type handling of typeset -H has been fixed. 10-01-15 The "adding empty subscript" warning now only emitted with -x set. 10-01-01 A bug in the parser in which '$((case i in i):;esac);:))' was not parsed correctly was fixed. 10-01-01 A bug in the parser in which '$(( 2 , 3.6 ))' dumped core for locales with radix char , and thousands separator . has been fixed. 09-12-28 A bug in the handling of SIGCLD on systems that generated SIGCLD while blocked waiting for process to complete has been fixed. 09-12-24 AST setlocale() reworked to differentiate env var changes from user override. 09-12-18 A bug with the SHOPT_BGX option set which disabled traps for signals < SIGCHLD when a trap for a signal > SIGCHLD was set has been fixed. 09-12-18 A bug where [[ -v var ]] was incorrect for some variables (including LC_* vars) has been fixed. 09-12-15 A bug that produced a syntax error when a multibyte character straddled a buffer boundary has been fixed. 09-12-11 A bug where the subscript of an unset variable was not evaluated has been fixed. 09-12-09 A bug where shcomp dumped core on certain syntax errors has been fixed. 09-12-07 A bug where a parent shell environment var reset in a subshell removed the value in subsequent children of the parent shell has been fixed. 09-12-04 A bug in which in some cases a trap in a function executed in a subshell could trigger twice has been fixed. 09-12-03 A bug in which SHLVL exported with some attributes could cause the shell to abort at startup has been fixed. 09-12-02 A bug with pipefail in which the shell could hang waiting for the writer to complete before the last reader command has been fixed. 09-11-30 A bug in which a trap could be inherited by the first element of a pipeline when the command had more than 63 arguments that did not contain any macro expansions has been fixed. 09-11-19 When read from a terminal was called from with a while or for loop, and an edit mode was on, a backspace or erase no longer will overwrite the prompt. 09-11-17 +Change .paths parse to handle BUILTIN_LIB=foo BUILTIN_LIB=foo-1.2. 09-11-17 Inside a function, typeset foo.bar will bind foo to global variable foo if local variable foo does not exist, instead of creating a local variable. 09-11-17 "read -n1" from the terminal has been fixed to read exactly one character. 09-11-11 Job control now works for subshell commands, (...). 09-11-11 If set -e is on for an interactive shell errors in special builtins now cause the shell to exit. 09-11-11 A bug in which an interrupt handler processed during the read builtin when IFS did not contain a new line has been fixed. 09-11-09 A bug in which a variable that has been unset in a subshell and then exported from that subshell does not show up in the environment has been fixed. 09-11-02 ``,2'' is now a valid numeric constant for locales with decimal_point=','. 09-11-02 A bug where "return" in .profile did not restore the shell state has been fixed. 09-10-31 A bug that corrupted saved exit status when pids wrapped around has been fixed. 09-10-26 A bug in { LANG LC_ALL LC_category } ordering has been fixed in -last. 09-10-16 A bug where notification to libast that the environment has changed has been fixed. 09-10-12 A bug in which a function loaded in a subshell could leave side effects in the parent shell has been fixed. 09-10-12 A bug in converting a printf %d operand to a number when the operand contains multiple subscripts for the same variable has been fixed. 09-10-09 A bug in the handling of the escape character \ in directory prefixes in command completion has been fixed. 09-10-09 $PATH processing has been changed to delay dir stat() and .paths lookup until the directory is needed in the path search. 09-09-28 Call the AST setlocale() intercept on unset too. 09-09-24 A bug in which LANG=foo; LC_ALL=foo; unset LC_ALL; did not revert LC_CTYPE etc. to the LANG value has been fixed. 09-09-17 A bug in which unsetting SVLVL could cause a script invoked by name without #! to core dump has been fixed. 09-09-16 A bug in which a pipeline in a here-document could hang when the pipefail option was on has been fixed. 09-09-09 A bug in the processing of line joining in here documents which occurred when a buffer began with has been fixed. 09-09-09 +A leading ; with commands in a brace group or parenthesis group no longer causes an error. It now is used for the "showme" option. 09-09-09 A bug in which a subshell containing a background process could block until the background process completed has been fixed. 09-09-04 A bug in handling ${var[sub]}, where var is a nameref has been fixed. 09-09-03 A bug which caused an indexed array to have the wrong number of elements when it was converted from a compound variable by adding an another element has been fixed. 09-09-03 Specifying export for a compound variable now generates an error. 09-09-02 $"..." localizations strings are no longer recognized inside `...`. 09-09-01 A bug in the for loop optimizer in the handling of type static variables has been fixed. 09-09-01 An error message is not displayed when * and @ are used as subscripts. 09-09-01 Several bugs in the processing for types that included an associative array of another type has been fixed. 09-09-01 A bug in the tracing of [[ a < b ]] and [[ a > b ]] has been fixed. 09-08-26 The .sh.file variable was not being set for a script that was run by name and didn't start with #! and this has been fixed. 09-08-25 A bug in which a function called to deeply from command substitution did not display an error message has been fixed. 09-08-24 +When processing profiles, ksh93 now violates the POSIX standard and treats &> as a redirection operator similar to bash. 09-08-23 A bug in the handling of the trap on SIGPIPE that could lead to a memory fault has been fixed. 09-08-21 A bug in the handling of the comma operator in arithmetic expressions that could cause a core dump on some systems has been fixed. 09-08-20 A bug in which a compound variable containing an array of a type that doesn't have any elements now expands correctly. 09-08-19 A bug which disabled function tracing inside a function after a call to another function has been fixed. 09-08-19 A bug in which initializing a compound variable instance to another compound variable by name has been fixed. 09-08-18 A bug in which compound variable instances could be lost after an instance that invoked a type method discipline has been fixed. 09-08-18 A bug in which a discipline function for a type applied to an array instance when invoked in a function ignored the subscript has been fixed. 09-08-18 A scoping error with variables in arithmetic expression with type variables when reference with a name reference has been fixed. 09-08-10 Several memory leaks were fixed primarily related to subshells. 09-08-06 A bug in which setting the trap on CHLD to ignore could cause a script to hang has been fixed. 09-07-08 A bug in the processing of name reference assignments when it contained pattern expansions with quoting has been fixed. 09-06-22 +The default width for typeset -X has been changed so that there should be no loss of precision when converting to a string. 09-06-19 A bug in the printing of array elements for binary variables with printf %B has been fixed. 09-06-19 A bug which caused a core dump with trap DEBUG set with an array assignment with no elements has been fixed. 09-06-19 A bug with read with typeset -b -Z has been fixed. 09-06-19 Two bugs related to read -b for array variables has been fixed. 09-06-19 A bug with typeset for compound variables containing arrays of compound variables has been fixed. 09-06-18 A bug in appending a compound variable to an indexed array of compound variables has been fixed. 09-06-18 A bug which occurs when appending a compound variable to an indexed array element has been fixed. 09-06-18 Setting VISUAL to a value other than one ending in vi or emacs will no longer unset the edit mode. 09-06-17 A bug in typeset -m when moving a local compound variable to a global compound variable via a name reference has been fixed. 09-06-17 A bug in appending to nodes of an array of compound variables when addressing them via nameref has been fixed. 09-06-17 A bug in typeset -p var, when var is an array of compound variables in which the output only contained on array element has been fixed. 09-06-17 The prefix expansion ${!y.@} now works when y is a name reference to an element of an array. 09-06-16 Traps on signals that are ignored when the shell is invoked no longer display. Previously they were ignored as required but would be listed with trap -p. 09-06-12 A bug in vi edit mode in which hitting the up arrow key at the end of a line longer than 40 characters which caused a core dump has been fixed. 09-06-11 A bug in which "eval non-builtin &" would create two processes, one for the & and another for non-builtin has been fixed. 09-06-08 When var is an identifier and is unset, ${var} no longer tries to run command substitution on the command var. 09-06-08 +Process substitution arguments of the form <(command) can now be used following the < redirection operator to redirect from command. 09-05-13 A bug in which redirections of the form 2>&1 1>&5 inside command substitution could cause the command substitution to hang has been fixed. 09-05-12 To conform with POSIX, the -u option only checks for unset variables and subscript elements rather than checking for all parameters. 09-05-12 A bug which could cause a core dump when a variable whose name begins with a . was referenced as part of a name reference inside a function has been fixed. 09-05-01 A bug that caused a core dump when SIGWINCH was received and both vi and emacs mode were off has been fixed. 09-04-22 +Default alias compound='typeset -C' added. 09-04-15 A bug that caused ${...;} to hang for large files has been fixed. 09-04-08 A change was made in the -n option which printed out an incorrect warning with <>. 09-04-07 The emacs edit command M-_ and M_. and the vi command _ was fixed to handle the case there there is no history file. 09-04-05 A bug in handling new-lines with read -n has been fixed. 09-04-05 The ENV variable defaults to the file named by $HOME/.kshrc rather then to the string $HOME/.kshrc. 09-03-31 A bug in which a nested command substitution with redirections could leave a file descriptor open has been fixed. 09-03-24 +ksh now only uses the value of the _ variable on startup if it can verify that it was set by the invoking process rather than being inherited by some other ancestor. 09-03-24 +When ksh is invoked without -p and ruid!=euid, and the shell is compiled without SHOPT_P_UID or ruid=SHOPT_P_UID then euid is set to ruid. A bug that did the wrong test (ruid&1 inside a command substitution wasn't working correctly has been fixed. 09-02-02 A bug in the call stack of arithmetic function with 2 args returning int has been fixed. 09-01-30 A bug in which 'eval print \$0' inside a function was giving the wrong value for $0 has been fixed. 09-01-28 A bug in which a command substitution could return an exit status of 127 when the pipefail option is enabled has been fixed. 09-01-26 ksh93 now generates an error message if you attempt to create a global name reference to a local variable. 09-01-26 +The [[ -v var ]] operator was modified to test for array elements. 09-01-23 +The redirection operator <>; was added. It is similar to <> except that if the command it is applied to succeeds, the file is truncated to the offset at the command completion. 09-01-23 The default file descriptor for <> was changed to 1. 09-01-20 A bug in which the exit status specified in an exit trap was not used when a process terminated with a signal has been fixed. 09-01-19 A bug in which a signal whose default action is to terminate a process could be ignored when the process is running a subshell has been fixed. 09-01-19 A bug in which sending SIGWINCH to a process that reads from a pipe could cause a memory fault has been fixed. 09-01-16 +The -R unary operator was added to [[ ... ]] and test to check whether a variable is a name reference. 09-01-16 +The -v unary operator was added to [[ ... ]] and test to check whether a variable is set. 09-01-14 The unset built-in was modified to return 0 exit status when unsetting a variable that was unset to conform with the POSIX standard. 09-01-14 The unset built-in was modified to continue to unset variables after encountering a variable that it could not unset to conform to the POSIX standard. 09-01-14 The parameter expansion ${x+value} no longer expands the value of the variable x when determining whether x is set or not. 09-01-13 A bug in which background jobs and pipelines that were not waited for could, in rare instances, cause the shell to go into an infinite loop or fail has been fixed. 09-01-06 A bug in indexed arrays of compound variables in which referencing non-existent sub-variable in an arithmetic expression could cause the sub-variable to be created has been fixed. 09-01-05 A bug in which the \ character did not escape extended regular expression pattern characters has been fixed. 08-12-24 A bug in which killing the last element of a pipe did not cause a write to the pipe to generate a SIGPIPE has been fixed. 08-12-19 A bug which could cause command substitution to hang when the last element of a pipeline in a command substitution was a built-in and the output was more that PIPE_BUFF. 08-12-18 A bug which occurs when a here documented marker embedded in a command substitution occurs on a buffer boundary has been fixed. 08-12-17 A bug in the output of typeset -p for variables that had attributes but did not have a value has been fixed. 08-12-16 A bug in which a name reference to a name reference variable that references an array element has been fixed. 08-12-16 A bug in which a variable given both the -A and -C attribute along with an initial assignment didn't work correctly has been fixed. 08-12-10 The [[ -t fd ]] test was fixed to handle fd>9. 08-12-10 A bug where function stack misalignment could cause a bus error has been fixed. 08-12-09 Command completion was changed to use \ to quote special characters instead of quoting the argument in single quotes. 08-12-07 A bug in typeset -m which occurred when the target node was an associative array element has been fixed. 08-12-07 A timing bug on some systems (for example Darwin), that could cause the last process of a pipeline entered interactively to fail with an "Exec format error" has been fixed. 08-12-04 +SHOPT_BGX enables background job extensions. Noted by "J" in the version string when enabled. (1) JOBMAX=n limits the number of concurrent & jobs to n; the n+1 & job will block until a running background job completes. (2) SIGCHLD traps are queued so that each completing background job gets its own trap; $! is set to the job pid and $? is set to the job exit status at the beginning of the trap. (3) sleep -s added to sleep until the time expires or until a signal is delivered. 08-12-04 The sign of floating point zero is preserved across arithmetic function calls. 08-12-04 A bug that caused print(1) to produce garbled stdout/stderr output has been fixed. 08-12-04 A bug in which printf "%d\n" "''" did not output the numerical value of the EURO symbol, 8354, has been fixed. 08-11-24 + /dev/fd* and /dev/std* redirections are first attempted with open() to preserve seek semantics; failing that the corresponding file descriptors are dup()'d. 08-11-20 A bug which could cause a core dump if a function compiled with shcomp was found has been fixed. 08-11-20 A bug in which jobs were not cleared from the jobs table for interactive shells when the pipefail option is on has been fixed. 08-11-11 A bug in which a field that was unset in a type definition and later set for an instance could appear twice when displaying the variable has been fixed. 08-11-11 A bug in which running a simple command & inside a function would not return the correct process id has been fixed. 08-11-10 A bug in which the exit status of a command could be lost if the pid was that of the most recent command substitution that had completed has been fixed. 08-11-10 The maximum depth for subshells has been increased from 256 to 65536. 08-11-06 A bug which could cause a core dump when the _ reference variable was used as an embedded type with a compound assignment has been fixed. 08-10-31 --- Release ksh93t --- 08-10-31 Variable scoping/initialization bugs that could dump core were fixed. 08-10-24 The lexer now accepts all RE characters for patterns prefixed with a ksh ~(...) option expression. 08-10-24 +For ${var/pat/sub} \0 in sub expands to the text matched by pat. 08-10-18 A bug in array scoping that could dump core has been fixed. 08-10-10 read -n and -N fixed to count characters in multibyte locales. 08-10-10 A bug that mishandled _.array[] type references has been fixed. 08-10-09 +${.sh.version} now contains a concatenation of the following (after 'Version') denoting compile time features: A SHOPT_AUDIT B SHOPT_BASH L SHOPT_ACCT M SHOPT_MULTIBYTE 08-10-09 A bug that caused subshell command substitution with redirection to hang has been fixed. 08-10-08 Output errors, other than to stderr, now result in a diagnostic. 08-10-08 ksh93 now supports types that contain arrays of other types as members. Earlier versions core dumped in this case. 08-10-05 A bug which caused the shell to emit a syntax error for an arithmetic statement of the form (( var.name[sub] = value)) has been fixed. 08-10-01 A bug that caused subshell command substitution to hang has been fixed. 08-09-29 When the -p export option of typeset is used with other options, only those variables matching the specified options are displayed. 08-09-29 When the shell reads the environment and finds variables that are not valid shell assignments, it now passes these on to subsequent commands rather than deleting them. 08-09-29 A bug in the display of compound variables containing an indexed array of compound variables has been fixed. 08-09-29 A bug in the display of compound variables containing an associative array with a subscript containing a . in the name has been fixed. 08-09-26 A core dump in the subshell environment restore has been fixed. 08-09-24 $(...) has been fixed to properly set the exit status in $?. 08-09-23 $(<...) with IFS=$'\n\n' has been fixed to retain all but the last of multiple trailing newlines. 08-09-23 The -p option to typeset when used with other attributes, restricts the output to variables with the specified attributes. 08-09-22 A bug that sometimes lost the exit status of a job has been fixed. 08-09-21 A bug that retained trailing command substitution newlines in cases where the command caused the shell to fork has been fixed. 08-09-19 type, whence -v, and command -v were fixed to comply with POSIX by writing 'not found' diagnostics to the standard error. 08-09-18 test and [ ... ] were fixed to comply with POSIX in the case of test '(' binop ')' where binop is a valid binary test operator. 08-09-16 +If a method discipline named create is specified when defining a type, this function will be called when an instance is created. 08-09-15 +The variable _ is now set as a reference to the compound variable when defining a compound variable or a type. 08-09-10 The shell now prints an error message when the type name specified for an indexed array subscript is not an enumeration type. 08-09-10 A bug in which a subshell that spawned a background process could lose output that was produced after the foreground completed has been fixed. 08-09-10 A timing bug on some systems that could cause coprocesses started by a subshell to not clean up and prevent other coprocesses has been fixed. 08-09-09 The typeset -m option is now able to rename array elements from the same array. 08-09-09 The exit status of 2 from the DEBUG trap causes the next command to be skipped. An exit value of 255 from a DEBUG trap called from a function causes the function to return. 08-09-08 A bug in which a coprocess created in a subshell that did not complete when the subshell terminated could prevent a coprocess from being created in the parent shell has been fixed. 08-09-05 An assignment of the form name1=name2 where name1 and name2 are both compound variables causes name1 to get a copy of name2. name1+=name2 causes name2 sub-variables to be appended to name1. 08-09-05 A bug in which unsetting a compound variable did not unset all the sub-variables has been fixed. 08-09-01 A bug in the subshell cleanup code that could cause SIGSEGV has been fixed. 06-08-26 +The SHLVL variable which is an environment variable used by bash and zsh that gets incremented when the shell starts. 08-08-25 +For an indexed array, a negative subscript now refers to offsets from the end so that -1 refers to the last element. 08-08-24 An alignment error for shorts on 64 bit architectures has been fixed. 08-08-22 If oldvar is a compound variable, typeset -C newvar=oldvar creates newvar as a copy of oldvar. 08-08-19 +The ALRM signal no longer cause the sleep builtin to terminate. 08-08-13 When used in an arithmetic expression, the .sh.version variable now produces a number that will be increasing for each release. 08-08-11 A bug in which type instantiation with a compound assignment in a dot script in which the type is defined has been fixed. 08-08-07 +The -m option has been added to typeset to move or rename a variable. Not documented yet. 08-08-06 A bug in read when used in a loop when a prompt was specified when reading from a terminal has been fixed. 08-08-01 A bug with the pipefail option in which a nested pipeline could cause an asynchronous command to block has been fixed. 08-08-01 A for loop optimizer bug that treats .sh.lineno as an invariant has been fixed. 08-07-30 A bug in which expanding compound variable that had a get discipline from with a here document could cause a syntax error has been fixed. 08-07-18 A bug in which a nameref caused a local variable to be created rather than binding to an existing variable in the global scope has been fixed. 08-07-17 A bug which occurred when a nameref was created from within a function that was part of a pipeline has been fixed. 08-07-14 +The compile option SHOPT_STATS was added. With this option the compound variable .sh.stats keeps usage statistics that could help with performance tuning. 08-07-10 +The output of set now always uses a single line for each variable. For array variables, the complete set of values is now displayed. 08-07-09 +The typeset -C option can be used with arrays to indicate that each element should default to a compound variable. 08-07-08 +The %B format now outputs compound variables and arrays. The alternate flag # can be used to cause output into a single line. 08-07-03 When the window change signal, WINCH, is received, the current edit line is redrawn in place. 08-07-01 A bug in the handling of shared variables when inside an embedded type has been fixed. 08-06-29 A bug in multiline edit mode which occurred when the prompt length was three characters or less has been fixed. 08-06-23 A bug in which the SIGCLD was not be triggered when background jobs completed has been fixed. 08-06-23 _KSH_VERSION added as a name reference to .sh.version. 08-06-20 type now outputs 'special builtin' for special builtins. 08-06-19 A couple of bugs in multidimensional arrays have been fixed. 08-06-19 A bug in which a syntax error in a dot script could generate a syntax error in the next subsequent command has been fixed. 08-06-17 Reduced the maximum function call depth to 2048 to avoid exceptions on some architectures. 08-06-16 A bug in which printf "%B" could generate an exception when the specified variable was not set has been fixed. 08-06-16 +When typeset -p is followed by variable names, it now displays the attributes names and values for the specific names. 08-06-14 A bug that could affect the drawing of the screen from multiline emacs or gmacs mode when walking up the history file has been fixed. 08-06-13 A bug in which a compound variable defined in a subshell could have side effects into the parent shell has been fixed. 08-06-13 A number of bugs related to using .sh.level to set the stack from for DEBUG traps have been fixed. 08-06-13 +The .sh.lineno variable has been added. When .sh.level is changed inside a DEBUG trap, the .sh.lineno contains the calling line number for the specified stack frame. 08-06-13 The .sh.level variable has been documented and now works. 08-06-11 +The -C option has been added to read for reading compound command definitions from a file. 08-06-11 +The . command is now permitted inside a compound command definition. The dot script can contain declaration commands and dot commands. 08-06-09 +Add -C option to typeset so that typeset -C foo, is equivalent to foo=(). 08-06-09 Added -n warning message for typeset option orderings that are valid with ksh88 but not valid with ksh93, for example Lx5. 08-06-09 A bug in which the return value for an assignment command containing a command substitution with that failed was zero when the assignment contained redirections has been fixed. 08-06-09 A bug in the quoting of $ inside a ERE pattern ~(E)(pattern) has been fixed. 08-06-06 A bug when processing `` command substitution with the character sequence \$' has been fixed. 08-06-02 +When defining a type, the typeset -r attribute causes this field to be required to be specified for each instance of the type and does not allow a default value. 08-06-02 Several bugs in which compound variables were modified by subshells have been fixed. 08-05-22 +The ceil function has been added to the math functions. 08-05-21 A bug in which a name reference defined in a function and passed as an argument to another function could cause an incorrect binding. 08-05-21 A bug in freeing compound variables that are local to functions has been fixed. 08-05-19 +The array expansions ${array[sub1..sub2]} and ${!array[sub1..sub2]} to expand to the value (or subscripts) for array between sub1 and sub2 inclusive. For associative arrays, the range is based on location in the POSIX locale. The .. must be explicit and cannot result from an expansion. 08-05-15 The trap on SIGCLD is no longer triggered by the completion of the foreground job as with ksh88. 08-05-14 A bug in the implementation of the editing feature added on 07-09-19 in emacs mode has been fixed. 08-05-12 A bug in processing the test built-in with parenthesis has been fixed. 08-05-12 The unset built-in now returns non-zero when deleting an array subscript that is not set. 08-05-08 +Changing the value of HISTFILE or HISTSIZE will cause the old history file to be close and reopened with the new name or size. 08-05-08 When FPATH is changed functions that were found via a path search will be searched for again. 08-05-08 A parser bug in which reserved words and labels were recognized inside compound indexed array assignment after a new-line has been fixed. 08-05-07 A bug in getopts when handling numerical option arguments has been fixed. 08-05-07 +The typeset -S option was added for variables outside type definitions to provide a storage class similar to C static inside a function defined with function name. When outside type definitions and outside a function, the -S option cause the specified variable so be unset before the assignment and before the remaining attributes are supplied. 08-05-07 A bug that affected the cursor movement in multiline mode when a character was deleted from near the beginning of the any line other than the first. 08-05-01 In multiline edit mode, the refresh operation will now clear the remaining portion of the last line. 08-05-01 A bug in computing prompt widths for the edit modes for prompts with multibyte characters has been fixed. 08-05-01 A bug in the multiline edit mode which could cause the current line to be displayed incorrectly when moving backwards from third or higher line to the previous line has been fixed. 08-05-01 A bug in which options set in functions declared with the function name syntax were carried across into functions invoked by these functions has been fixed. 08-04-30 A bug which could cause a coprocess to hang when the read end is a builtin command has been fixed. 08-04-30 +The emacs and vi editors have been modified to handle window change commands as soon as they happen rather than waiting for the next command. 08-04-28 A bug in which ${!x} did not expand to x when x was unset has been fixed. 08-04-27 A bug in which the assignment x=(typeset -a foo=([0]=abc)) created x.foo as an associative array has been fixed. 08-04-25 A bug in which $# did not report correctly when there were more than 32K positional parameters has been fixed. 08-04-04 Choose the name _ as the sub-variable that holds type or instance specific data used by discipline functions. 08-03-27 A bug in which the terminal group was not given back to the parent shell when the last part of a pipeline was handled by the parent shell and the other parts of the pipeline complete has been fixed. The symptom was that the pipeline became uninterruptible. 08-03-25 A bug in restricted mode introduced in ksh93s that caused scripts that did not use #! to executed in restricted mode has been fixed. 08-03-25 A bug in which the pipefail option did not work for a pipeline within a pipeline has been fixed. 08-03-24 A bug in which OPTIND was not set correctly in subshells has been fixed. 08-03-24 A bug which could cause a memory exception when a compound variable containing an indexed array with only element 0 defined was expanded. 08-03-20 A bug in which ${!var[sub].*} was treated as an error has been fixed. 08-03-20 Associative array assignments of the form ([name]=value ...) now allow ; as well as space tab and new line to separate elements. 08-03-18 A buffering problem in which standard error was sometimes not flushed before sleep has been fixed. 08-03-17 A bug in which a signal sent to $$ while in a subshell would be sent to the subshell rather than the parent has been fixed. 08-03-17 + A --default option added to set(1) to handle set +o POSIX semantics. set --state added as a long name alias for set +o. 08-03-14 A bug in which using monitor mode from within a script could cause the terminal group to change has been fixed. 08-03-10 The new ${...} command substitution will treat the trailing } as a reserved word even if it is not at the beginning of a command, for example, ${ date }. 08-03-10 If the name of the ENV begins with /./ or ././ then the /etc/ksh.kshrc file will not be executed on systems that support this interactive initialization file. 08-03-07 A bug in which ksh -i did not run the ENV file has been fixed. 08-03-07 A bug in which ulimit did not always produce the same output as ulimit -fS has been fixed. 08-03-04 A bug in multiline mode in emacs and vi mode which could cause the cursor to be on the wrong line when interrupt was hit has been fixed. 08-03-03 The change made in ksh93s+ on 07-06-18 in which braces became optional for ${a[i]} inside [[ ... ]] was restored in the case where the argument can be a pattern. 08-03-03 A bug in which creating a name reference to an associative array instance would fail when the subscript contained characters [ or ] has been fixed. 08-02-29 +The redirection operator >; has been added which for non-special files, generates the output in a temporary file and writes the specified file only of the command has completed successfully. 08-02-15 A bug in ${var/pattern/string} for patterns of the form ?(*) and +(*) has been fixed. 08-02-07 A bug in which test \( ! -e \) produced an error has been fixed. 08-02-14 +The typeset -a option can now optionally be followed by the name of an enumeration type which allows subscripts to be enumerations. 08-02-14 +The enum builtin which creates enumeration types has been added. 08-02-12 The backoff logic when there are no more processes has been fixed. 08-02-07 The -X option has been added to typeset. The -X option creates a double precision number that gets displayed using the C99 %a format. It can be used along with -l for long double. 08-01-31 The -T option to typeset has been added for creating typed variables. Also the -h and -S options have been added to typeset that are only applicable when defining a type. 08-01-31 The prefix expansion operator @ has been added. ${@name} expands to the type of name or yields the attributes. 07-11-15 A bug in the macro expander for multibyte characters in which part of the character contains a file pattern byte has been fixed. 07-10-03 A bug in which : was not allowed as part of an alias name has been fixed. 07-09-26 A bug in which appending a compound variable to a compound variable or to an indexed array didn't work has been fixed. 07-09-19 In both emacs and vi edit mode, the escape sequence \E[A (usually cursor up, when the cursor is at the end of the line will fetch the most recent line starting with the current line. 07-09-18 The value of ${!var} was correct when var was a reference to an array instance. 07-09-18 The value of ${!var[sub]} was not expanding to var[sub] and this was fixed. It also fixed ${name} where name is a name reference to var[sub]. 07-09-18 +It is now legal to create a name reference without an initialization. It will be bound to a variable on the first assignment. 07-08-30 +A discipline function can be invoked as ${x.foo} and is equivalent to ${ x.foo;} and can be invoked as x.foo inside ((...)). 07-07-09 A bug in which typeset -a did not list indexed arrays has been fixed. 07-07-03 +The command substitution ${ command;} has been added. It behaves like $(command) except that command is executed in the current shell environment. The ${ must be followed by a blank or an operator. 08-04-17 --- Release ksh93s+ --- 08-04-17 A bug in which umask was not being restored correctly after a subshell has been fixed. 08-04-15 A bug in which sending a STOP signal to a job control shell started from within a shell function caused cause the invoking shell to terminate has been fixed. 08-04-11 A bug which caused $(exec > /dev/null) to go into an infinite loop has been fixed. 08-03-27 A bug in which typeset -LZ was being treated as -RZ has been fixed. 08-03-06 A bug with ksh -P on systems that support the profile shell, in which it would exit after running a non-builtin has been fixed. 08-01-31 A bug in which command substitution inside ((...)) could cause syntax errors or lead to core dumps has been fixed. 08-01-17 A bug in which discipline functions could be deleted when invoked from a subshell has been fixed. 08-01-17 A bug in which a command substitution consisting only of assignments was treated as a noop has been fixed. 08-01-17 A bug in which discipline functions invoked from within a compound assignment could fail has been fixed. 08-01-16 Incomplete arithmetic assignments, for example ((x += )), now generate an error message. 08-01-16 A bug in which a set discipline defined for a variable before an array assignment could cause a core dump has been fixed. 08-01-03 A bug in on some systems in which exit status 0 is incorrectly returned by a process that catches the SIGCONT signal is stopped and then continued. 07-12-13 A race condition in which a program that has been stopped and then continued could lose its exit status has been fixed. 07-12-12 Code to check for file system out of space write errors for all writes has been added. 07-12-11 A bug in the macro expander for multibyte characters in which part of the character contains a file pattern byte has been fixed. 07-12-06 A bug in the emacs edit mode when multiline was set that output a backspace before the newline to the screen has been fixed. 07-12-04 A bug in which using TAB after a variable name listing expansion in the edit modes would cause the $ to disappear has been fixed. 07-11-28 A bug in which setting IFS to readonly could cause a subsequent command substitution to fail has been fixed. 07-11-27 A work around for a gcc 4.* C99 "feature" that could cause a job control shell to go into an infinite loop by adding the volatile attribute to some auto vars in functions that call setjmp(). 07-11-27 A bug in which the shell could read ahead on a pipe causing the standard input to be incorrectly positioned has been fixed. 07-11-27 A bug in which compound variable UTF-8 multibyte values were not expanded or traced properly has been fixed. 07-11-21 A bug where an unbalanced '[' in a command argument was not treated properly has been fixed. 07-11-15 A bug in which compatibility mode (no long option names) getopts(1) incorrectly set the value of OPTARG for flag options has been fixed. 07-11-15 A bug in which "hash -- name" treated "--" as an invalid name operand has been fixed. 07-11-15 typeset now handles "-t -- [-r] [--]" for s5r4 hash(1) compatibility. 07-11-15 A bug in which the umask builtin mishandled symbolic mode operands has been fixed. 07-11-15 Bugs in which shell arithmetic and the printf builtin mishandled the signs of { -NaN -Inf -0.0 } have been fixed. 07-11-15 +The full { SIGRTMIN SIGRTMIN+1 ... SIGRTMAX-1 SIGRTMAX } range of signals, determined at runtime, are now supported. 07-11-15 A bug in which creating an indexed array with only subscript 0 created only a simple variable has been fixed. 07-11-14 A bug in which appending to an indexed array using the form name+=([sub]=value) could cause the array to become an associative array has been fixed. 07-11-14 A bug in which typeset without arguments could coredump if a variable is declared as an indexed array and has no elements has been fixed. 07-11-14 A bug in which creating a local SECONDS variable with typeset in a function could corrupt memory has been fixed. 07-11-14 A bug which could cause a core dump when a script invoked by name from a function used compound variables has been fixed. 07-11-05 A bug in which printf %d "'AB" did not diagnose unconverted characters has been fixed. 07-11-05 printf %g "'A" support added for all floating point formats. 07-11-01 A bug in which typeset -f fun did not display the function definition when invoked in a subshell has been fixed. 07-10-29 The sleep builtin was fixed so that all floating point constants are valid operands. 07-10-10 A bug in which the locale was not being restored after LANG=value command has been fixed. 07-09-20 A bug in which a nameref to a compound variable that was local to the calling function would not expand correctly when displaying is value has been fixed. 07-09-19 A bug which could cause a core dump if .sh.edchar returned 80 characters or more from a keyboard trap has been fixed. 07-09-14 A bug in which could cause a core dump when more than 8 file descriptors were in use has been fixed. 07-09-10 A bug in which creating a name reference to an instance of an array when the array name is itself a reference has been fixed. 07-09-10 The file completion code has been modified so that after an = in any word, each : will be considered a path delimiter. 07-09-06 A bug in which subprocess cleanup could corrupt the malloc() heap has been fixed. 07-08-26 A bug in which a name reference to an associative array instance could cause the subscript to be evaluated as an arithmetic expression has been fixed. 07-08-22 A bug in which the value of an array instance was of a compound variable was not expanded correctly has been fixed. 07-08-14 A bug which could cause a core dump when a compound assignment was made to a compound variable element with a typeset -a attribute has been fixed. 07-08-08 A bug in which a trap ignored in a subshell caused it to be ignored by the parent has been fixed. 07-08-07 A bug in which the set command would generate erroneous output for a variable with the -RZ attribute if the variable name had been passed to a function has been fixed. 07-08-02 A bug in which read x[1] could core dump has been fixed. 07-08-02 A second bug in which after read x[sub] into an associative array of an element that hasn't been assigned could lead to a core dump has been fixed. 07-07-31 A bug in which a pipeline that completed correctly could have an exit status of 127 when pipefail was enabled has been fixed. 07-07-09 +The SHOPT_AUDIT compile option has been added for keyboard logging. 07-06-25 In vi insert mode, ksh no longer emits a backspace character before the carriage return when the newline is entered. 07-06-25 A bug in which pipefail would cause a command to return 0 when the pipeline was the last command and the failure happened on a component other than the last has been fixed. 07-06-25 A bug in the expansion of ${var/pattern/rep} when pattern or rep contained a left parenthesis in single quotes has been fixed. 07-06-18 The braces for a subscripted variable with ${var[sub]} are now optional when inside [[ ... ]], ((...)) or as a subscript. 07-05-28 A bug in brace expansion in which single and double quotes did not treat the comma as a literal character has been fixed. 07-05-24 The -p option of whence now disables -v. 07-05-23 Several bug fixes in compound variables and arrays of arrays have been made. 07-05-15 A bug in which the %B format of printf was affected by the locale has been fixed. 07-05-14 A bug in which \ was not removed in the replacement pattern with ${var/pattern/rep} when it was not followed by \ or a digit has been fixed. 07-05-10 A bug in which ksh -R file core dumped if no script was specified has been fixed. it not displays an error message. 07-05-07 Added additional Solaris signals to signal table. 07-04-30 A bug in which a pipeline with command substitution inside a function could cause a pipeline that invokes this function to hang when the pipefail option is on has been fixed. 07-04-30 +Added -q to whence. 07-04-18 A small memory leak with each redirection of a non-builtin has been fixed. 07-03-08 A bug in which set +o output command line options has been fixed. 07-03-08 A bug in which an error in read (for example, an invalid variable name), could leave the terminal in raw mode has been fixed. 07-03-06 A bug in which read could core dump when specified with an array variable with a subscript that is an arithmetic expression has been fixed. 07-03-06 Several serious bugs with the restricted shell were reported and fixed. 07-03-02 If a job is stopped, and subsequently restarted with a CONT signal and exits normally, ksh93 was incorrectly exiting with the exit status of the stop signal number. 07-02-26 +M-^L added to emacs mode to clear the screen. 07-02-26 A bug in which setting a variable readonly in a subshell would cause an unset error when the subshell completed has been fixed. 07-02-19 +The format with printf uses the new = flag to center the output. 07-02-19 A bug in which ksh93 did not allow multibyte characters in identifier names has been fixed. 07-02-19 A bug introduced in ksh93 that causes global compound variable definitions inside functions to exit with "no parent" has been fixed. 07-02-19 A bug in which using compound commands in process redirection arguments would give syntax errors <(...) and >(...) has been fixed. 07-01-29 A bug which caused the shell to core dump which can occur when a built-in exits without closing files that it opens has been fixed. 07-01-26 A bug in which ~(E) in patterns containing \ that are not inside () has been fixed. 06-12-29 --- Release ksh93s --- 06-12-29 A bug in which the value of IFS could be changed after a command substitution has been fixed. 06-12-22 +/dev/(tcp|udp|sctp)/HOST/SEVRICE now handles IPv6 addresses on systems that provide getaddrinfo(3). 06-12-19 +A -v option was added to read. With this option the value of the first variable name argument will become the default value when read from a terminal device. 06-11-20 A bug in which "${foo[@]:1}}" expands a null argument (instead of no argument), when foo[0] is not empty has been fixed. 06-11-16 The discipline functions have been modified to allow each subscript to act independently. Currently, the discipline function will not be called when called from a discipline function of the same variable. 06-11-14 A bug which could cause a core dump if a file descriptor for an internal file was closed from with a subshell has been fixed. 06-10-30 +The redirections <# pattern, and <## pattern have been added. Both seek forward to the beginning of the next line that contains the pattern. The <## form copies the skipped portion to standard output. 06-10-26 +On systems that support stream control transport, the virtual file name /dev/sctp/host/port can now be used to establish connections. 06-10-26 +The printf modifier # when used with d produces units in thousands with a single letter suffix added. The modifier # when used with the i specification provides units of 1024 with a two letter suffix. 06-10-24 The value of $! is now set to the process id of a job put into the background with the bg command as required by POSIX. 06-10-23 A bug in which the value of $! was affected by a background job started from a subshell has been fixed. 06-10-23 A bug in ${var:offset:len} in multibyte locales has been fixed. 06-10-15 +The remaining math functions from C99 were added for any system that supports them. 06-10-13 The klockwork.com software detected a few coding errors that have been fixed. 06-10-12 A bug when skipping over `...` with ${x:=`...`} when x is set has been fixed. 06-10-11 A bug in process floating constants produced by the %a format of printf has been fixed. 06-10-06 A bug in which IFS was not being restored correctly in some cases after a subshell has been fixed. 06-10-06 A bug in which pipefail was not detecting some failures in pipelines with 3 or more states has been fixed. 06-10-03 A bug in the processing of >(...) with builtins which could cause the builtin to hang has been fixed. 06-10-03 A bug in the for loop optimizer which causes >(...) process substitution to be ignored has been fixed. 06-09-17 +The -a option was added to typeset for indexed arrays. This is only needed when using the ([subscript]=value ...) form. 06-09-06 +The showme option was added. Each simple command not beginning with a redirection and not occurring with in the while, until, if, select condition can be preceded by a semi-colon which will be ignored when showme is off. When showme is on, any command preceded by a colon will be traced but not executed. 06-08-16 +As a new feature, a leading ~(N) on a pattern has no effect except when used for file expansion. In this case if not matches are found, the pattern is replaced by nothing rather than itself. 06-08-11 A bug in the expansion of ${.sh.match[i]:${#.shmatch[i]}} has been fixed. 06-08-10 +The read builtin options -n and -N have been modified to treat the size as characters rather than bytes unless storing into a binary (typeset -B) variable. 06-07-27 +When the here document operator << is followed directly by a # rather than a -, the first line of the here-document determines how much whitespace is removed for each line. 06-07-26 A bug in the C-shell history (enabled with set -H) in which the history event !$ was not processed has been fixed. 06-07-21 A bug on some systems in which assigning PATH on a command line would not take effect has been fixed. 06-07-20 Add ksh93 and rksh93 as allowable names for ksh binaries. 06-07-20 Removed the SHOPT_OO compilation option which was only partially implemented. 06-07-20 The ability to use egrep, grep, and fgrep expressions within shell patterns has been documented. 06-07-17 A bug with arithmetic command expressions for locales in which the comma is a thousands separator has been fixed. 06-07-13 +The default HISTSIZE was increased from 128 to 512. 06-07-13 A multibyte problem with locales that use shift codes has been fixed. 06-06-23 A number of bug fixes for command, file, and variable completion have been mode. 06-06-20 +Floating point division by zero now yields the constant Inf or -Inf and floating functions with invalid arguments yield NaN. 06-06-20 +The floating point constants Inf and NaN can be used in arithmetic expressions. 06-06-20 +The functions isinf(), isnan(), tanhl() have been added for arithmetic expressions. 06-06-13 Internal change to use ordering for variables instead of hashing to speed up prefix matching. 06-06-13 A window between fork/exec in which a signal could get lost and cause a program to hang has been eliminated 06-06-13 A bug in edit completion with quoted strings has been fixed. 06-06-07 The restricted options can now be enabled by set as well as on the command line. Once set, it can not be disabled. 06-06-04 Modified built-in binding so that for systems for which /bin and /usr/bin are the same, a builtin bound to /bin will get selected when either /bin or /usr/bin is scanned. 06-06-04 +Added literal-next character processing for emacs/gmacs mode. This change is not compatible with earlier versions of ksh93 and ksh88 when the stty lnext is control-v. The sequence escape-control-v will display the shell version. 06-05-31 +Modified emacs and vi mode so that entering a TAB after a partial TAB completion, generates a listing of possible completions. After the second TAB, a number followed by a TAB will perform the completion with the corresponding item. 06-05-19 +Modified arithmetic so that conversions to strings default to the maximum number of precision digits. 06-05-16 Bug fixes for multibyte locales. 06-05-10 The =~ operator was added to [[ ... ]] and [[ string ~= ERE ]] is equivalent to [[ string == ~(E)ERE ]]. 06-04-25 A bug in the vi edit mode which could cause the shell to core dump when switching from emacs mode. 06-04-17 A bug in which using LANG or LC_ in assignment lists with builtins did not restore the locale correctly has been fixed. 06-04-04 A bug in which discipline functions could not be added to variables whose names started with .sh has been fixed. 06-03-28 +The -s option to typeset was added to modify -i to indicate short integers. 06-03-28 A bug in which variables assignment lists before functions defined with function name were not passed on the functions invoked by this function has been fixed. 06-03-28 A bug in which name references defined within a function defined with function name could not be used with compound variables has been fixed. 06-03-27 A bug in which read <&p (print >&p) would cause the coprocess input (output) pipe to close before reading from (after writing to) it has been fixed. 06-02-28 A bug in which stopping a job created with the hist builtin command would create a job that could not be restarted has been fixed. 06-01-24 --- Release ksh93r --- 06-01-24 A bug in which running commands with standard output closed would not work as expected has been fixed. 06-01-23 A bug in which print -u could fail when file descriptor was open for writing has been fixed. 06-01-19 The ?: arithmetic operator fixed to work when the operation after the colon was an assignment. 05-12-24 A bug which could lead to a core dump when elements of a compound variable were array elements, i.e. foo=(bar=(1 2)), has been fixed. 05-12-13 An arithmetic bug in which x+=y+=z was not working has been fixed. 05-12-13 An arithmetic bug in which x||y was returning x when x was non-zero rather than 1 has been fixed. 05-12-07 +The aliases for integer and float have been changed to use attributes -li and -lE to handle long long and long double types. 05-12-07 +The histexpand (-H) option has been added which allows C-shell style history expansions using the history character !. 05-12-07 +The multiline option was added which changes that way the edit modes handle lines longer than the window width. Instead of horizontal scrolling, multiple lines on the screen are used. 05-12-05 The whence builtin now returns an absolute pathname when the command is found in the current directory. 05-11-29 A bug which caused ksh -c '[[ ! ((' to core dump rather than report a syntax error has been fixed. 05-11-29 A bug when reading fixed length records into typeset -b variables which caused a zero byte to terminate the value has been fixed. 05-11-22 +The ability to seek to an offset within a file has been added with the new I/O redirection operators, <# and >#. Currently, these redirection operators must be followed by ((expr)) but in a future release, it should be able to used to seek forward to the specified shell pattern. In addition $(n<#) expands to the current byte offset for file descriptor n. 05-11-22 +The .sh.match array variable is now set after each [[ ... ]] pattern match. Previously it was only set for substring matches. 05-10-17 A bug in which the library path variable could be prefixed with a directory when a .path file was not encountered in the directory of the executable has been fixed. 05-09-15 A for/while loop optimizer bug in which $OPTIND was not correctly expanded has been fixed. 05-09-05 A bug in which a history command that invoked a history command could go into an infinite loop has been fixed. 05-08-31 +In the case that IFS contains to adjacent new-lines so that new-line is not treated as a space delimiter, only a single new-line is deleted at the end of a command substitution. 05-08-19 +When a tilde expansion expands to the / directory and is followed by a /, it is replaced by the empty string. 05-08-16 A bug in which n<&m did not synchronize m has been fixed. 05-08-16 A bug in which process substitution ( <() and >() ) was not working within for and while loops has been fixed. 05-07-24 A bug in which the pattern ~(E)(foo|bar) was treated as a syntax error has been fixed. 05-07-24 A bug in completion with =, where n was the one of the previous selection choices has been fixed. 05-07-21 A bug with multibyte input when no edit mode was specified which caused the input line to shift left/right has been fixed. 05-06-24 A race condition which could cause the exit status to get lost on some fast systems has been fixed. 05-06-21 A bug in which nested patterns of the form {m,n}(pat) would cause syntax errors has been fixed. 05-06-21 A bug in the macro expander has been fixed which could cause a syntax error for an expansion of the form ${x-$(...)} when x is set and the command substitution contained certain strings. 05-06-08 +On systems for which echo does not do System V style \ expansions, the -e option was added to enable these expansion. 05-06-08 A bug in which ${var op pattern} to not work when inside an arithmetic expression has been fixed. 05-05-23 +An extension to shell patterns that allows matching of nested groups while skipping over quoted strings has been added. 05-05-18 A bug in which the line number for errors was not correct for functions loaded from FPATH has been fixed. 05-04-18 A bug in which the exit status $? is not set when a trap triggered by the [[ ... ]] command is executed has been fixed. 05-04-08 +Redirection operators can be directly preceded with {varname} with no intervening space, where varname is a variable name which allows the shell to select a file descriptor > 10 and store it into varname. 05-04-08 +SHOPT_CMDLIB_BLTIN=1 now includes generated table. 05-04-07 +[[ -o ?option ]] is true if "option" is a supported option. 05-04-05 A bug in handling file completion with spaces in the names has been fixed. 05-03-25 +The SIGWINCH signal is caught by default to keeps the LINES and COLUMNS variables in sync with the actual window size. 05-03-25 +Building ksh with SHOPT_REMOTE=1 causes ksh to set --rc if stdin is a socket (presumably part of a remote shell invocation.) 05-03-25 +Building ksh with SHOPT_SYSRC=1 causes interactive ksh to source /etc/ksh.kshrc (if it exists) before sourcing the $ENV file. 05-03-25 +{first..last[..incr][%fmt]} sequences added to brace expansions when braceexpand is enabled. 05-03-03 A bug where a SIGCHLD interrupt could cause a fifo open to fail has been fixed. 05-02-25 A bug in which a builtin command run in the background could keep a file descriptor open which could cause a foreground process to hang has been fixed. 05-02-24 A bug where builtin library commands (e.g., date and TZ) failed to detect environment variable changes has been fixed. 05-02-22 +The read builtin and word splitting are now consistent with respect to IFS -- both treat IFS as field delimiters. 05-02-22 +The read builtin no longer strips off trailing delimiters that are not space characters when there are fewer variables than fields. 05-02-17 A builtin bug on systems where dlsym(libcmd) returns link-time bindings has been fixed. 05-02-12 A bug in which the lib_init() function for .paths BUILTIN_LIB libraries was not called has been fixed. 05-02-06 A bug on some systems in which moving the write end of a co-process to a numbered file descriptor could cause it to close has been fixed. 05-02-06 A bug in the vi-edit mode in which the character under the cursor was not deleted in some cases with the d% directive has been fixed. 05-02-06 A bug where external builtin stdout/stderr redirection corrupted stdout has been fixed. 05-02-04 A bug where times formatting assumed CLK_TCK==60 has been fixed. 05-01-11 --- Release ksh93q --- 05-01-11 A bug in the integral divide by zero check has been fixed. 05-01-11 +The -l option has been added to read /etc/profile and $HOME/.profile, if they exist, before the first command. 05-01-11 An argument parsing bug that caused `kill -s x -- n' to fail has been fixed. 05-01-11 +The .paths file, introduced in ksh93m, which can appear in any directory in PATH, now allows a line of the form 'BUILTIN_LIB=.' When a command is searched for this directory, and the full path matches the path of the built-in version of the command (listed by the 'builtin' command) then the built-in version of the command is used. When ksh is built with SHOPT_CMDLIB_DIR=1 then all libcmd functions become builtins with the '/opt/ast/bin/' directory prefix. 05-01-10 A bug in which a nameref to a compound name caused a core dump has been fixed. 05-01-09 A bug in which some SIGCHLD interrupts (from child processes exiting) caused a fatal print/echo error diagnostic has been fixed. 04-12-24 A bug in which some SIGCHLD interrupts (from child processes exiting) corrupted the internal process/job list, sometimes causing the shell to hang, has been fixed. 04-12-01 A bug in which typeset -Fn truncated less than n digits for large numbers has been fixed. 04-11-25 A bug in which standard error could be closed after a redirection to /dev/stderr has been fixed. 04-11-17 A bug in which an expansion of the form ${array[@]:3} could expand to ${array[0]} when ${array[3]} was not set has been fixed. 04-10-22 +The -E or -orc command line option reads ${ENV-$HOME/.kshrc} file. 04-10-22 +`-o foo' equivalent to `+o nofoo', `-o nobar' equivalent to `+o bar'. `--foo' equivalent to `-o foo', `--nofoo' equivalent to `+o foo' 04-10-05 +The .paths file, introduced in ksh93m, which can appear in any directory in PATH, now allows a line of the form 'BUILTIN_LIB=libname'. When a command is searched for this directory, the shared library named by libname will first be searched for a built-in version of the command. 04-09-03 <<< here documents now handle quotes in the word token correctly. 04-08-08 +The maximum size for read -n and read -N was increased from 4095 to 32M. 04-08-04 +printf %q was modified so that if an no operand was supplied, no no output would be generated rather than a quoted empty string. 04-08-01 +The -n and -N options of the read builtin has been modified when reading variables with the binary attribute so that the data is stored directly rather than through assignment. 04-08-01 +The shcomp command has been modified to process alias commands under some conditions. 04-07-31 +The .sh.match variable added in ksh93l, now works like other indexed arrays. 04-07-08 A loop optimizer bug which occurs when typeset is used in a for or while loop inside a function has been fixed. 04-06-24 +The number of subexpressions in a pattern was increased to 64 from the current number of 20. 04-06-17 +The -t option to read was modified to allow seconds to be specified as any arithmetic expression rather than just an integral number of seconds, for example even -t 'sin(.5)' is now valid. 04-06-16 Two small memory leak problems were fixed. 04-06-15 A bug in ${var/pattern/"string"} which occurred when string contained pattern matching characters has been fixed. 04-05-08 printf $'%d\n' produced an erroneous error message and has been fixed. 04-05-24 A bug in which an associative array without any elements could cause a core dump when a script with an associative array with the same name was declared in a script invoked by name has been fixed. 04-05-11 A bug in which an exec statement could close the script that is being processed in a script that is run by name causing a failure has been fixed. 04-04-28 +If the first character of assignment to an integer variable was 0, the variable had been treated as unsigned. This behavior was undocumented and has been removed. 04-04-05 A bug in which the positioning of standard input could be incorrect after reading from standard input from a subshell has been fixed. 04-03-30 A bug in the for loop optimizer which in rare cases could cause memory corruption has been fixed. 04-03-29 +The preset alias source='command .' has been added. 04-03-29 A bug introduced in ksh93p on some systems in which invoked by name with #! on the first line would not get the signals handling initialized correctly has been fixed. 04-03-29 A bug introduced in ksh93p in which a HUP signal received by a shell that is a session group leader was not passed down to its children has been fixed. 04-02-28 --- Release ksh93p --- 04-02-28 +The ability to apply an append discipline to any variable has been added. 04-02-14 A bug in which the exportall option (set -a) would cause incorrect results for arrays has been fixed. 04-02-02 A bug in which an exported array would pass more than the first element to a script invoked by name has been fixed. 04-02-02 A bug on some systems in which name=value pairs preceding a script invoked by name was not getting passed to the script has been fixed. 04-01-20 A bug in which an unset discipline function could cause a core dump on some systems has been fixed. 04-01-12 A bug in which a continue or break called outside a loop from inside a function defined with name() syntax could affect the invoking function has been fixed. 04-01-08 If a command name begins with ~, only filename completion will be attempted rather than pathname completion using the builtin editors. 04-01-08 A bug in the vi edit mode in which the wrong repeat count on multiple word replacements with the . directive has been fixed. 04-01-06 Backspace characters are now handled correctly in prompt strings. 04-01-06 +The getopts builtin has been modified to accept numerical arguments of size long long on systems that support this. 04-01-06 A bug in which unsetting all elements of an associative array would cause it to be treated as an indexed array has been fixed. 03-12-15 A bug in which a quoted string ending with an unescaped $ would delete the ending $ in certain cases has been fixed. 03-12-05 A bug in which the shell could hang when set -x tracing a command when an invalid multibyte character is encountered has been fixed. 03-12-05 On some systems, if the KEYBD trap is set, then commands that use the meta key were not processed until return was hit. This has been fixed. 03-12-05 A problem which occurred when the login shell was not a group leader that could cause it to fail has been fixed. 03-12-05 A problem in which a shell could core dump after receiving a signal that should cause it to terminate while it was in the process of acquiring more space has been fixed. 03-12-05 +If ENV is not specified, the shell will default to $HOME/.kshrc for interactive shells. 03-11-21 A bug introduced in ksh93o in which the DEBUG trap could get disabled after it triggered has been fixed. 03-11-04 A bug in which using arithmetic prefix operators ++ or -- on a non-lvalue could cause a core dump has been fixed. 03-11-04 A bug in which leading zeros were stripped from variable expansions within arithmetic computation to avoid being treated as octal constants when they should not have, has been fixed. 03-10-08 A bug introduced in ksh93o in which a large here document inside a function definition could get corrupted has been fixed. 03-09-22 A bug in which the .get discipline function was not being called when a string variable was implicitly referenced from within a numerical expression has been fixed. 03-09-22 A bug in which a script without a leading #! could get executed by /bin/sh rather than the current shell on some systems has been fixed. 03-09-12 +To improve conformance with ksh88, leading zeros will be ignored when getting the numerical value of a string variable so that they will not be treated as octal constants. 03-09-03 +The builtin kill command now processes obsolete invocations such as kill -1 -pid. 03-09-02 The restriction on modifying FPATH in a restricted shell (sh -r) has been documented. 03-09-02 +The restricted shell (sh -r) has been modified to disallow executing command -p. 03-08-07 A bug in which the KEYBD trap was not being invoked when characters with the 8th bit set has been fixed. 03-08-02 A parser bug introduced in ksh93o which caused the character after () in a POSIX function definition to be skipped when reading from standard input has been fixed. 03-08-01 A bug in which "${foo#pattern}(x)" treated (x) as if it were part of the pattern has been fixed. 03-08-01 +The command -x option has been modified so that any trailing arguments that do expand to a single word will be included on each invocation, so that commands like command -x mv * dir work as expected. 03-07-20 --- Release ksh93o+ --- 03-07-20 A bug in which could cause memory corruption when a POSIX function invoked another one has been fixed. 03-07-15 A bug in which a file descriptor>2 could be closed before executing a script has been fixed. 03-07-15 A parsing error for <() and >() process substitutions inside command substitution has been fixed. 03-07-15 A parsing error for patterns of the form {...}(...) when used inside ${...} has been fixed. 03-07-15 An error in which expanding an indexed array inside a compound variable could cause a core dump has been fixed. 03-07-15 A bug in which on rare occasions a job completion interrupt could cause to core dump has been fixed. 03-06-26 A bug in which process substitution embedded within command substitution would generate a syntax error has been fixed. 03-96-23 A bug in which ${@:offset:len} could core dump when there were no arguments has been fixed. 03-96-23 A bug in which ${X[@]:offset:len} could core dump when X was unset has been fixed. 03-06-22 +The -x option was added to the command builtin. If this option is on, and the number of arguments would exceed ARG_MAX, the command will be invoked multiple times with a subset of the arguments. For example, with alias grep='command -x grep, any number of arguments can be specified. 03-06-14 A bug in which could cause a core dump on some systems with vi and emacs editors with the MULTIBYTE option has been fixed. 03-06-06 A bug in which the shell could core dump when a script was run from its directory, and the script name a symlink to a file beginning with .., has been fixed. 03-06-05 A bug in which the shell could core dump when a child process that it is unaware of terminates while it is calling malloc() has been fixed. 03-06-02 +An option named globstar (set -G) has been added. When enabled, during pathname expansion, any component that consists only of ** is matches all files and any number of directory levels. 03-05-30 A bug in which the PATH search could give incorrect results when run from directory foo and PATH contained .:foo:xxx has been fixed. 03-05-29 +Some changes were made to the code that displays the prompt in edit mode to better handle escape sequences in the prompt. 03-05-27 I added = to the list of characters that mark the beginning of a word for edit completion so that filenames in assignments can be completed. 03-05-20 A bug in which read -N could hang on some systems when reading from a terminal or a pipe has been fixed. 03-05-19 A bug in which the output of uname from a command substitution would go to the standard output of the invoking command when uname was invoked with a non-standard option has been fixed. 03-05-19 A job control bug which would cause the shell to exit because it hadn't taken back the terminal has been fixed. The bug could occur when running a function that contained a pipeline whose last element was a function. 03-05-19 A job control timing bug introduced in ksh93o on some systems which could cause a pipeline to hang if the first component completed quickly has been fixed. 03-05-13 +The read builtin has been modified so that the builtin editors will not overwrite output from a previous incomplete line. 03-05-13 A bug in which the name of an identifier could have the string .sh. prefixed to it after expanding a variable whose name begins with .sh. has been fixed. 03-05-13 A bug in the expansion of $var for compound variables in which some elements would not be output when the name was a prefix of another name in the compound variable has been fixed. 03-05-08 The last item in the ksh93o release on 03-01-02 has been altered slightly to preserve the leading 0's when the preceding character is a digit. Thus, with typeset -LZ3 x=10, $(( 1$x)) will be 1010 whereas $(( $x) will be 10. 03-04-25 A bug in which if x is a name reference, then nameref y=x.foo did not follow x has been fixed. 03-03-18 --- Release ksh93o --- 03-03-18 +A -N unary operator was added to test and [[ ... ]] which returns true if the file exists and the file has been modified since it was last read. 03-03-18 +The TIMEFORMAT variable was added to control the format for the time compound command. The formatting description is described in the man page. 03-03-06 +A -N n option was added to read which causes exactly n bytes to be read unlike -n n which causes at most n bytes to be read. 03-03-03 +Three new shell variables were added. The variable .sh.file stores the full pathname of the file that the current command was found in. The variable .sh.fun names the current function that is running. The variable .sh.subshell contains the depth of the current subshell or command substitution. 03-03-03 +When the DEBUG trap is executed, the current command line after expansions is placed in the variable .sh.command. The trap is also now triggered before each iteration of a for, select, and case command and before each assignment and redirection. 03-02-28 +Function definitions are no longer stored in the history file so that set -o nolog no longer has any meaning. 03-02-28 +All function definitions can be displayed with typeset -f not just those stored in the history file. In addition, typeset +f displays the function name followed by a comment containing the line number and the path name for the file that defined this function. 03-02-28 A bug in which the value of $LINENO was not correct when executing command contained inside multi-line command substitutions has been fixed. 03-02-19 +Since some existing ksh88 scripts use the undocumented and unintended ability to insert a : in front of the % and # parameter expansion operators, ksh93 was modified to accept :% as equivalent to % and :# as equivalent to # with ${name op word}. 03-02-14 A bug which could cause a core dump when reading from standard error when standard error was a pty has been fixed. 03-02-14 +The shell arithmetic was modified to use long double on systems that provide this data type. 03-02-09 A bug in which a function located in the first directory in FPATH would not be found when the last component of PATH was . and the current directory was one of the directories in PATH has been fixed. 03-02-07 +The trap and kill builtin commands now accept a leading SIG prefix on the signal names as documented. 03-02-05 A bug in the expansion of ${var/$pattern}, when pattern contained \[ has been fixed. 03-02-05 A bug in which .sh.match[n], n>0, was not being set for substring matches with % and %% has been fixed. 03-01-15 A bug in which getopts did not work for numerical arguments specified as n#var in the getopts string has been fixed. 03-01-09 A bug in which using ${.sh.match} multiple times could lead to a memory exception has been fixed. 03-01-06 A bug in the expansion of ${var/pattern/$string} in the case that $string contains \digit has been fixed. 03-01-02 +A -P option was added for systems such as Solaris 8 that support profile shell. 03-01-02 For backward compatibility with ksh88, arithmetic expansion with ((...)) and let has been modified so that if x is a zero-filled variable, $x will not be treated as an octal constant. 02-12-05 --- Release ksh93n+ --- 02-11-30 A bug that can show up in evaluating arithmetic statements that are in an autoloaded function when the function is autoload from another function has been fixed. 02-11-30 An optimization bug in which an expansion of the form ${!name.@}, which occurred inside a for or a while loop, when name is a name reference, has been fixed. 02-11-18 A bug in which modifying array variables in a subshell could leave side effects in the parent shell environment has been fixed. 02-11-18 A memory leak when unsetting an associative array has been fixed. 02-11-14 +The code to display compound objects was rewritten to make it easier for runtime extensions to reuse this code. 02-11-14 +A change was made to allow runtime builtins to be notified when a signal is received so that cleanup can be performed. 02-10-31 +User applications can now trap the ALRM signal. Previously, the ALRM signal was used internally and could not be used by applications. 02-10-31 A bug in which signals received while reading from a coprocess for which traps were set was not handled correctly has been fixed. 02-10-31 A bug in which a file opened with exec inside a subshell could be closed before the subshell completed has been fixed. 02-10-21 A bug in which setting PATH or FPATH inside a function might not take effect has been fixed. 02-10-21 A bug which could cause a core dump when a local SECONDS variable is defined in a function has been fixed. 02-10-15 A bug in which the associative array name operator ${!array[@]} could return the same name multiple times has been fixed. 02-10-15 A bug in which the zero'th element of an associative array was not getting set when an assignment was made without a subscript specified has been fixed. 02-09-30 --- Release ksh93n --- 02-09-30 +The maximum indexed array size was increased to 16Megs. 02-09-30 A bug which could cause a core dump when changing attributes of associative array has been fixed. 02-09-30 A bug in which exporting an array variable would not export the 0-th element has been fixed. 02-09-30 A bug in which an array assignment of the form a=($a ...) would unset 'a' before the right hand side was evaluated has been fixed. 02-09-27 A bug in which the error message for ${var?message} when var was null or unset did not contain the variable name var has been fixed. 02-09-27 A bug in which closing file descriptors 0 through 2 could cause a subsequent here document to fail has been fixed. 02-09-14 A bug in whence which occurs when the specified name contained a / has been fixed. 02-09-14 A bug in the parser for strings of the form name$((expr))=value has been fixed. 02-09-14 A for loop optimization bug in which the number of elements in an array was treated as an invariant has been fixed. 02-09-09 A bug in which redirection or closing of a file descriptor between 3 and 9 could cause a subsequent here document to fail has been fixed. 02-09-09 A bug in which a background job was not removed from the job list when a subshell completed has been fixed, for example (prog&). 02-09-03 A bug in which an assignment of the form name=(integer x=3) could be interpreted as an array assignment rather than a compound variable assignment has been fixed. 02-08-19 A command completion bug which occurred on file systems that are case insensitive has been fixed. 02-08-19 A bug which could lead to an exception on some systems (for example FREEBSD) which occurred when setting PATH has been fixed. 02-08-11 A bug in arithmetic rounding in which a value input as a decimal string would output as a rounded version of the string has been fixed. 02-08-11 A bug in which the last character could be deleted from shell traces and from whence when called from a multibyte locale has been fixed. 02-08-01 A bug which could cause a core dump to occur when a shell script is executed while a coprocess is running that has closed the output pipe has been fixed. 02-08-01 A bug in which command completion in multibyte mode could corrupt memory for long command lines has been fixed. 02-06-17 --- Release ksh93n- --- 02-06-17 A bug in which user defined macros could cause a core dump in with MULTIBYTE mode has been fixed. 02-06-17 A bug in which printf format specifiers of the form %2$s were causing a core dump has been fixed. 02-06-17 A bug in which setting stty to noecho mode did not prevent the echoing of characters by ksh when emacs or viraw mode was enabled has been fixed. 02-06-17 A bug in which background job completion could cause the sleep builtin to terminate prematurely has been fixed. 02-06-17 A bug in which the shell could core dump if getopts was called when the OPTIND variable contained a negative value has been fixed. 02-06-10 +The edit mode prompt has been modified to handle escape sequences. 02-06-10 A bug which occurred for interactive shells in which the builtin cat command was used in command substitution on a file whose size was larger than PIPE_BUF has been fixed. 02-06-10 A bug in which the trap on ERR was not being processed when set inside a function has been fixed. 02-06-07 A bug in which function definitions could cause the history count to be decremented by one (and even become negative) has been fixed. 02-06-05 A bug in read in which share mode could be enabled has been fixed. 02-05-28 A bug which could occur when the last command of a script was a case statement and the action selected ended in ;& instead of ;; has been fixed. 02-05-23 A bug with unary + introduced in ksh93k has been fixed. 02-05-07 A bug in substitutions of the form ${var/pattern/string} in which a backslash was inserted in the replacement string when it contained a special pattern character has been fixed. 02-05-01 A bug in the emacs edit mode which occurred in versions compiled for multibyte character sets which occurred when a repeated search was requested after a long line had been returned for the previous search has been fixed. 02-04-02 +vi and emacs edit modes were modified so that tab completion is disabled when invoked from the read built-in. 02-03-26 --- Release ksh93m+ --- 02-03-26 A bug in which \ was not handled correctly when used in file expansion has been fixed. 02-02-18 A bug in which lines beginning with a # were deleted from here documents when the here-document delimiter was followed by a comment has been fixed. 02-12-06 An optimization bug in which ${!x[@]) was treated as invariant in a for loop has been fixed. 02-02-06 A bug in which the ERR trap is not cleared for a script invoked by name from within a function has been fixed. 02-01-08 A bug in which a shell script executed from within a subshell could cause this script to have an invalid pointer leading to a memory fault has been fixed. 02-01-07 +Added here documents of the form <<< word (as per zsh) which is equivalent to << delim\nword\ndelim. 02-01-07 A bug in which the first word of a compound assignment, x=(word ...), was treated as a reserved word has been fixed. 02-01-07 A bug in the handling of \ when noglob was enabled and a substitution of the form ${word op pattern} occurred in the same word has been fixed. 02-01-07 +A compilation option, CMDLIB_BLTIN in the file OPTION, has been added. When this options is set, all commands implemented in libcmd become shell builtin commands by default. 02-01-07 A bug in which builtin foo, where foo is already a builtin would result in the builtin foo getting removed has been fixed. 02-01-07 A bug which the shell executed a command found in the current directory when PATH have no valid directories has been fixed. 01-11-28 The value of $? was not being set when called with exit. 01-11-28 If the last command was of the form (...) and a trap on EXIT or ERR was set, and the command inside () modified the trap, then the original trap wasn't executed. 01-11-26 +The value for 0 is now preceded by the base number when the base was not 10. 01-11-26 +The default has compilation mode has been changes so that viraw mode will always be on. 01-10-31 --- Release ksh93m --- 01-10-31 A for loop optimizer bug for subshells contained within for loops has been fixed. 01-10-16 typeset without arguments no longer outputs variable names that do not have any attributes that are set. 01-10-16 A bug introduced in ksh93l in which assignments specified with the exec built-in were not being expanded properly has been fixed. 01-10-11 An optimization bug in which ${!x) was treated as invariant in a for loop has been fixed. 01-10-11 Unsigned integer variables in bases other than 10 are printed now expand in that base with the base prefix. 01-10-10 A number of typos in the self generating man pages for shell built-ins have been fixed. 01-10-04 The self generated man pages for hist and fc were not working correctly and have been fixed. 01-10-03 Yet another optimizer bug in which shell patterns were treated as invariants has been fixed. 01-09-27 Two bugs relating to multibyte history searches and to find have been fixed. 01-09-27 A bug introduced in ksh93k in which the PATH searching was not restored after running a command with an assignment list has been fixed. 01-09-26 A bug in which a zero filled field was treated as octal when converted to integer has been fixed. 01-09-26 Yet another bug in the optimization of for loops related to recursive functions with break or continue statements has been fixed. 01-09-25 +The exponentiation operator ** was added to the shell arithmetic evaluation. It has higher precedence than * and is left associative. 01-09-25 The code was modified to use the AST multibyte macros and functions for handling multibyte locales. 01-09-25 +The expansion ${parameter:offset:length} now handles negative offsets which cause offsets to be measured from the end. 01-09-25 Some spelling errors in the documentation were corrected. 01-09-24 +The /dev/tcp/host/port and /dev/udp/host/port now allow the ports to be specified by service name. 01-09-24 +The change starting with ksh93g in which the appropriate library path variable is prepended with a corresponding library directory has been modified. With the new method, only the library path defined in the file named .paths in the directory where the executable is found will be modified. See the man page for more details. 01-09-23 +The .fpath file (see ksh93h) is no longer looked for in each directory on the path to locate function directories. The file named .paths is used instead. 01-09-23 A bug in which IFS was not being restored after being changed in a subshell has been fixed. 01-09-16 +With the vi and emacs edit modes, after a list of command or functions is generated with = or M-= respectively, any element from the list can be pasted on the command line by preceding the = or M-= with a numeric parameter specifying the position on the list. 01-09-16 A bug in ksh93l caused command completion not to find aliases and functions. Command listing from the edit mode was presented in reverse order. This has been fixed. 01-09-13 Another bug in the optimization of for loops related to subshells when traps were set has been fixed. 01-09-07 A change in ksh93l caused brace expansion to stop working and this has been fixed. 01-09-04 A bug introduced in ksh93k in which an arithmetic statement within a function that used name references did not follow the reference has been fixed. 01-09-04 A bug introduced in ksh93l in which export -p did not prefix each export with the word export has been fixed. 01-08-29 A bug in multibyte input which occurred when a partial multibyte character was received has been fixed. 01-08-29 A bug introduced in ksh93l which could cause a core dump when an assignment list containing PATH is specified inside command substitution has been fixed. 01-08-09 Another bug in the optimization of for loops in ksh93l caused errors in recursive functions using local variables that contained for loops has been fixed. 01-07-27 A bug in which IFS would be unset after a command substitution inside a here document has been fixed. 01-07-26 To conform to the POSIX standard, if you invoked ksh name, and name does not contain a /, it will first try to run one in the current directory whether it is executable or not before doing a path search for an executable script. Earlier versions first checked for an executable script using the PATH variable. 01-07-23 A bug in which unset -f invoked in a subshell could unset a function defined in the parent has been fixed. 01-07-16 A bug in the optimization of for loops in ksh93l caused name references to be treated as invariants has been fixed. 01-07-09 A bug in which a discipline function applied to a local variable could cause a shell exception has been fixed. Discipline functions can only be specified for global variables. 01-06-18 --- Release ksh93l --- 01-06-18 A bug in assigning integers larger than can be represented as long integers to floating point variables has been fixed. 01-06-18 A bug in the handling of unsigned integers (typeset -ui) has been fixed. 01-06-04 The evaluation of the PS1 prompt no longer affects the value of the $? variable. 01-06-01 A small memory leak from subshells has been fixed. 01-05-22 A bug in which attributes for variables that did not have values would be lost after a subshell has been fixed. 01-05-22 +The %R format has been added to convert a shell pattern into an extended regular expression. 01-05-22 +The escape sequences \e, \cX, \C[.collating-element.], and \x{hex} have been added to ASCII-C strings and to printf format strings. 01-05-20 +Patterns of the form {n}(pattern) and {m,n}(pattern) are now recognized. The first form matches exactly n of pattern whereas, the second form matches from m to n instances of pattern. 01-05-20 +The shell allows *-(pattern), +-(pattern), ?-(pattern), {m,n}-(pattern}, and @-(pattern) to cause the minimal match of pattern to be selected whenever possible rather than the maximal (greedy) match. 01-05-20 +The character class [:word:] has been added to patterns. The word class is the union of [:alnum:] and the character _. 01-05-20 +Inside (...) pattern groups, the \ character is now treated specially even when in an enclosing character class. The sequences, \w, \d, \s are equivalent to the character classes word, digit, and space respectively. The sequences \W, \D, and \S are their complement sets. 01-05-20 +The shell now recognizes pattern groups of the form ~(options:pattern) where options or :pattern can be omitted. Options use the letters + and - to enable and disable options respectively. The option letters g (greedy), i (ignore case) are used to cause maximal matching and to cause case insensitive matching respectively. If :pattern is also specified, these options are only in effect while this pattern is being processed. Otherwise, these options remain in effect until the end of the pattern group that they are contained in or until another ~(...) is encountered. These pattern groups are not counted with respect to group numbering. 01-05-14 When edit completion, expansion, or listing occurs in the middle of a quoted string, the leading quote is ignored when performing the completion, expansion, or listing. 01-05-14 A small memory leak from subshells has been fixed. 01-05-10 A bug in which open files were not restored after a subshell that had used exec to replace a file has been fixed. 01-05-10 +Redirection to a null file name now generates an error message. 01-05-09 The shell now rejects some invalid parameter substitutions that were previously processed in undefined ways. 01-05-09 A bug in which the output of select was not flushed before the read when input did not come from the terminal has been fixed. 01-05-08 A bug in which job ids would not be freed for interactive shells when subshells ran built-ins in the background has been fixed. 01-05-08 +The FPATH variable now requires an explicit . to cause the current directory to be treated as a function directory. 01-05-08 A bug in read -n when echo mode was disabled has been fixed. 01-05-07 A bug in which function definitions could be listed as part of the history has been fixed. 01-04-30 +This release uses a new and often much faster pattern matcher than earlier releases. 01-04-30 +An optimizer now eliminates invariant parameter expansions from for while and until loops. 01-04-30 +The variable .sh.match is set after each pattern match (# % or /) in a variable substitution. The variable .sh.match is an indexed array with element 0 being the complete match. The array is only valid until the next subsequent pattern match or until the value of the variable changes which ever comes first. 01-04-30 +A self generating man page has been added to shcomp. Also, shcomp now stops compiling when it finds an exit or exec command and copies the remainder so that it can be used for standard input. 01-04-30 +The shcomp command was modified so that it can work in an EBCDIC environment and that binary scripts are portable across environments. 01-04-30 A bug in the handling of a trailing : in PATH has been fixed. 01-04-30 A bug in which the builtin version of a command would get invoked even though the full pathname for the command was specified has been fixed. 01-04-30 A bug in which read would lose the last character when reading the last line of a file that did not contain a new-line character has been fixed. 01-04-23 A bug on some systems in which in vi mode the end of file character and end of line character could be swapped has been fixed. 01-04-23 A bug on some systems in which invoking a shell script that did not have execute permission could set the exit value to 127 rather than 126 has been fixed. 01-04-20 A bug in which read -n from a pipe would block if fewer than n characters was received has been fixed. 01-04-09 A bug in which invalid patterns, for example, ) by itself, was not treated as a string has been fixed so that if i=')', then [[ $i == $i ]] is true. 01-04-09 +The shell arithmetic now interprets C character constants. 01-04-09 A bug in which a non-zero return from a function defined with the function reserved word did not trigger the ERR trap or exit with set -e has been fixed. 01-04-02 A bug on some systems, in which characters above 127 were not displayed correctly in vi or emacs edit mode has been fixed. 01-04-02 A bug on some systems, introduced in the 'k' point release, in which the erase character in viraw mode was moving the cursor to the left without erasing the character has been fixed. 01-04-02 On some systems the wcwith() function was returning a wrong value for characters and caused characters to be displayed incorrectly from the shell edit modes. A work around for this problem has been added. 01-03-26 A bug in which valid scripts could produce syntax errors when run with locales that considered characters such as "'" to be space characters has been fixed. 01-03-20 A bug in which an syntax error in an arithmetic expression entered interactively could cause the shell to go into an infinite loop outputting the error message has been fixed. 01-03-10 +ksh93 accepts -l as a synonym for -L in test on systems for which /bin/test -l tests for symbolic links. 01-03-10 A bug in parsing scripts in which { and } are used in place of in and esac in case statements embedded in compound commands has been fixed. Use of { and } for in and esac is obsolete. 01-03-06 A bug in which an argument of the form foo=bar was not being passed correctly to a traced function whose name was foo has been fixed. 01-03-02 Using $(trap -p name) did not print the name of the current trap setting for trap name. 01-02-26 Exported floating point variables gave incorrect results when passing them to ksh88. This has been fixed. 01-02-25 A race condition in which a coprocess which completed too quickly would not allow subsequent coprocesses to start has been fixed. 01-02-25 The 'g' format specifier is now handled by printf. It had inadvertently been omitted. 01-02-20 The + was not being displayed during an execution trace with the += assignment operator. 01-02-19 The error message which occurs when the interpreter name defined on the #! line does not exist is more informative. 01-02-19 A bug in which $0 would not be set correctly when a script with #! was invoked by full pathname from the directory of the script has been fixed. 01-02-19 A shell script did not always pick up tty mode changes made by external commands such as stty which could effect the behavior of read. 01-02-19 The -u, -g, and -k unary tests did not give the correct results when used with negation and this has been fixed. 01-02-05 --- Release ksh93k+ --- 01-02-05 The sequence \ inside $'...' was not incrementing the line count and this has been fixed. 01-02-05 +Modified expansion of "${@-}" so that if no arguments are set it results in null string rather than nothing. 01-02-02 memory leak problem with local variables in functions fixed. 01-01-25 +allow arithmetic expressions with float%int and treat them as ((int)float)%int rather than as an error. 01-01-19 read -n1 was not working and has been fixed. 01-01-17 +ksh now handles the case in which a here document in command substitution $() is terminated by the trailing ). Previously, a new-line was needed at the end of the delimiter word. 01-01-02 A bug in which a KEYBD trap would cause a multi-line token to be processed incorrectly has been fixed. 00-12-10 +Arithmetic integer constants can now have L and U suffices. 00-12-10 A bug in the processing of arithmetic expressions with compound variables when the -n option is on has been fixed. 00-12-08 A bug in M-f and M-b from emacs mode has been fixed. This bug only occurs when ksh93 is compiled without MULTIBYTE enabled. 00-11-29 A bug in which jobs -p would yield 0 for background jobs run in a script has been fixed. 00-11-21 A bug in integer arrays in which the number of elements is incorrect when the ++ operator is applied to a non-existing element has been fixed. For example, integer x; ((x[3]++)). 00-11-20 A timing bug in which the shell could reset the terminal group to the wrong value in the case that the a new process changes the terminal group during startup has been fixed. 00-10-27 --- Release ksh93k --- 00-10-27 Using tab for completion now works only when applied after a non-blank character at the end of the current line. In other case a tab is inserted. 00-10-27 A bug in the emacs edit mode for ^X^E has been fixed. The ^X^E sequence is supposed to invoke the full editor on the current command. 00-10-18 A bug in which expansions of the form ${var//pattern/string} did not work correctly when pattern was '/' or "/" has been fixed. 00-10-18 +The output format for indexed arrays in compound variables has been modified so that it can be used as input. 00-10-18 Assignments with name references (typeset -n) will now implicitly unreference an existing name reference. 00-10-17 A bug the += append operator when a single array element is appended to a variable that is not an array has been fixed. 00-10-16 A bug in which the SIGCONT signal was being sent to each process will kill -0 or kill -n 0 has been fixed. 00-10-12 +The arithmetic evaluation portion has been rewritten to perform a number of optimizations. 00-10-10 A bug in which name prefix matching ${!name.*} was not checking name to see if it was a name reference has been fixed. 00-09-26 A bug in the multibyte version in which the width of for non-printing characters was not correct has been fixed. 00-09-12 +Made changes to get multibyte editing work on UWIN for Windows. 00-09-12 A bug in which multibyte characters would be displayed incorrectly has been fixed. 00-08-08 Removed build dependency on iswprint() and iswalph(). 00-07-20 In some cases the read builtin would read more than a single line from a pipe on standard input and therefore leave the seek position in the wrong location. 00-07-05 +If the directory / is on the path, a / will not be inserted between the directory and the file name during path searching to avoid searching // for systems that treat this specially. 00-06-26 A bug in which on rare occasions wait could return before all jobs have completed has been fixed. 00-06-21 A bug in which backspace did not work correctly during the R replace directive in vi-mode has been fixed. 00-06-12 +Added variable name completion/expansion/listing to the set of completions. Variable name completions begin with $ or "$ followed by a letter. 00-05-09 --- Release ksh93j --- 00-05-09 Modified command substitution to avoid using /tmp files when run on read-only file systems. 00-04-17 +Modified printf to handle '%..Xc' and '%..Xs' options where X is not an alpha character. Previous versions core dumped with this. 00-04-10 +Changes to multibyte editing code were made to use standard ISO C functions rather than methods devised before the standard. 00-04-09 Add %H options to printf to output strings with <"'&\t> properly converted for use in HTML and XML documents. 00-04-07 +Modified getopts builtin to handle \f...\f in usage string by invoking specified function. 00-04-04 Added self generating man pages for bg, fc, fg, disown, jobs, hist, let, ., and ulimit. 00-03-30 +The append operator += has been added and can be used for all assignments, strings, arrays, and compound variables. 00-03-30 +Code was modified in several places to support automatic generation of C locale dictionaries. 00-03-28 A bug in which the set and trap commands invoked with --name type arguments would terminate the invoking script has been fixed. 00-03-27 A bug in which the library path variable was not updated correctly on some systems as described in the 'g' point release has been fixed. 00-03-07 printf now returns a non-zero exit status when one of its arguments cannot be converted to the given type. 00-03-05 The return value and error message for a command that was found on the path but was not executable was set incorrectly. 00-03-05 A prototype for ioctl() was removed from the vi edit mode. 00-01-28 --- Release ksh93i --- 00-01-28 +Most of the built-in commands and ksh itself are now self documenting. Running command --man will produce screen output. Running command --html produces the man page in html format. 00-01-28 +The getopts builtin can process command description strings to produce man pages. 00-01-28 A bug in which a script could terminate when getopts encountered an error when invoked inside a function has been fixed. 00-01-28 When a symbolic link was specified as the name of the script to invoke by name, the value of $0 was set to the real file name rather than the link name in some cases and this has been fixed. 00-01-28 A bug in which the precision given as an argument to printf was not working has been fixed. 99-03-31 --- Release ksh93h --- 99-03-31 +The PATH search algorithm has been modified to look for a file named .fpath in each bin directory and if found, to search for functions in this directory if it cannot find the command in that directory. 99-03-31 +When performing pathname expansion, the shell checks to see whether each directory it reads is case sensitive or not, and performs the matching accordingly. 99-03-31 +The %T format for printing formatted date/time. 99-03-31 +The emacs and vi modes now handle arrow keys when they use standard ANSI escape sequences. 99-03-31 +The TAB key can be used for completion in emacs and viraw mode. 99-03-31 A bug in setting .sh.editchar during the KEYBD trap for the MULTIBYTE option was fixed in release ksh93h. 99-03-31 A bug in shcomp for compilation of unary operators with [[ ... ]] has been fixed. 99-03-31 A bug in which the value of $? was changed when executing a keyboard trap has been fixed. 99-03-31 The handling of SIGCHLD has been changed so that the trap is not triggered while executing trap commands to avoid recursive trap calls. 99-03-31 A bug in which a local variable in a function declared readonly would generate an error when the function went out of scope has been fixed. 99-03-31 A bug in which \ entered from the keyboard with the KEYBD trap enabled has been fixed. 99-03-31 The error message for a misplaced ((, for example print ((3), was often garbled and has been fixed. 99-03-31 A bug in the KEYBD trap in which escape sequences of the form [#~ were not being handled as a unit has been fixed. 99-03-31 A bug in which ksh would consider expressions like [[ (a) ]] as syntax errors has been fixed. 99-03-31 A function defined as foo() without a function body was not reported as a syntax error. 99-03-31 A bug in which ksh could run out of file descriptors when a stream was repeatedly opened with exec and read from has been fixed. 98-04-30 --- Release ksh93g --- 98-04-30 +The pipefail option has been added. With pipefail enabled, a pipeline will not complete until all commands are complete, and the return value will be that of the last command to fail, or zero if all complete successfully. 98-04-30 +The name-value pair library uses the cdt library rather than the hash library. This change should be transparent to applications. 98-04-30 +On the U/WIN version for Window 95 and Windows NT, when a directory beginning with a letter followed by a colon is given to cd, it is assumed to be an absolute directory 98-04-30 +When an executable is found on a given path, the appropriate library path variable is prepended with a corresponding library directory. 98-04-30 A bug in which a name reference could be created to itself and later cause the shell to get into an infinite loop has been fixed. 98-04-30 A bug in shcomp relating to compound variables was fixed. 98-04-30 A bug introduced in ksh93e in which leading 0's in -Z fields caused the value to be treated as octal for arithmetic evaluation has been fixed. 98-04-30 A bug when a name reference with a shorter name than the variable it references was the subject of a compound assignment has been fixed. 98-04-30 A bug which in which assignment to array variables in a subshell could affect the parent shell has been fixed. 98-04-30 read name?prompt was putting a 0 byte at the end of the prompt on standard error. 98-04-30 A bug in [[ string1 > string2 ]] when ksh was run with -x has been fixed. 98-04-30 A bug in which the escape character was not processed correctly inside {...} when brace expansion is enabled has been fixed, for example {\$foo}. 98-04-30 A bug in line continuation in here-documents has been fixed. 98-04-30 The default base when not specified with typeset -i is 10 in accordance with the documentation. Previously, the value was determined by the first assignment. 98-04-30 A parsing bug in which a # preceded alphanumeric characters inside a command substitution caused a syntax error to be reported has been fixed. 98-04-30 A bug in which a decimal constant represented as 10#ddd where ddd was more than five digits generated a syntax error has been fixed. 98-04-30 A bug in here document expansion in which ${...} expansions were split across buffer boundaries has been fixed. 98-04-30 +The sh_fun() function now takes third argument which is an argument list for the invoked discipline function or built-in. 98-04-30 +A callback function can be installed which will give notification of file duplications and file closes. 98-04-30 When ksh is compiled on systems that do not use fork() current option settings where not propagated to subshells. 97-06-30 --- Release ksh93f --- 97-06-30 +Hostnames in addition to host addresses can be given in /dev/tcp/host/port virtual file names. 97-06-30 File name completion and expansion now quotes special characters in file names from both emacs and vi edit modes. 97-06-30 An empty for list behave like a for list with null expansions. It produces a warning message with sh -n. 97-06-30 +The code has been modified to work with EBCDIC as well as ASCII. 97-06-30 A bug which would cause the secondary prompt to be displayed when a user entered a literal carriage return has been fixed. 97-06-30 A bug which caused ksh read -s name to core dump was fixed. 97-06-30 A bug with the expansion of \} and \] inside double quoted strings that also contained variable expansions has been fixed 97-06-30 Changes in the ksh93e point release caused autoload functions invoked from within command substitution to fail. This has been fixed. 97-06-30 A bug in the processing of here-documents that could prevent variable substitution to occur after $(...) command substitution for long here documents has been fixed. 97-06-30 A bug caused by a race condition that could cause SIGTERM to be ignored by a child process has been fixed. 97-06-30 A bug which prevented the startup of a coprocess immediately after killing a running coprocess has been fixed. 97-06-30 ulimit foobar, where foobar is not an arithmetic expression, now gives an error message as it did with ksh88 instead of setting the file size limit to 0. 97-06-30 A bug which could cause an interactive shell to terminate when the last process of a pipeline was a POSIX function was fixed. 97-06-30 A bug which could cause command substitution of a shell script to core dump has been fixed. 97-06-30 A security hole was fixed in suid_exec. 97-06-30 Arithmetic functions such as pow() that take more than one argument, did not work if arguments other than the first contained parenthesized sub-expression. 97-06-30 The error message from a script containing an incomplete arithmetic expression has been corrected. 97-06-30 A bug which caused a core dump on some machines when the value of a name reference contained a positional parameter and the name reference was not defined inside a function has been fixed. 97-06-30 Arithmetic expressions now correctly handle hexadecimal constants. 97-06-30 A bug in which integer variables could be expanded with a leading 10# when declared with typeset -i multiple times has been corrected. 97-06-30 A bug in which IFS wasn't correctly restored when set within command substitution has been fixed. 97-06-30 The _ character is now considered as part of a word with the M-f and M-b emacs directives as it was in ksh88. 97-06-30 A bug in brace pattern expansions that caused expressions such as {foo\,bar,bam} to expand incorrectly have been fixed. 96-07-31 --- Release ksh93e --- 96-07-31 +The math functions, atan2, hypot, fmod, and pow were added. 96-07-31 +When a shared library is loaded, if the function lib_init() is defined in the library, it is invoked the first time that the library is loaded with builtin -f library. 96-07-31 The k-shell information abstraction database option, KIA, has been revamped. 96-07-31 Empty command substitutions of the form $() now work. whence -v foo now gives the correct result after calling builtin -d foo. 96-07-31 A bug in right to left arithmetic assignment for which the arithmetic expression (( y = x = 1.5 )) did not yield 1 for y when x was declared typeset -i was fixed. 96-07-31 printf has been fixed to handle format containing \0 and/or \0145 correctly. In addition, characters following %b in the format string are no longer displayed when the operand contains \c. 96-07-31 A bug in printf that could cause the %E format to produce unnormalized results has been fixed. 96-07-31 A bug which causes some arithmetic expressions to be incorrectly evaluated as integer expressions rather than floating point has been fixed. 96-07-31 Functions defined inside a subshell no longer remain defined when the subshell completes. 96-07-31 The error message from sh -c ';echo foo' has been corrected. 96-07-31 The format for umask -S has been changed to agree with the specification in the POSIX standard. 96-07-31 A bug that caused side effects in subscript evaluation when tracing was enabled for subscripts using ++ or -- has been fixed. 96-07-31 To conform to the POSIX standard getopts has been changed so that the option char is set to ? when it returns with a non-zero exit status. 96-07-31 The handling of \} inside ${name...} has been fixed so that the \ quotes the }. 96-07-31 A bug that caused the read builtin to resume execution after processing a trap has been fixed. 96-07-31 [[ -s file ]] has been fixed so that if file is open by ksh, it is flushed first. 96-07-31 In some cases attributes and sizes for non exported variables weren't being reset before running a script. 96-07-31 The value of TMOUT was affected by changes make to it in a subshell. 96-07-31 The jobs command did not reflect changes make by sending the CONT signal to a command. 96-07-31 The error message for ksh -o unknown was incorrect. 96-07-31 Functions invoked as name=value name, did not use values from the calling scope when evaluating value. 96-07-31 A bug in which the shell would re-execute previously executed code when a shell script or coprocess was run in the background has been fixed. 96-07-31 A bug in which an empty here-document would leave a file descriptor open has been fixed. 96-07-31 A bug in which $(set -A array ...) would leave a side effect has been fixed. 96-07-31 A discipline function for a global variable defined within a function defined with the function keyword, incorrectly created a local variable of the same name and applied the discipline to it. 95-08-28 --- Release ksh93d --- 95-08-28 The \ character was not handled correctly in replacement patterns with ${x/pattern/replace}. 95-08-28 A bug with read in which the line did not end with a new-line has been fixed. 95-08-28 A bug in file name generation which sometimes appended a . for filenames that ended in / has been fixed. 95-08-28 +If a process is waited for after a status has been returned by a previous wait, wait now returns 127. 95-08-28 A bug with hist (fc) -e which prevented a command to re-executed after it had been edited has been fixed. 95-08-28 A bug which prevented quoting from removing the meaning of unary test operators has been fixed. 95-08-28 A bug with typeahead and KEYBOARD traps with the MULTIBYTE option set has been fixed. 95-08-28 +Builtin functions can take a third argument which is a void*. 95-08-28 The nv_scan() function can restrict the scope of a walk to the top scope. 95-04-31 --- Release ksh93c --- 95-04-31 The expansion of "$@" was incorrect when $1 was the null string. 95-04-31 A bug which could incorrectly report a syntax error in a backquoted expression when a $ was preceded by \\ has been fixed. 95-04-31 A bug which prevented the shell from exiting after reporting an error when failing to open a script has been fixed. 95-04-31 A bug that could lead to memory corruption when a large here document that required parameter or command substitution was expanded has been fixed. 95-04-31 A bug that could cause a core dump on some systems after ksh detected an error when reading a function has been fixed. 95-04-31 A bug which could cause a coprocess to hang when reading from a process that has terminated has been fixed. 95-04-31 A bug which caused a script to terminate when set -e was on and the first command of and && or || list failed has been fixed. 95-04-31 A bug with here documents inside $(...) when the delimiter word is an identifier has been fixed. 95-04-31 A bug which caused $0 to display the wrong value when a script was invoked as an argument to the . command and the eval command has been fixed. 95-04-31 A bug that could cause the built-in sleep to hang has been fixed. 95-04-31 A bug introduces in 12/28/93b which caused the backslash to be removed when it was followed by digit inside double quotes in some instances has been fixed. 95-04-31 A bug which could cause a core dump if ksh was invoked with standard input closed has been fixed. 95-04-31 A bug which could cause a core dump if typeset -A was specified for an existing variable has been fixed. 95-04-31 Variables that were unset but had attributes such as readonly and export were not listed with readonly, export and typeset. 95-04-31 Several problems with signals have been fixed. 95-04-31 A bug which prevented ulimit -t from working has been fixed. Also, a bug in which failed ulimits could cause a core dump has also been fixed. 95-04-31 A bug in expansion of the form ${name/#pattern/string} and ${name/%pattern/string} has been fixed. 95-04-31 A bug which caused read -r on a line that contained only blanks to get a non-null value has been fixed. 95-04-31 A bug introduced in the 'a' point release in which ${x='\\'} expanded to \ when x was unset has been fixed. 95-04-31 A bug which prevented a trap on EXIT from being executed when the last command in a script was a function invocation has been fixed. 95-04-31 A bug which caused an interactive shell ignore input when standard error was redirected to a file with exec, and then restored with exec 2>&1 has been fixed. 95-04-31 An interactive shell turns on monitor mode even when standard error has been redirected to a file. 95-04-31 A bug which could cause standard input to be incorrectly positioned for the last command of a script has been fixed. 95-04-31 A bug in the edit modes which allowed walking back in the history file for more than HISTSIZE commands has been fixed. 95-04-31 A bug which could cause a core dump if variable TMPDIR was changed between two command substitutions has been fixed. 95-04-31. A bug which prevented a trap on EXIT from being cleared has been fixed. 95-04-31 A bug fixed for the v directive in vi MULTIBYTE has been fixed. 95-04-31 Code to for IFS handling of multibyte characters has been added. 95-04-31 The displaying of multibyte strings in export, readonly, typeset, and execution traces has been fixed. 95-04-31 Variables inside functions are now statically scoped. The previous behavior was never documented. 95-04-31 Variables inside functions are now statically scoped. The previous behavior was never documented. 95-04-31 A few changes have been made to the name-value library that affect built-ins that use disciplines. The changes allow disciplines to be shared by variables and should make it possible to add new disciplines without recompilation. 95-04-31 +The name-value library interface has undergone significant change for this revision. See the new nval.3 man page. 94-12-31 --- Release ksh93b --- 94-12-31 +Variables inside functions are now statically scoped. The previous behavior was never documented. 94-12-31 +If IFS contains two consecutive identical characters belonging to the [:space:] class, then this character is treated as a non-space delimiter so that each instance will delimit a field. For example, IFS=$'\t\t' will cause two consecutive tabs to delimit a null field. 94-12-31 +The getopts command has a -a name option that specifies a name that will be used for usage messages. 94-12-31 A bug which caused unset RANDOM to dump core has been fixed. 94-12-31 A bug which prevented return for terminating a profile or ENV file has been fixed. 94-12-31 A bug which prevented standard input from being directed to /dev/null for background jobs when monitor mode was turned off has been fixed. 94-12-31 Statements of the form typeset -options var[expr]=value did not perform substitutions on expr as expected. 94-12-31 A bug which prevented the shell from sending a HUP signal to some background jobs that were not disowned has been fixed. 94-12-31 A bug which allowed a script to trap signals that are ignored at the time that the shell was invoked by exec has been fixed. 94-12-31 A bug which could cause a core dump when a discipline function was unset within a discipline was fixed. 94-12-31 The typeset builtin now accepts a first argument of + or - for compatibility with ksh88. 94-12-31 For compatibility with ksh88, the results of expansions of command arguments will treat the extended character match characters ()|& as ordinary characters. 94-12-31 A bug which caused read to fail on a file that was open for read/write with <> when the first operation was print or printf has been fixed. 94-12-31 When a job is suspended, it is put on the top of the job list as required by the POSIX standard. 94-12-31 The value of OPTARG when an option that required an argument but didn't have one was incorrect in the case the option string began with a :. 94-12-31 A bug which caused the terminal to get into a bad state with some KEYBD traps in vi-mode has been fixed. 94-12-31 A bug which caused an invalid trap to cause a script to terminate, rather than just return an error, has been fixed. 94-12-31 Backreferencing sub-expressions in patterns and replacement strings now works. 94-12-31 A bug in chmod which caused the -R option to fail has been fixed. 94-12-31 +More signal names have been added for Solaris 94-06-30 --- Release ksh93a --- 94-06-30 An expansion bug which causes portions of a word after a $((...)) expansion that contains a nested $var expansion to be lost has been fixed. 94-06-30 A bug that caused a core dump when a script that did not have PWD set and did a cd inside command substitution has been fixed. 94-06-30 A bug which caused a core dump on some machines when the LANG variable was assigned to has been fixed. 94-06-30 A bug which incorrectly handled set disciplines that performed arithmetic evaluation when the discipline was called from the arithmetic evaluator has been fixed. 94-06-30 A bug caused by an EXIT trap inside a function that was executed in a subshell was fixed. 94-06-30 If foo is a function, and not a program, then command foo now reports that foo isn't found rather than invoking foo. 94-06-30 The previous version incorrectly listed -A as an invocation option. The -A option is only for set. 94-06-30 A bug was fixed which caused ksh to loop when execution trace was enabled and the PS4 prompt required command substitution. 94-06-30 A bug which could cause the job control switch character to be disabled when a script that enabled monitor mode terminated was fixed. 94-06-30 A bug in the macro expansion global replacement operator //, when the pattern began with a [ or +( has been fixed. 94-06-30 A bug which prevented ~ expansion from occurring when it was terminated with a colon inside an assignment has been fixed. 94-06-30 A bug in the dot command which prevented autoload functions from working has been fixed. 94-06-30 A bug which caused a variable to be unset if the its value were expanded inside a set discipline has been fixed. 94-06-30 Whence -a now longer reports that a defined function is undefined. 94-06-30 A bug on some systems in which $0 would be incorrect in scripts invoked by name has been fixed. 94-06-30 Here documents with an empty body now work. 94-06-30 A bug which disabled argument passing and resetting of options for a script invoked by name inside a function has been fixed. 94-06-30 A bug in which an EXIT trap set the caller of a function would be executed if a command called inside a function was not found has been fixed. 94-06-30 A bug which allowed a script to trap signals that are ignored at the time that the shell was invoked has been fixed. 94-06-30 A bug which caused 2<&1- when applied to a shell built-in to leave standard input closed has been fixed. 94-06-30 A bug which caused the shell to incorrectly parse $() command substitutions with nested case statements has been fixed. ksh-1.0.0-beta.2/src/cmd/ksh93/RELEASE88000066400000000000000000000472221415700074400170350ustar00rootroot00000000000000This file is of historic interest. For recent changes in both ksh 93u+m and the accompanying libraries, see the file NEWS in the top-level directory. ____ This is a list of changes that have been made since the 11/16/88 version of ksh. 1. New features in 12/28/93 a. Associative arrays. The new version of ksh supports both associative arrays and the older indexed arrays with the same array syntax. A new -A option of typeset is used to declare an array to be associative. As with indexed arrays, $name is equivalent to ${name[0]}. The prefix operator ! was added to the parameter expansion syntax to expand to the list of indices. For example, ${!name[@]} expands to the list of array indices for variable name. b. Several additions have been made to shell arithmetic: 1. The shell now performs floating point arithmetic. The typeset options -F and -E have been added for floating point and scientific notation respectively. 2. The prefix and postfix ++ and -- operators. 3. The comma and ?: operators. 4. The math library functions. 5. An arithmetic for statement of the form for ((expr1; expr2; expr3)) do ... done 6. Integer arithmetic extended up to base 64. c. Some additions to the macro expansion syntax have been made to specify substrings and sub-arrays: 1. ${name:expr} expands to the substring of ${name} starting at the character position defined by arithmetic expression expr. 2. ${name:expr1:expr2} expands to the substring of ${name} starting at expr1 and consisting of at most expr2 characters. 3. ${name[@]:expr} expands to the values of ${name[@]} starting at the element defined by arithmetic expression expr. 4. ${name[@]:expr1:expr2} expands to at most expr2 values of ${name} starting at expr1. 5. ${@:expr} expands the positional parameters starting at expr. 6. ${@:expr1:expr2} expands to at most expr2 positional parameters starting at expr1. 7. ${!name} expands to the name of the variable named by name. It will expand to name unless name is a reference variable. 8. ${!name[sub]} expands to the name of the subscript of the given variable. If sub is @ or * the list of subscripts is generated. 9. ${!prefix*} and ${!prefix@} expand to the list of variable names beginning with prefix. 10. The substring operators, # and % can be now be applied with aggregates (@ or *) and are applied to each. 11. ${name/pattern/string} expands to the value of name with the first occurrence of pattern replaced by string. With aggregates (@ or *) this operation is applied to each. 12. ${name/#pattern/string} Same as above but the pattern to be replaced must match at the beginning. 13. ${name/%pattern/string} Same as above but the pattern to be replaced must match at the end. 14. ${name//pattern/string} expands to the value of name with each occurrence of pattern replaced by string. With aggregates (@ or *) this operation is applied to each. d. The name space for variables has been extended. The character '.' can be used at the beginning of a name, and to separate identifiers within a name. However, to create a name of the form, foo.bar, the variable foo must exist. The namespace starting with .sh is reserved for shell implementation variables. Exported variables cannot contain a '.'. e. Compound assignments. The assignment syntax, varname=value, has been extended to allow assignments of the form varname=(assignment_list). As elsewhere in the shell spaces or tabs are optional around the parentheses, and no space is permitted between the varname and the =. The assignment_list can be one of the following: 1. A list of words. In this case each word is expanded as in a for list and the resulting items become elements of the indexed array varname. 2. A list of subscript assignments in the form [subscript]=value. In this, these elements become elements of the associative array varname. 3. A list of assignments; simple or compound. In this case, each assignment is made to varname.name, where name is the name of the enclosed assignment. 4. Assignments in the form of readonly or typeset statements. In this case each assignment is made as in 3 above, and the attributes are given to the corresponding variable. In case 3 and 4 above, the value of "$varname" after the above assignment is (assignment_list), where the assignment_list produced would reproduce all of the variables under varname.*. f. Function names of the form variable.action (called discipline functions) can be defined where variable is any valid variable name and action is get, set, or unset. The function variable.get is invoked each time the variable is referenced. The set discipline is invoked each time the variable is assigned to. The unset discipline is invoked when a variable is unset. The new variables .sh.name, .sh.subscript, and .sh.value are defined inside the function body. Other shell extensions may have their own set of discipline functions. g. The compound command !, which negates the return value of the following pipeline, has been added. h. On systems that support dynamic loading with dlopen(), it is now possible to add built-in commands at runtime with the builtin command named 'builtin'. i. The following builtins have been added: 1. command name [ ... ] 2. sleep [decimal-seconds] 3. builtin [-ds] [-f file] [name...] 4. getconf name [pathname] 5. disown [job...] j. An addition format for literal strings, $'....' can be used where ever literal strings are valid. The string inside the single quotes will be converted using the ANSI C escape conventions. Additionally, the escape sequence \E expands to the escape character (default \033) whenever ANSI C escape sequences are recognized. k. A typeset -n option has been added which causes the value of a variable to be treated as a reference to another variable so that variables can be indirectly named. For example, if $1 contains the name of a variable, then typeset -n foo=$1 causes the variable foo to be synonymous with the variable whose name is $1. A builtin alias, nameref='typeset -n' has been added to aid mnemonics. Reference names cannot contain a '.'. Whenever that portion of a variable up to the first '.' matches a reference name, the reference value is substituted. For example, with nameref foo=.top, then ${foo.bar} is equivalent to ${.top.bar}. When used as the index of a for or select loop, each assignment causes a new name reference to occur. l. The KEYBD trap has been added which is triggered when a key or escape sequence is typed while reading from the keyboard in an edit mode. This, combined with some new variables makes it possible to program your key bindings in ksh. m. New variables have been added: 1. FIGNORE defines a set of file names to be ignored in each directory when performing pathname expansion, replacing the rule that requires that a leading . be matched explicitly. 2. Variable sh.edchar contains the value of the keyboard character that has been entered when processing a KEYBD trap. If the value is changed as part of the trap action, then the new value replaces the key or keys that caused the trap. 3. Variable sh.edcol is set to the character position of the cursor within the input buffer during a KEYBD trap. 4. Variable sh.edmode is set to the escape character when in vi insert mode. 5. Variable sh.edtext is set to the contents of the input buffer during a KEYBD trap. 6. HISTEDIT is checked before FCEDIT. FCEDIT is obsolete. 7. HISTCMD is the number of the current command in the history file. 8. Variable .sh.version is set to the version string for this shell. 9. Variable .sh.name is set to the name of the variable that was referenced or assigned to when executing a get or set discipline function. 10. Variable .sh.subscript is set to the subscript for the variable that was referenced or assign to when executing a get or set discipline function. 11. Variable .sh.value is set to the new value for the variable that was assigned to when executing the set discipline function. n. New invocation and set -o options have been added: 1. set -o notify (or set -b) causes background completion messages to be displayed as soon as the job completes. 2. There is a compile time option named KIA which enables creation of a relational database for commands, variables and functions defined and referenced by a script. The option -I , causes the database to be generated in . The database format can be queried via the cql command. o. ksh93 can read and evaluate pre-compiled scripts generated by a separate program called shcomp. p. More work on internationalization has been added: 1. The decimal point character is processed per locale 2. A $ can be placed in front of each string to indicate that the string needs translation but is otherwise ignored. This means that if a message catalog of all $"..." strings is generated, then a program such as print $"hello world" could display "bonjour monde" in the French locale. q. Backreferences have been added to pattern matching. The sequence \d, where d is a digit from 1-9, matches the same string as the d-th previous parenthesis group. Backreferences can be used within patterns, and within replacement strings with any of the ${name/...} operators. 2. Changes made in 12/28/93 a. The output format of many commands has changed as follows: 1. System error messages are displayed whenever a failure is caused by a system call. 2. The exit status has changed in many cases: a. USAGE messages cause an exit status of 2. b. Commands not found cause exit - 127. c. Command found, but not executable - 126. d. Terminated because of signal - 256+sig 3. The output of values from built-ins that contain special characters are quoted in a manner that then can be re-input. 4. The trace output puts quotes around the output so that it can be reused as input. 5. The output for trap is in a format that can be reinput to the shell to restore the traps. 6. kill -l lists the signal names without numbers as required by the POSIX standard. b. The following changes have been made to shell functions: 1. The semantics of functions declared with name() has changed to conform with the IEEE-POSIX 1003.2 standard. In particular, these functions are executed in a dot script environment rather than a separated function environment so that there are no local variables and no scoping for traps. 2. Functions declared as function name, preserve the old ksh semantics can be also used as the first argument to the dot (.) command to have them executed in a dot script environment. c. The command search rules have changed as follows: 1. Special built-ins (those with a dagger in front of them) are executed first. 2. Functions are executed next. 3. Other built-ins that do not require an executable version (for example cd and read) come next. 4. If the command name contains a slash, the pathname corresponding to the command name is executed. 5. If name corresponds to a previously encountered pathname on the PATH variable, the corresponding command is executed. 6. If the command name does not contain a slash, then the PATH variable is used to find an executable by that name. If the directory that the command is found is also contained in the FPATH variable, then the command treated as a function. If the shell has a built-in version of the command corresponding to this command, then the built-in version of this command is executed. Otherwise, the shell remembers that pathname corresponding to this command name and executes this pathname. 7. If the name is not found on PATH, then the directories in FPATH are searched. If found, then the command is executed as a function. d. Built-in commands options now conform to the IEEE-POSIX 1003.2 conventions with some additions. In particular, name -? will now print a Usage line for name, except for true, false, colon, login, newgrp, echo, [, and command. e. Tilde expansion is now performed as part of the word expansions. The effect of this is that if word begins with ~ in ${name op word}, it will be expanded unless escaped. f. Pathname expansion is no longer performed on redirection words unless the shell is interactive. g. Changes to shell and options: 1. The -n option has been enhanced to produce more warning and portability messages. 2. The -C option is equivalent to -o noclobber. Files are created with O_EXCL when -C is on. h. The following changes have been made to [[ ... ]]: 1. A string by itself is equivalent to -n string. 2. -e has been added as equivalent to -a. 3. == has been added as equivalent =. 4. -a and = are now considered obsolete. 5. Arithmetic comparisons are now considered obsolete. i. kill has been changed as follows: 1. Signal names can be upper case or lower case. 2. Numerical arguments to kill -l cause the given signal names to be displayed. 3. String arguments to kill -l cause the given signal numbers to be displayed. 4. Synopsis changed for getopts conformance. j. print has a -f format option which is equivalent to the IEEE POSIX printf. Both print -f format, and printf have the following extensions from IEEE POSIX: 1. Floating point formats are supported. 2. Size and precision specifications can be *. 3. The %d option can take an argument after precision to specify the base that the number will be displayed. 4. A %q format can be used to output a string quoted so that it can be re-input to the shell. 5. A %P format can be used to output the shell pattern which corresponds to the give extended regular expression. 6. For numerical fields, the arguments can be arithmetic expressions which will be evaluated. 7. The %n format works as described in ANSI C. k. The following changes have been made to fc: 1. It has been renamed hist. fc is now a predefined alias. 2. hist uses ${HISTEDIT:-$FCEDIT}. FCEDIT is obsolete. 3. A new -s option is equivalent to the obsolete -e -. 4. If the first argument refers to a command earlier than the first accessible command, it now implies the first accessible command, so that hist -l 1 lists all accessible history commands. l. The dot command (.) has changed as follows: 1. The argument can be the name of a function declared as function name. The function will execute without creating a new scope. 2. If there are arguments to the given script or function, the positional parameters are restored to their original value when . completes. m. The read built-in has been changed as follows: 1. A -A option to read has been added to allow the fields to be read into an indexed array. 2. A -t n option has been added which causes read to timeout after n seconds when reading from a slow device. 3. A -d char option has been added which causes the read to terminate at char rather than at new-line. n. The trap command has been changed as follows: 1. Trap names can be either upper case or lower case. 2. Trap -p only causes the specified trap values to be displayed. 3. The value of trap in a subshell will be the value in the parent shell until a call to trap which changes the trap settings has been made. Thus, savetraps=$(trap) works as required by the POSIX standard. o. The exec command has been extended as follows: 1. The -c option clears the environment first. 2. The -a name option sets argv[0] to name for the program. p. true and false are built-ins, not aliases to built-ins. q. test has been modified to conform to the IEEE-POSIX 1003.2 standard when there are three or less arguments. r. umask -S option displays the mask in a symbolic format. s. wait now returns the correct exit status of any previous background job that has not been waited for, not just the most recent one. t. The whence built-in has an option -a which causes all uses for the given command name to be reported. u. unalias has -a option to clear all the aliases. v. The times built-in command has been removed. The time reserved word, without a command, gives time cumulative time for the shell and its children. A built-in alias for times should enable scripts using times to continue to run. w. Command substitution and arithmetic substitution will now be performed for PS1, ENV, and PS4 evaluation in addition to parameter expansion. x. The SECONDS variable now displays elapsed time in floating point seconds with 3 places after the decimal point by default. y. The getopts built-in now handles the complete libast optget functionality. If any errors have occurred with getopts when it has reached the end of arguments, then the Usage message will be generated from the option string and the exit status from getopts will be 2 rather than 1. The usage message will be stored in the OPTARG variable if the option string contains a leading colon; otherwise it will be printed on standard error automatically. z. THE ENV file is only processed for interactive shell invocations. In addition, the -x attributes for aliases and functions is ignored. aa. The built-in edit modes have been changed as follows: 1. The pathname completion and pathname listing options now perform command completion and command listing when applied to a word in the command position. 2. In emacs mode ^N as the first related command after the prompt will move to the next command relative to the last known history position. 3. In emacs mode, successive kill and delete commands will accumulate their data in the kill buffer, by appending or prepending as appropriate. This mode will be reset by any command not adding something to the kill buffer. 4. The control-T of emacs mode has been changed to behave like control-T in gnu-emacs. bb. The TMOUT variable also sets a limit for select timeouts and default timeouts for read. 4. The source code has undergone significant modification. a. Much of the code has been rewritten, In many cases this has resulted in significant performance improvement. b. The code is organized differently. See the README files for more details. c. Most configuration parameters now get generated using the FEATURE mechanism of nmake. Other options are set in the OPTIONS file. c. There are several new compile time options. See the README file for details. Some of the old ones have been removed. d. The install script is a Mamfile that is generated by nmake and processed by a script that comes with the distribution. e. There are far fewer global names. This should make it must easier to add built-in commands without worrying about conflicts. f. The code uses the sfio library which makes it possible to mix with stdio. g. The code is written in ANSI C with full prototypes. The code is based on the IEEE POSIX 1003.1 standard. The code can be compiled with K&R C and with C++ by using the ANSI cpp that comes with nmake or running the code through the proto filter before pre-processing. This happens automatically with our shipping system. h. There is a programming interface for capturing references and assignment to shell variables. It is also possible to intercept variable creation and supply the array processing function for that variable. See nval.3 for a description. ksh-1.0.0-beta.2/src/cmd/ksh93/RELEASE93000066400000000000000000000536521415700074400170350ustar00rootroot00000000000000This file is of historic interest. For recent changes in both ksh 93u+m and the accompanying libraries, see the file NEWS in the top-level directory. ____ This is a list of changes that have been made since the 12/28/93 version of ksh. 1. New features in 12/28/93b a. If IFS contains two consecutive identical characters belonging to the [:space:] class, then this character is treated as a non-space delimiter so that each instance will delimit a field. For example, IFS=$'\t\t' will cause two consecutive tabs to delimit a null field. b. The getopts command has a -a name option that specifies a name that will be used for usage messages. 2. New features in 12/28/93e a. The math functions, atan2, hypot, fmod, and pow were added. b. When a shared library is loaded, if the function lib_init() is defined in the library, it is invoked the first time that the library is loaded with builtin -f library. 3. New features in 12/28/93f a. Hostnames in addition to host addresses can be given in /dev/tcp/host/port virtual file names. b. File name completion and expansion now quotes special characters in file names from both emacs and vi edit modes. 4. New features in 12/28/93g a. The pipefail option has been added. With pipefail enabled, a pipeline will not complete until all commands are complete, and the return value will be that of the last command to fail, or zero if all complete successfully. b. When an executable is found on a given path, the appropriate library path variable is prepended with a corresponding library directory. 5. New features in 12/28/93h a. The PATH search algorithm has been modified to look for a file named .fpath in each bin directory and if found, to search for functions in this directory if it cannot find the command in that directory. b. When performing pathname expansion, the shell checks to see whether each directory it reads is case sensitive or not, and performs the matching accordingly. c. The %T format for printing formatted date/time. 6. New features in 12/28/93i a. Most of the built-in commands and ksh itself are now self documenting. Running command --man will produce screen output. Running command --html produces the man page in html format. b. The getopts builtin can process command description strings to produce man pages. 7. Bugs fixed in 12/28/93a for default OPTIONS a. An expansion bug which causes portions of a word after a $((...)) expansion that contains a nested $var expansion to be lost has been fixed. b. A bug that caused a core dump when a script that did not have PWD set and did a cd inside command substitution has been fixed. c. A bug which caused a core dump on some machines when the LANG variable was assigned to has been fixed. d. A bug which incorrectly handled set disciplines that performed arithmetic evaluation when the discipline was called from the arithmetic evaluator has been fixed. e. A bug caused by an EXIT trap inside a function that was executed in a subshell was fixed. f. If foo is a function, and not a program, then command foo now reports that foo isn't found rather than invoking foo. g. The previous version incorrectly listed -A as an invocation option. The -A option is only for set. h. A bug was fixed which caused ksh to loop when execution trace was enabled and the PS4 prompt required command substitution. i. A bug which could cause the job control switch character to be disabled when a script that enabled monitor mode terminated was fixed. j. A bug in the macro expansion global replacement operator //, when the pattern began with a [ or +( has been fixed. k. A bug which prevented ~ expansion from occurring when it was terminated with a colon inside an assignment has been fixed. l. A bug in the dot command which prevented autoload functions from working has been fixed. m. A bug which caused a variable to be unset if the its value were expanded inside a set discipline has been fixed. n. Whence -a now longer reports that a defined function is undefined. o. A bug on some systems in which $0 would be incorrect in scripts invoked by name has been fixed. p. Here documents with an empty body now work. 1. A bug which disabled argument passing and resetting of options for a script invoked by name inside a function has been fixed. r. A bug in which an EXIT trap set the caller of a function would be executed if a command called inside a function was not found has been fixed. s. A bug which allowed a script to trap signals that are ignored at the time that the shell was invoked has been fixed. t. A bug which caused 2<&1- when applied to a shell built-in to leave standard input closed has been fixed. u. A bug which caused the shell to incorrectly parse $() command substitutions with nested case statements has been fixed. 8. Bugs fixed in 12/28/93b for default OPTIONS a. A bug which caused unset RANDOM to dump core has been fixed. b. A bug which prevented return for terminating a profile or ENV file has been fixed. c. A bug which prevented standard input from being directed to /dev/null for background jobs when monitor mode was turned off has been fixed. d. Statements of the form typeset -options var[expr]=value did not perform substitutions on expr as expected. e. A bug which prevented the shell from sending a HUP signal to some background jobs that were not disowned has been fixed. f. A bug which allowed a script to trap signals that are ignored at the time that the shell was invoked by exec has been fixed. g. A bug which could cause a core dump when a discipline function was unset within a discipline was fixed. h. The typeset builtin now accepts a first argument of + or - for compatibility with ksh88. i. For compatibility with ksh88, the results of expansions of command arguments will treat the extended character match characters ()|& as ordinary characters. j. A bug which caused read to fail on a file that was open for read/write with <> when the first operation was print or printf has been fixed. k. When a job is suspended, it is put on the top of the job list as required by the POSIX standard. l. The value of OPTARG when an option that required an argument but didn't have one was incorrect in the case the option string began with a :. m. A bug which caused the terminal to get into a bad state with some KEYBD traps in vi-mode has been fixed. n. A bug which caused an invalid trap to cause a script to terminate, rather than just return an error, has been fixed. o. Backreferencing sub-expressions in patterns and replacement strings now works. p. A bug in chmod which caused the -R option to fail has been fixed. 9. Bugs fixed in 12/28/93c for default OPTIONS a. The expansion of "$@" was incorrect when $1 was the null string. b. A bug which could incorrectly report a syntax error in a backquoted expression when a $ was preceded by \\ has been fixed. c. A bug which prevented the shell from exiting after reporting an error when failing to open a script has been fixed. d. A bug that could lead to memory corruption when a large here document that required parameter or command substitution was expanded has been fixed. e. A bug that could cause a core dump on some systems after ksh detected an error when reading a function has been fixed. f. A bug which could cause a coprocess to hang when reading from a process that has terminated has been fixed. g. A bug which caused a script to terminate when set -e was on and the first command of and && or || list failed has been fixed. h. A bug with here documents inside $(...) when the delimiter word is an identifier has been fixed. i. A bug which caused $0 to display the wrong value when a script was invoked as an argument to the . command and the eval command has been fixed. j. A bug that could cause the built-in sleep to hang has been fixed. k. A bug introduces in 12/28/93b which caused the backslash to be removed when it was followed by digit inside double quotes in some instances has been fixed. l. A bug which could cause a core dump if ksh was invoked with standard input closed has been fixed. m. A bug which could cause a core dump if typeset -A was specified for an existing variable has been fixed. n. Variables that were unset but had attributes such as readonly and export were not listed with readonly, export and typeset. o. Several problems with signals have been fixed. p. A bug which prevented ulimit -t from working has been fixed. Also, a bug in which failed ulimits could cause a core dump has also been fixed. q. A bug in expansion of the form ${name/#pattern/string} and ${name/%pattern/string} has been fixed. r. A bug which caused read -r on a line that contained only blanks to get a non-null value has been fixed. s. A bug introduced in the 'a' point release in which ${x='\\'} expanded to \ when x was unset has been fixed. t. A bug which prevented a trap on EXIT from being executed when the last command in a script was a function invocation has been fixed. u. A bug which caused an interactive shell ignore input when standard error was redirected to a file with exec, and then restored with exec 2>&1 has been fixed. v. An interactive shell turns on monitor mode even when standard error has been redirected to a file. w. A bug which could cause standard input to be incorrectly positioned for the last command of a script has been fixed. y. A bug in the edit modes which allowed walking back in the history file for more than HISTSIZE commands has been fixed. z. A bug which could cause a core dump if variable TMPDIR was changed between two command substitutions has been fixed. aa. A bug which prevented a trap on EXIT from being cleared has been fixed. 10. Bugs fixed in 12/28/93d for default OPTIONS a. The \ character was not handled correctly in replacement patterns with ${x/pattern/replace}. b. A bug with read in which the line did not end with a new-line has been fixed. c. A bug in file name generation which sometimes appended a . for filenames that ended in / has been fixed. d. If a process is waited for after a status has been returned by a previous wait, wait now returns 127. e. A bug with hist (fc) -e which prevented a command to re-executed after it had been edited has been fixed. f. A bug which prevented quoting from removing the meaning of unary test operators has been fixed. 11. Bugs fixed in 12/28/93e for default OPTIONS a. Empty command substitutions of the form $() now work. b. whence -v foo now gives the correct result after calling builtin -d foo. c. A bug in right to left arithmetic assignment for which the arithmetic expression (( y = x = 1.5 )) did not yield 1 for y when x was declared typeset -i was fixed. d. printf has been fixed to handle format containing \0 and/or \0145 correctly. In addition, characters following %b in the format string are no longer displayed when the operand contains \c. e. A bug in printf that could cause the %E format to produce unnormalized results has been fixed. f. A bug which causes some arithmetic expressions to be incorrectly evaluated as integer expressions rather that floating point has been fixed. g. Functions defined inside a subshell no longer remain defined when the subshell completes. h. The error message from sh -c ';echo foo' has been corrected. i. The format for umask -S has been changed to agree with the specification in the POSIX standard. j. A bug that caused side effects in subscript evaluation when tracing was enabled for subscripts using ++ or -- has been fixed. k. To conform to the POSIX standard getopts has been changed so that the option char is set to ? when it returns with a non-zero exit status. l. The handling of \} inside ${name...} has been fixed so that the \ quotes the }. m. A bug that caused the read builtin to resume execution after processing a trap has been fixed. n. [[ -s file ]] has been fixed so that if file is open by ksh, it is flushed first. o. In some cases attributes and sizes for non exported variables weren't being reset before running a script. p. The value of TMOUT was affected by changes make to it in a subshell. q. The jobs command did not reflect changes make by sending the CONT signal to a command. r. The error message for ksh -o unknown was incorrect. s. Functions invoked as name=value name, did not use values from the calling scope when evaluating value. t. A bug in which the shell would re-execute previously executed code when a shell script or coprocess was run in the background has been fixed. u. A bug in which an empty here-document would leave a file descriptor open has been fixed. v. A bug in which $(set -A array ...) would leave a side effect has been fixed. w. A discipline function for a global variable defined within a function defined with the function keyword, incorrectly created a local variable of the same name and applied the discipline to it. 12. Bugs fixed in 12/28/93f for default OPTIONS a. A bug which would cause the secondary prompt to be displayed when a user entered a literal carriage return has been fixed. b. I bug which caused ksh read -s name to core dump was fixed. c. I bug with the expansion of \} and \] inside double quoted strings that also contained variable expansions has been fixed d. Changes in the 'e' point release caused autoload functions invoked from within command substitution to fail. This has been fixed. e. A bug in the processing of here-documents that could prevent variable substitution to occur after $(...) command substitution for long here documents has been fixed. f. A bug caused by a race condition that could cause SIGTERM to be ignored by a child process has been fixed. g. A bug which prevented the startup of a coprocess immediately after killing a running coprocess has been fixed. h. ulimit foobar, where foobar is not an arithmetic expression, now gives an error message as it did with ksh88 instead of setting the file size limit to 0. i. A bug which could cause an interactive shell to terminate when the last process of a pipeline was a POSIX function was fixed. j. A bug which could cause command substitution of a shell script to core dump has been fixed. k. A security hole was fixed in suid_exec. l. Arithmetic functions such as pow() that take more than one argument, did not work if arguments other than the first contained parenthesized sub-expression. m. The error message from a script containing an incomplete arithmetic expression has been corrected. n. A bug which caused a core dump on some machines when the value of a name reference contained a positional parameter and the name reference was not defined inside a function has been fixed. o. Arithmetic expressions now correctly handle hexadecimal constants. p. A bug in which integer variables could be expanded with a leading 10# when declared with typeset -i multiple times has been corrected. q. A bug in which IFS wasn't correctly restored when set within command substitution has been fixed. r. The _ character is now considered as part of a word with the M-f and M-b emacs directives as it was in ksh88. 13. Bugs fixed in 12/28/93g for default OPTIONS a. A bug in which a name reference could be created to itself and later cause the shell to get into an infinite loop has been fixed. b. A bug in shcomp relating to compound variables was fixed. c. A bug introduced in 'e' in which leading 0's in -Z fields caused the value to be treated as octal for arithmetic evaluation has been fixed. d. A bug when a name reference with a shorter name than the variable it references was the subject of a compound assignment has been fixed. e. A bug which in which assignment to array variables in a subshell could effect the parent shell has been fixed. f. read name?prompt was putting a 0 byte at the end of the prompt on standard error. g. A bug in [[ string1 > string2 ]] when ksh was run with -x has been fixed. k. A bug in which the escape character was not processed correctly inside {...} when brace expansion is enabled has been fixed, for example {\$foo}. l. A bug in line continuation in here-documents has been fixed. m. The default base when not specified with typeset -i is 10 in accordance with the documentation. Previously, the value was determined by the first assignment. n. A parsing bug in which a # preceded alphanumeric characters inside a command substitution caused a syntax error to be reported has been fixed. o. A bug in which a decimal constant represented as 10#ddd where ddd was more than five digits generated a syntax error has been fixed. p. A bug in here document expansion in which ${...} expansions were split across buffer boundaries has been fixed. 14. Bugs fixed in 12/28/93h for default OPTIONS a. I bug in shcomp for compilation of unary operators with [[ ... ]] has been fixed. b. A bug in which the value of $? was changed when executing a keyboard trap has been fixed. c. The handling of SIGCHLD has been changed so that the trap is not triggered while executing trap commands to avoid recursive trap calls. d. I bug in which a local variable in a function declared readonly would generated an error when the function went out of scope has been fixed. e. I bug in which \ entered from the keyboard with the KEYBD trap enabled has been fixed. f. The error message for a misplaced ((, for example print ((3), was often garbled and has been fixed. g. I bug in the KEYBD trap in which escape sequences of the form [#~ were not being handled as a unit has been fixed. h. A bug in which ksh would consider expressions like [[ (a) ]] as syntax errors has been fixed. i. A function defined as foo() without a function body was not reported as a syntax error. j. A bug in which ksh could run out of file descriptors when a stream was repeatedly opened with exec and read from has been fixed. k. A bug introduced when fixing item n from the 'g' point release has been fixed. 15. Bugs fixed in 12/28/93i for default OPTIONS a. A bug in which a script could terminate when getopts encountered an error when invoked inside a function has been fixed. b. When a symbolic link was specified as the name of the script to invoke by name, the value of $0 was set to the real file name rather than the link name in some cases and this has been fixed. 16. Bug fixes for specific non-default option combinations. a. More signal names have been added for Solaris b. A bug fixed for the v directive in vi MULTIBYTE has been fixed. c. Code to for IFS handling of multibyte characters has been added. d. The displaying of multibyte strings in export, readonly, typeset, and execution traces has been fixed. e. A bug with type ahead and KEYBOARD traps with the MULTIBYTE option set has been fixed. f. The k-shell information abstraction database option, KIA, has been revamped for the 'e' point release. g. A bug in brace pattern expansions that caused expressions such as {foo\,bar,bam} to expand incorrectly have been fixed. h. On the U/WIN version for Window 95 and Windows NT, when a directory beginning with a letter followed by a colon is given to cd, it is assumed to be an absolute directory. i. There was a bug in the compile option that does not use fork() in which the current option settings where not propagated to sub-shells. j. A bug in setting .sh.editchar during the KEYBD trap for the MULTIBYTE option was fixed in release 'h'. k. A bug in which the precision given as an argument to printf was not working has been fixed. 17. Other changes to 12/28/93[abcdefghi] a. A couple of minor changes to make adding built-ins easier. b. Variables inside functions are now statically scoped. The previous behavior was never documented. c. A few changes have been made to the name-value library that affect built-ins that use disciplines. The changes allow disciplines to be shared by variables and should make it possible to add new disciplines without recompilation. d. The name-value library interface has undergone significant change for this revision. See the new nval.3 man page. e. Builtin functions can take a third argument which is a void*. f. The nv_scan() function can restrict the scope of a walk to the top scope. Starting in 'f', nv_scan() has an additional pointer argument that is passed to each invoked function. g. Starting with release 'f', an empty for list behave like a for list with null expansions. It produces a warning message with sh -n. h. Starting with release 'f' the code has been modified to work with EBCDIC as well as ASCII. i. Starting with the release 'g', the name-value pair library uses the cdt library rather than the hash library. j. The sh_fun() function now takes third argument which is an argument list for the invoked discipline function or built-in. k. A callback function can be installed which will give notification of file duplications and file closes. 18. Incompatibilities with 12/28/93 version. None intentional. ksh-1.0.0-beta.2/src/cmd/ksh93/SHOPT.sh000066400000000000000000000046121415700074400170770ustar00rootroot00000000000000# # Compile-time SHOPT_* options for ksh93. # 1 to enable, 0 to disable, empty value to probe. # # For a more complete description of the options, see src/cmd/ksh93/README. # SHOPT 2DMATCH=1 # two dimensional ${.sh.match} for ${var//pat/str} SHOPT ACCT= # accounting SHOPT ACCTFILE= # per-user accounting info SHOPT AUDIT=1 # enable auditing per SHOPT_AUDITFILE SHOPT AUDITFILE='\"/etc/ksh_audit\"' # auditing file SHOPT BGX=1 # one SIGCHLD trap per completed job SHOPT BRACEPAT=1 # C-shell {...,...} expansions (, required) SHOPT CMDLIB_HDR= # '' # custom -lcmd list for path-bound builtins SHOPT CMDLIB_DIR= # '\"/opt/ast/bin\"' # virtual directory prefix for path-bound builtins SHOPT CRNL= # accept MS Windows newlines () for SHOPT DEVFD= # use /dev/fd instead of FIFOs for process substitutions SHOPT DYNAMIC=1 # dynamic loading for builtins SHOPT ECHOPRINT= # make echo equivalent to print SHOPT EDPREDICT=0 # History pattern search menu (type #, then ESC TAB). Experimental. SHOPT ESH=1 # emacs/gmacs edit mode SHOPT FILESCAN=1 # fast file scan SHOPT FIXEDARRAY=1 # fixed dimension indexed array SHOPT GLOBCASEDET= # -o globcasedetect: adapt globbing/completion to case-insensitive file systems SHOPT HISTEXPAND=1 # csh-style history file expansions SHOPT KIA= # ksh -R