diff options
78 files changed, 5721 insertions, 25 deletions
@@ -1,7 +1,15 @@ 1999-09-13 Paul D. Smith <psmith@gnu.org> + * Version 3.77.96 released. + * Makefile.am (loadavg): Use CPPFLAGS, etc. to make sure we get all the right #defines to compile. + (check-regression): Look for the regression test suite in the make + package itself. If we're building remotely, use symlinks to make + a local copy. + (dist-hook): Put the test suite into the tar file. + + * configure.in: Look for perl for the test suite. 1999-09-10 Paul Eggert <eggert@twinsun.com> diff --git a/Makefile.am b/Makefile.am index bcddcb0..b157f27 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,18 +62,18 @@ install-exec-local: # --------------- Local DIST Section -# Install the w32 subdirectory +# Install the w32 and tests subdirectories # dist-hook: (cd $(srcdir); \ - w32=`find w32 -follow \( -name CVS -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ - tar chf - $$w32) \ + sub=`find w32 tests -follow \( -name CVS -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ + tar chf - $$sub) \ | (cd $(distdir); tar xfBp -) # --------------- Local CHECK Section -check-local: check-loadavg check-regression +check-local: check-regression check-loadavg .PHONY: check-loadavg check-regression # > check-loadavg @@ -97,30 +97,30 @@ check-loadavg: loadavg # > check-regression # -# Look for the make test suite, and run it if found. Look in MAKE_TEST if -# specified, or else in the srcdir or the distdir, their parents, and _their_ -# parents. +# Look for the make test suite, and run it if found and we can find perl. +# If we're building outside the tree, we use symlinks to make a local copy of +# the test suite. Unfortunately the test suite itself isn't localizable yet. # MAKETESTFLAGS = -check-regression: all - @here=`pwd`; testdir=""; \ - case "$(MAKE_TEST)" in "") \ - for d1 in $$here $(srcdir); do \ - for d2 in ../.. .. .; do \ - all=`echo $$d1/$$d2/make-test-[0-9]*/run_make_tests`; \ - case "$$all" in \ - "$$d1/$$d2/make-test-[0-9]*/run_make_tests") : ;; \ - *) try=`for x in $$all; do echo $$x; done | sort | tail -1`;\ - testdir=`dirname $$try` ;; esac; \ - done; done ;; \ - *) testdir="$(MAKE_TEST)" ;; \ - esac; \ - case "$$testdir" in \ - "") echo "Couldn't find make-test-* regression test suite."; exit 0;; \ - esac; \ - echo "cd $$testdir && ./run_make_tests -make $$here/make $(MAKETESTFLAGS)"; \ - cd $$testdir && ./run_make_tests -make $$here/make $(MAKETESTFLAGS) +check-regression: + @if test -f "$(srcdir)/tests/run_make_tests"; then \ + if $(PERL) -v >/dev/null 2>&1; then \ + case `cd $(srcdir); pwd` in `pwd`) : ;; \ + *) mkdir tests; \ + if ln -s "$(srcdir)/tests" srctests; then \ + for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ + rm -f tests/$$f; ln -s ../srctests/$$f tests; \ + done; fi ;; \ + esac; \ + echo "cd tests && ./run_make_tests -make ../make $(MAKETESTFLAGS)"; \ + cd tests && ./run_make_tests -make ../make $(MAKETESTFLAGS); \ + else \ + echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ + fi; \ + else \ + echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ + fi # --------------- Local CLEAN section diff --git a/configure.in b/configure.in index 3002e6a..9e36112 100644 --- a/configure.in +++ b/configure.in @@ -19,6 +19,9 @@ AC_AIX AC_ISC_POSIX AC_MINIX +AC_CHECK_PROG(PERL, perl, perl, perl) dnl Needed for the test suite (only) + + dnl This test must come as early as possible after the compiler configuration dnl tests, because the choice of the file model can (in principle) affect dnl whether functions and headers are available, whether they work, etc. diff --git a/tests/COPYING b/tests/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/tests/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/tests/NEWS b/tests/NEWS new file mode 100644 index 0000000..a9fdaee --- /dev/null +++ b/tests/NEWS @@ -0,0 +1,161 @@ +Changes from 0.4.9 to 3.78 (Sep 6, 1999): + + Lots of new tests. Renamed to follow the GNU make scheme. Also + added some support for using Purify with make. + + Rob Tulloh contributed some changes to get the test suite running on + NT; I tweaked them a bit (hopefully I didn't break anything!) Note + that NT doesn't grok the self-exec funkiness that Unix shells use, + so instead I broke that out into a separate shell script + "run_make_tests" that invokes perl with the (renamed) script + run_make_tests.pl. + + Eli Zaretski contributed changes to get the test suite running on + DOS with DJGPP. I also meddled in these somewhat. + + If you're on DOS or NT you should run "perl.exe run_make_tests.pl ..." + If you're on Unix, you can continue to run "./run_make_tests ..." as + before. + +Changes from 0.4.8 to 0.4.9 (May 14, 1998): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Add some perl to test_driver.pl to strip out GNU make clock skew + warning messages from the output before comparing it to the + known-good output. + + A new test for escaped :'s in filenames (someone on VMS found this + didn't work anymore in 3.77): scripts/features/escape. + +Changes from 0.4.7 to 0.4.8 (May 14, 1998): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + New tests for features to be included in GNU make 3.77. + +Changes from 0.4.6 to 0.4.7 (August 18, 1997): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Reworked some tests to make sure they all work with both perl4 and perl5. + + Work around a bug in perl 5.004 which doesn't clean the environment + correctly in all cases (fixed in at least 5.004_02). + + Updated functions/strip to test for newline stripping. + + Keep a $PURIFYOPTIONS env variable if present. + +Changes from 0.4.5 to 0.4.6 (April 07, 1997): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Updated to work with GNU make 3.76 (and pretests). + + Added new tests and updated existing ones. Note that the new tests + weren't tested with perl 4, however I think they should work. + + Ignore any tests whose filenames end in "~", so that Emacs backup + files aren't run. + +Changes from 0.4.4 to 0.4.5 (April 29, 1995): + + Updated to be compatible with perl 5.001 as well as 4.036. + + Note: the test suite still won't work on 14-char filesystems + (sorry, Kaveh), but I will get to it. + + Also, some tests and stuff still haven't made it in because I + haven't had time to write the test scripts for them. But they, + too, will get in eventually. Contributions of scripts (ie, tests + that I can just drop in) are particularly welcome and will be + incorporated immediately. + +Changes from 0.4.3 to 0.4.4 (March 1995): + + Updated for changes in make 3.72.12, and to ignore CVS directories + (thanks go to Jim Meyering for the patches for this). + + Fixed uname call to not make a mess on BSD/OS 2.0 (whose uname -a + is very verbose). Let me know if this doesn't work correctly on + your system. + + Changed to display test name while it is running, not just when it + finishes. + + Note: the test suite still won't work on 14-char filesystems + (sorry, Kaveh), but I will get to it. + + Also, some tests and stuff still haven't made it in because I + haven't had time to write the test scripts for them. But they, + too, will get in eventually. + +Changes from 0.4 to 0.4.3 (October 1994): + + Fixed bugs (like dependencies on environment variables). + + Caught up with changes in make. + + The load_limit test should now silently ignore a failure due to + make not being able to read /dev/kmem. + + Reorganized tests into subdirs and renamed lots of things so that + those poor souls who still have to deal with 14-char filename + limits won't hate me any more. Thanks very much to Kaveh R. Ghazi + <ghazi@noc.rutgers.edu> for helping me with the implementation and + testing of these changes, and for putting up with all my whining + about it... + + Added a $| = 1 so that systems that don't seem to automatically + flush their output for some reason will still print all the + output. I'd hate for someone to miss out on the smiley that + you're supposed to get when all the tests pass... :-) + +Changes from 0.3 to 0.4 (August 1993): + + Lost in the mists of time (and my hurry to get it out before I + left my job). + +Changes from 0.2 to 0.3 (9-30-92): + + Several tests fixed to match the fact that MAKELEVEL > 0 or -C now + imply -w. + + parallel_execution test fixed to not use double colon rules any + more since their behavior has changed. + + errors_in_commands test fixed to handle different error messages + and return codes from rm. + + Several tests fixed to handle -make_path with a relative path + and/or a name other than "make" for make. + + dash-e-option test fixed to use $PATH instead of $USER (since the + latter does not exist on some System V systems). This also + removes the dependency on getlogin (which fails under certain + weird conditions). + + test_driver_core changed so that you can give a test name like + scripts/errors_in_commands and it will be handled correctly (handy + if you have a shell with filename completion). + +Changes from 0.1 to 0.2 (5-4-92): + + README corrected to require perl 4.019, not 4.010. + + -make_path replaces -old. + + errors_in_commands test updated for change in format introduced in + make 3.62.6. + + test_driver_core now uses a better way of figuring what OS it is + running on (thanks to meyering@cs.utexas.edu (Jim Meyering) for + suggesting this, as well as discovering the hard way that the old + way (testing for /mnt) fails on his machine). + + Some new tests were added. diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..a0e800c --- /dev/null +++ b/tests/README @@ -0,0 +1,79 @@ +This is release 3.78 (September 6, 1999) of the GNU make test +suite. See the file NEWS for some of the changes since the last +release. + +This release is made by psmith@gnu.org to correspond to GNU make 3.78. +It won't work correctly for versions before that. In addition to some +infrastructure changes I've added a number of new tests. + +Rob Tulloh has contributed changes to get the suite running on NT. + +Eli Zaretski and Esa A E Peuha <peuha@cc.helsinki.fi> have contributed +changes to the get the suite running on DJGPP/DOS. + +This package has a number of problems which preclude me from +distributing it with make as a default "make check" test suite. The +most serious of these is that it's not parallelizable: it scribbles all +over its installation directory and so can only test one make at a +time. I simply don't have time to do more with this than I am so far; +I'm very actively interested in finding someone willing to overhaul the +test suite infrastructure. If you're interested, contact me (see below)! + +The test suite thus far has been written by Steve McGee, Chris Arthur, +and Paul D. Smith. It is covered by the GNU General Public License +(Version 2), described in the file COPYING. + +The test suite requires Perl and is known to work with Perl 4.036 and +Perl 5.004 (available from ftp.gnu.org, and portable to many machines). +Earlier or later versions may work; I don't know. It assumes that the +first "diff" it finds is GNU diff, but that only matters if a test +fails. + +To run the test suite on a UNIX system, use "perl ./run_make_tests" +(or just "./run_make_tests" if you have a perl on your PATH). + +To run the test suite on Windows NT or DOS systems, use +"perl.exe ./run_make-tests.pl". + +By default, the test engine picks up the first executable called "make" +that it finds in your path. You may use the -make_path option (ie, +"perl run_make_tests -make_path /usr/local/src/make-3.78/make") if +you want to run a particular copy. This now works correctly with +relative paths and when make is called something other than "make" (like +"gmake"). + +Tests cannot end with a "~" character, as the test suite will ignore any +that do (I was tired of having it run my Emacs backup files as test :) + +If you want to run the tests in parallel, you should use the mkshadow +script included here to create temporary "copies" (via symbolic links) +of the test suite, one for each parallel job. This is a pain and one +day maybe the test suite will be rewritten so it's no longer +necessary--volunteers welcome! + +Also, sometimes the tests may behave strangely on networked +filesystems. You can use mkshadow to create a copy of the test suite in +/tmp or similar, and try again. If the error disappears, it's an issue +with your network or file server, not GNU make (I believe). + +The options/dash-l test will not really test anything if the copy of +make you are using can't obtain the system load. Some systems require +make to be setgid sys or kmem for this; if you don't want to install +make just to test it, make it setgid to kmem or whatever group /dev/kmem +is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the +options/dash-l test should no longer *fail* because make can't read +/dev/kmem. + +A directory named "work" will be created when the tests are run which +will contain any makefiles and "diff" files of tests that fail so that +you may look at them afterward to see the output of make and the +expected result. + +There is a -help option which will give you more information about the +other possible options for the test suite. + +Any complaints/suggestions/bugs/etc. for the test suite itself (as +opposed to problems in make that the suite finds) should be sent to +psmith@gnu.org. Enjoy! + Paul D. Smith + Chris Arthur diff --git a/tests/mkshadow b/tests/mkshadow new file mode 100755 index 0000000..baae836 --- /dev/null +++ b/tests/mkshadow @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Simple script to make a "shadow" test directory, using symbolic links. +# Typically you'd put the shadow in /tmp or another local disk +# + +case "$1" in + "") echo 'Usage: mkshadow <destdir>'; exit 1 ;; +esac + +dest="$1" + +if [ ! -d "$dest" ]; then + echo "Destination directory \`$dest' must exist!" + exit 1 +fi + +if [ ! -f run_make_tests ]; then + echo "The current directory doesn't appear to contain the test suite!" + exit 1 +fi + +suite=`pwd | sed 's%^/tmp_mnt%%'` +name=`basename "$suite"` + +files=`echo *` + +set -e + +mkdir "$dest/$name" +cd "$dest/$name" + +ln -s "$suite" .testdir + +for f in $files; do + ln -s .testdir/$f . +done + +rm -rf work + +echo "Shadow test suite created in \`$dest/$name'." +exit 0 diff --git a/tests/run_make_tests b/tests/run_make_tests new file mode 100755 index 0000000..b68b784 --- /dev/null +++ b/tests/run_make_tests @@ -0,0 +1,2 @@ +#!/bin/sh +exec perl $0.pl ${1+"$@"} diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl new file mode 100755 index 0000000..56902ca --- /dev/null +++ b/tests/run_make_tests.pl @@ -0,0 +1,203 @@ +#!/usr/local/bin/perl +# -*-perl-*- + +# Test driver for the Make test suite + +# Usage: run_make_tests [testname] +# [-debug] +# [-help] +# [-verbose] +# [-keep] +# [-make <make prog>] +# [-work <work dir>] +# (and others) + +require "test_driver.pl"; + +sub valid_option +{ + local($option) = @_; + if ($option =~ /^-make([-_]?path)?$/) + { + $make_path = shift @argv; + if (!-f $make_path) + { + print "$option $make_path: Not found.\n"; + exit 0; + } + return 1; + } + elsif ($option =~ /^-work([-_]?dir)?$/) + { + $workdir = shift @argv; + return 1; + } + + return 0; +} + +sub run_make_with_options +{ + local ($filename,$options,$logname,$expected_code) = @_; + local($code); + local($command) = $make_path; + + $expected_code = 0 unless defined($expected_code); + + if ($filename) + { + $command .= " -f $filename"; + } + + if ($options) + { + $command .= " $options"; + } + + $code = &run_command_with_output($logname,$command); + + # Check to see if we have Purify errors. If so, keep the logfile. + # For this to work you need to build with the Purify flag -exit-status=yes + + if ($pure_log && -f $pure_log) { + if ($code & 0x7000) { + $code &= ~0x7000; + + # If we have a purify log, save it + $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : ""); + print("Renaming purify log file to $tn\n") if $debug; + rename($pure_log, "$tn") + || die "Can't rename $log to $tn: $!\n"; + ++$purify_errors; + } + else { + unlink($pure_log); + } + } + + if ($code != $expected_code) + { + print "Error running $make_path ($code): $command\n"; + $test_passed = 0; + return 0; + } + + if ($profile & $vos) + { + system "add_profile $make_path"; + } +1; +} + +sub print_usage +{ + &print_standard_usage ("run_make_tests", "[-make_path make_pathname]"); +} + +sub print_help +{ + &print_standard_help ("-make_path", + "\tYou may specify the pathname of the copy of make to run."); +} + +sub get_this_pwd { + if ($vos) + { + $delete_command = "delete_file"; + $__pwd = `++(current_dir)`; + } + else + { + $delete_command = "rm"; + chop ($__pwd = `pwd`); + } + + return $__pwd; +} + +sub set_defaults +{ + # $profile = 1; + $testee = "GNU make"; + $make_path = "make"; + $tmpfilesuffix = "mk"; + $pwd = &get_this_pwd; + + # Find the full pathname of Make. For DOS systems this is more + # complicated, so we ask make itself. + + open(MAKEFILE,"> makefile.tmp"); + print MAKEFILE 'all: ; @echo $(MAKE)' . "\n"; + close(MAKEFILE); + $make_path = `$make_path -f makefile.tmp`; + chop $make_path; + unlink "makefile.tmp"; +} + +sub set_more_defaults +{ + local($string); + local($index); + + $string = `$make_path -v -f /dev/null 2> /dev/null`; + + $string =~ s/[,\n].*/\n/s; + $testee_version = $string; + + $string = `sh -c "$make_path -f /dev/null 2>&1"`; + if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { + $make_name = $1; + } + else { + if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) { + $make_name = $1; + } + else { + $make_name = $make_path; + } + } + + # prepend pwd if this is a relative path (ie, does not + # start with a slash, but contains one). Thanks for the + # clue, Roland. + + if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) + { + $mkpath = "$pwd$pathsep$make_path"; + } + else + { + $mkpath = $make_path; + } + + # Get Purify log info--if any. + + ($pure_log = $ENV{PURIFYOPTIONS}) =~ s,.*-logfile=([^ ]+) .*,\1,; + $pure_log =~ s/%v/$make_name/; + $purify_errors = 0; + + $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`; + if ($string =~ /not supported/) { + $parallel_jobs = 0; + } + else { + $parallel_jobs = 1; + } +} + +sub setup_for_test +{ + $makefile = &get_tmpfile; + if (-f $makefile) + { + unlink $makefile; + } + + # Get rid of any Purify logs. + ($pure_testname = $testname) =~ tr,/,_,; + $pure_testname = "$pure_log.$pure_testname"; + system("rm -f $pure_testname*"); + print("Purify testfiles are: $pure_testname*\n") if $debug; +} + +exit !&toplevel; diff --git a/tests/scripts/features/comments b/tests/scripts/features/comments new file mode 100644 index 0000000..9257955 --- /dev/null +++ b/tests/scripts/features/comments @@ -0,0 +1,35 @@ +$description = "The following test creates a makefile to test comments\n" + ."and comment continuation to the next line using a \n" + ."backslash within makefiles."; + +$details = "To test comments within a makefile, a semi-colon was placed \n" + ."after a comment was started. This should not be reported as\n" + ."an error since it is within a comment. We then continue the \n" + ."comment to the next line using a backslash. To test whether\n" + ."the comment really continued, we place an echo command with some\n" + ."text on the line which should never execute since it should be \n" + ."within a comment\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<\EOF; +# Test comment vs semicolon parsing and line continuation +target: # this ; is just a comment \ + @echo This is within a comment. + @echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)) diff --git a/tests/scripts/features/conditionals b/tests/scripts/features/conditionals new file mode 100644 index 0000000..3557fb5 --- /dev/null +++ b/tests/scripts/features/conditionals @@ -0,0 +1,67 @@ +# -*-perl-*- +$description = "Check GNU make conditionals."; + +$details = "Attempt various different flavors of GNU make conditionals."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +objects = foo.obj +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = second + +all: +ifeq ($(arg1),$(arg2)) + @echo arg1 equals arg2 +else + @echo arg1 NOT equal arg2 +endif + +ifeq '$(arg2)' "$(arg5)" + @echo arg2 equals arg5 +else + @echo arg2 NOT equal arg5 +endif + +ifneq '$(arg3)' '$(arg4)' + @echo arg3 NOT equal arg4 +else + @echo arg3 equal arg4 +endif + +ifndef undefined + @echo variable is undefined +else + @echo variable undefined is defined +endif +ifdef arg4 + @echo arg4 is defined +else + @echo arg4 is NOT defined +endif + +EOMAKE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "arg1 NOT equal arg2 +arg2 equals arg5 +arg3 NOT equal arg4 +variable is undefined +arg4 is defined +"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/default_names b/tests/scripts/features/default_names new file mode 100644 index 0000000..824f889 --- /dev/null +++ b/tests/scripts/features/default_names @@ -0,0 +1,63 @@ +$description = "This script tests to make sure that Make looks for +default makefiles in the correct order (GNUmakefile,makefile,Makefile)"; + +# Create a makefile called "GNUmakefile" +$makefile = "GNUmakefile"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n"; + +close(MAKEFILE); + +# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile. +# Just test what we can here (avoid Makefile versus makefile test). +# +if ($osname !~ /DOS|Windows/i) +{ + # Create another makefile called "makefile" + open(MAKEFILE,"> makefile"); + + print MAKEFILE "SECOND: ; \@echo It chose makefile\n"; + + close(MAKEFILE); +} + + +# Create another makefile called "Makefile" +open(MAKEFILE,"> Makefile"); + +print MAKEFILE "THIRD: ; \@echo It chose Makefile\n"; + +close(MAKEFILE); + + +&run_make_with_options("","",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "It chose GNUmakefile\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)) || &error("abort"); +unlink $makefile; + +# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile. +# Just test what we can here (avoid Makefile versus makefile test). +# +if ($osname !~ /DOS|Windows/i) +{ + $answer = "It chose makefile\n"; + + &run_make_with_options("","",&get_logfile); + + &compare_output($answer,&get_logfile(1)) || &error("abort"); + unlink "makefile"; +} + +$answer = "It chose Makefile\n"; + +&run_make_with_options("","",&get_logfile); + +&compare_output($answer,&get_logfile(1)) || &error("abort"); +unlink "Makefile"; diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon new file mode 100644 index 0000000..096fb33 --- /dev/null +++ b/tests/scripts/features/double_colon @@ -0,0 +1,48 @@ +$description = "The following test creates a makefile to test Double-Colon\n" + ."Rules. They are rules which are written with '::' instead\n" + ."of ':' after the target names. This tells make that each \n" + ."of these rules are independent of the others and each rule's\n" + ."commands are executed if the target is older than any \n" + ."dependencies of that rule."; + +$details = "The makefile created by this test contains two double-colon \n" + ."rules for foo; each with their own commands. When make is run,\n" + ."each command should be executed in the sequence that they are \n" + ."found. The command is a simple echo statement."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo:: bar.h \n" + ."\t\@echo Executing rule foo FIRST\n" + ."foo2: bar.h \n" + ."foo:: bar2.h \n" + ."\t\@echo Executing rule foo SECOND\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("bar.h","bar2.h"); + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + + +$answer = "Executing rule foo FIRST\n" + ."Executing rule foo SECOND\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink("bar.h","bar2.h"); + +1; + + + + + + diff --git a/tests/scripts/features/echoing b/tests/scripts/features/echoing new file mode 100644 index 0000000..ed1e862 --- /dev/null +++ b/tests/scripts/features/echoing @@ -0,0 +1,90 @@ +$description = "The following test creates a makefile to test command \n" + ."echoing. It tests that when a command line starts with \n" + ."a '\@', the echoing of that line is suppressed. It also \n" + ."tests the -n option which tells make to ONLY echo the \n" + ."commands and no execution happens. In this case, even \n" + ."the commands with '\@' are printed. Lastly, it tests the \n" + ."-s flag which tells make to prevent all echoing, as if \n" + ."all commands started with a '\@'."; + +$details = "This test is similar to the 'clean' test except that a '\@' has\n" + ."been placed in front of the delete command line. Four tests \n" + ."are run here. First, make is run normally and the first echo\n" + ."command should be executed. In this case there is no '\@' so \n" + ."we should expect make to display the command AND display the \n" + ."echoed message. Secondly, make is run with the clean target, \n" + ."but since there is a '\@' at the beginning of the command, we\n" + ."expect no output; just the deletion of a file which we check \n" + ."for. Third, we give the clean target again except this time\n" + ."we give make the -n option. We now expect the command to be \n" + ."displayed but not to be executed. In this case we need only \n" + ."to check the output since an error message would be displayed\n" + ."if it actually tried to run the delete command again and the \n" + ."file didn't exist. Lastly, we run the first test again with \n" + ."the -s option and check that make did not echo the echo \n" + ."command before printing the message."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\techo This makefile did not clean the dir... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t\@$delete_command $example\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +# TEST #1 +# ------- + +&run_make_with_options($makefile,"",&get_logfile,0); +$answer = "echo This makefile did not clean the dir... good\n" + ."This makefile did not clean the dir... good\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +&run_make_with_options($makefile,"clean",&get_logfile,0); +$answer = ""; +&compare_output($answer,&get_logfile(1)); + +if (-f $example) +{ + $test_passed = 0; +} + +# TEST #3 +# ------- + +&run_make_with_options($makefile,"-n clean",&get_logfile,0); +$answer = "$delete_command $example\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #4 +# ------- + +&run_make_with_options($makefile,"-s",&get_logfile,0); +$answer = "This makefile did not clean the dir... good\n"; +&compare_output($answer,&get_logfile(1)); + + +1; + + + + + + + + + diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors new file mode 100644 index 0000000..a39064f --- /dev/null +++ b/tests/scripts/features/errors @@ -0,0 +1,93 @@ +$description = "The following tests the -i option and the '-' in front of \n" + ."commands to test that make ignores errors in these commands\n" + ."and continues processing."; + +$details = "This test runs two makes. The first runs on a target with a \n" + ."command that has a '-' in front of it (and a command that is \n" + ."intended to fail) and then a delete command after that is \n" + ."intended to succeed. If make ignores the failure of the first\n" + ."command as it is supposed to, then the second command should \n" + ."delete a file and this is what we check for. The second make\n" + ."that is run in this test is identical except that the make \n" + ."command is given with the -i option instead of the '-' in \n" + ."front of the command. They should run the same. "; + +if ($vos) +{ + $delete_command = "delete_file"; +} +else +{ + $delete_command = "rm"; +} + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "clean:\n" + ."\t-$delete_command cleanit\n" + ."\t$delete_command foo\n" + ."clean2: \n" + ."\t$delete_command cleanit\n" + ."\t$delete_command foo\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("foo"); + +unlink("cleanit"); +$cleanit_error = `sh -c "$delete_command cleanit 2>&1"`; +$delete_error_code = $? >> 8; + +# TEST #1 +# ------- + +$answer = "$delete_command cleanit\n" + . $cleanit_error + ."$make_name: [clean] Error $delete_error_code (ignored)\n" + ."$delete_command foo\n"; + +&run_make_with_options($makefile,"",&get_logfile); + +# The output for this on VOS is too hard to replicate, so we only check it +# on unix. +if (!$vos) +{ + &compare_output($answer,&get_logfile(1)); +} + +# If make acted as planned, it should ignore the error from the first +# command in the target and execute the second which deletes the file "foo" +# This file, therefore, should not exist if the test PASSES. +if (-f "foo") +{ + $test_passed = 0; +} + + +&touch("foo"); + +# TEST #2 +# ------- + +$answer = "$delete_command cleanit\n" + . $cleanit_error + ."$make_name: [clean2] Error $delete_error_code (ignored)\n" + ."$delete_command foo\n"; + +&run_make_with_options($makefile,"clean2 -i",&get_logfile); + +if (!$vos) +{ + &compare_output($answer,&get_logfile(1)); +} + +if (-f "foo") +{ + $test_passed = 0; +} + +1; diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape new file mode 100644 index 0000000..7404387 --- /dev/null +++ b/tests/scripts/features/escape @@ -0,0 +1,38 @@ +$description = "Test various types of escaping in makefiles."; + +$details = "Make sure that escaping of `:' works in target names."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE '$(path)foo : ; @echo cp $^ $@ +'; + +close(MAKEFILE); + + +# TEST 1 + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "cp foo\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 2: This one should fail, since the ":" is unquoted. + +&run_make_with_options($makefile, "path=p:", &get_logfile, 512); +$answer = "$makefile:1: *** target pattern contains no `%'. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 3: This one should work, since we escape the ":". + +&run_make_with_options($makefile, "'path=p\\:'", &get_logfile, 0); +$answer = "cp p:foo\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 4: This one should fail, since the escape char is escaped. + +&run_make_with_options($makefile, "'path=p\\\\:'", &get_logfile, 512); +$answer = "$makefile:1: *** target pattern contains no `%'. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/include b/tests/scripts/features/include new file mode 100644 index 0000000..2a48fbd --- /dev/null +++ b/tests/scripts/features/include @@ -0,0 +1,58 @@ +# -*-mode: perl; rm-trailing-spaces: nil-*- + +$description = "Test various forms of the GNU make `include' command."; + +$details = "Test include, -include, sinclude and various regressions involving them. +Test extra whitespace at the end of the include, multiple -includes and +sincludes (should not give an error) and make sure that errors are reported +for targets that were also -included."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +\#Extra space at the end of the following file name +include $makefile2 +all: ; \@echo There should be no errors for this makefile. + +-include nonexistent.mk +-include nonexistent.mk +sinclude nonexistent.mk +sinclude nonexistent-2.mk +-include makeit.mk +sinclude makeit.mk + +error: makeit.mk +EOF + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n"; + +close(MAKEFILE); + +# Create the answer to what should be produced by this Makefile +&run_make_with_options($makefile, "all", &get_logfile); +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile, "ANOTHER", &get_logfile); +$answer = "This is another included makefile\n"; +&compare_output($answer, &get_logfile(1)); + +# Try to build the "error" target; this will fail since we don't know +# how to create makeit.mk, but we should also get a message (even though +# the -include suppressed it during the makefile read phase, we should +# see one during the makefile run phase). + +&run_make_with_options($makefile, "error", &get_logfile, 512); +$answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n"; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules new file mode 100644 index 0000000..6f120f1 --- /dev/null +++ b/tests/scripts/features/mult_rules @@ -0,0 +1,78 @@ +$description = "\ +The following test creates a makefile to test the presence +of multiple rules for one target. One file can be the +target of several rules if at most one rule has commands; +the other rules can only have dependencies."; + +$details = "\ +The makefile created in this test contains two hardcoded rules +for foo.o and bar.o. It then gives another multiple target rule +with the same names as above but adding more dependencies. +Additionally, another variable extradeps is listed as a +dependency but is defined to be null. It can however be defined +on the make command line as extradeps=extra.h which adds yet +another dependency to the targets."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +objects = foo.o bar.o +foo.o : defs.h +bar.o : defs.h test.h +extradeps = +\$(objects) : config.h \$(extradeps) +\t\@echo EXTRA EXTRA +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("defs.h","test.h","config.h"); + +if ($vos) +{ + $error_code = 3307; +} +else +{ + $error_code = 512; +} + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + $error_code); + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: *** No rule to make target `extra.h', needed by `foo.o'. Stop.\n"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +&touch("extra.h"); + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "EXTRA EXTRA\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink("defs.h","test.h","config.h","extra.h"); + +1; + + + + + + diff --git a/tests/scripts/features/mult_targets b/tests/scripts/features/mult_targets new file mode 100644 index 0000000..c8ff418 --- /dev/null +++ b/tests/scripts/features/mult_targets @@ -0,0 +1,46 @@ +$description = "The following test creates a makefile to test that a \n " + ."rule with multiple targets is equivalent to writing \n" + ."many rules, each with one target, and all identical aside\n" + ."from that."; + +$details = "A makefile is created with one rule and two targets. Make \n" + ."is called twice, once for each target, and the output which \n" + ."contains the target name with \$@ is looked at for the changes.\n" + ."This test also tests the substitute function by replacing \n" + ."the word output with nothing in the target name giving either\n" + ."an output of \"I am little\" or \"I am big\""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "bigoutput littleoutput: test.h\n"; +print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("test.h"); + +&run_make_with_options($makefile,"bigoutput",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = "I am big\n"; + +&compare_output($answer,&get_logfile(1)); + +&run_make_with_options($makefile,"littleoutput",&get_logfile); +$answer = "I am little\n"; +&compare_output($answer,&get_logfile(1)); + +unlink "test.h"; + +1; + + + + + + diff --git a/tests/scripts/features/override b/tests/scripts/features/override new file mode 100644 index 0000000..23e4f2b --- /dev/null +++ b/tests/scripts/features/override @@ -0,0 +1,34 @@ +$description = "The following test creates a makefile to ..."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "override define foo\n" + ."\@echo First comes the definition.\n" + ."\@echo Then comes the override.\n" + ."endef\n" + ."all: \n" + ."\t\$(foo)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"foo=Hello",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "First comes the definition.\n" + ."Then comes the override.\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism new file mode 100644 index 0000000..17e800c --- /dev/null +++ b/tests/scripts/features/parallelism @@ -0,0 +1,76 @@ +# -*-perl-*- + +$description = "Test parallelism (-j) option."; + + +$details = "This test creates a makefile with three double-colon default +rules. The first rule has a series of sleep and echo commands +intended to run in series. The second and third have just an +echo statement. When make is called in this test, it is given +the -j option with a value of 4. This tells make that it may +start up to four jobs simultaneously. In this case, since the +first command is a sleep command, the output of the second +and third commands will appear before the first if indeed +make is running all of these commands in parallel."; + +if (!$parallel_jobs) { + return -1; +} + +if ($vos) { + $delete_command = "delete_file -no_ask"; + $sleep_command = "sleep -seconds"; +} +else { + $delete_command = "rm -f"; + $sleep_command = "sleep"; +} + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<"EOF"; +all : def_1 def_5 def_6 +def_1 : +\t\@$sleep_command 3 ; echo ONE +\t\@echo TWO +\t\@$sleep_command 1 ; echo THREE +\t\@echo FOUR +def_5 : +\t\@echo FIVE +def_6 : +\t\@$sleep_command 1 ; echo SIX + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "-j 4", &get_logfile); +$answer = "FIVE\nSIX\nONE\nTWO\nTHREE\nFOUR\n"; +&compare_output($answer, &get_logfile(1)); + + +# Test parallelism with included files + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<'EOF'; +all: 1 2 3; @echo success + +-include 1.inc 2.inc 3.inc + + 1.inc: ; @sleep 1; echo 1; echo "1: ; @echo $@ has been included" > $@ +2.inc: ; @sleep 2; echo 2; echo "2: ; @echo $@ has been included" > $@ +3.inc: ; @echo 3; echo "3: ; @echo $@ has been included" > $@ +EOF + +close(MAKEFILE); + +&run_make_with_options("$makefile2", "-j 4", &get_logfile); +$answer = "3\n1\n2\n1.inc has been included\n2.inc has been included\n3.inc has been included\nsuccess\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('1.inc', '2.inc', '3.inc'); + +1; diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars new file mode 100644 index 0000000..0684a80 --- /dev/null +++ b/tests/scripts/features/patspecific_vars @@ -0,0 +1,40 @@ +# -*-perl-*- +$description = "Test pattern-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of pattern-specific variable +settings, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +all: one.x two.x three.x +FOO = foo +BAR = bar +BAZ = baz +thr% : override BAZ = three +t%.x: BAR = four +%.x: BAR = two +%.x: override BAZ = three +one.x: override FOO = one +one.x two.x three.x: ; @echo $(FOO) $(BAR) $(BAZ) +EOF + +close(MAKEFILE); + + +# TEST #1 -- basics + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "one two three\nfoo four baz\nfoo bar three\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 -- try the override feature + +&run_make_with_options($makefile, "BAZ=five", &get_logfile); +$answer = "one two three\nfoo four five\nfoo bar three\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/features/quoting b/tests/scripts/features/quoting new file mode 100644 index 0000000..916681c --- /dev/null +++ b/tests/scripts/features/quoting @@ -0,0 +1,32 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test using \n" . + "quotes within makefiles."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOM'; +SHELL = /bin/sh +TEXFONTS = NICEFONT +DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\" +test: ; @"echo" 'DEFINES = $(DEFINES)' +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +&run_make_with_options($makefile,"",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion new file mode 100644 index 0000000..444f7ce --- /dev/null +++ b/tests/scripts/features/recursion @@ -0,0 +1,61 @@ +# -*-perl-*- +$description = "The following test creates a makefile to ...\n"; + +$details = "DETAILS"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n" + ."\t\$(MAKE) -f $makefile foo \n" + ."foo: \n" + ."\t\@echo \$(MAKE) \n" + ."\t\@echo MAKELEVEL = \$(MAKELEVEL)\n" + ."\t\$(MAKE) -f $makefile last \n" + ."last: \n" + ."\t\@echo \$(MAKE) \n" + ."\t\@echo MAKELEVEL = \$(MAKELEVEL) \n" + ."\t\@echo THE END\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +if ($vos) +{ + $answer = "$make_name: Entering directory \`$pwd\'\n" + ."make 'CFLAGS=-O' -f $makefile foo \n" + ."make CFLAGS=-O\n" + ."MAKELEVEL = 0\n" + ."make 'CFLAGS=-O' -f $makefile last \n" + ."make CFLAGS=-O\n" + ."MAKELEVEL = 0\n" + ."THE END\n" + ."$make_name: Leaving directory `$pwd'\n"; +} +else +{ + $answer = "$make_name: Entering directory `$pwd'\n" + ."$mkpath -f $makefile foo \n" + ."${make_name}[1]: Entering directory `$pwd'\n" + ."$mkpath\n" + ."MAKELEVEL = 1\n" + ."$mkpath -f $makefile last \n" + ."${make_name}[2]: Entering directory `$pwd'\n" + ."$mkpath\n" + ."MAKELEVEL = 2\n" + ."THE END\n" + ."${make_name}[2]: Leaving directory `$pwd'\n" + ."${make_name}[1]: Leaving directory `$pwd'\n" + ."$make_name: Leaving directory `$pwd'\n"; +} + +$mkoptions = "CFLAGS=-O -w"; +$mkoptions .= " -j 2" if ($parallel_jobs); + +&run_make_with_options($makefile,$mkoptions,&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke new file mode 100644 index 0000000..1047d0e --- /dev/null +++ b/tests/scripts/features/reinvoke @@ -0,0 +1,90 @@ +# -*-mode: perl-*- + +$description = "Test GNU make's auto-reinvocation feature."; + +$details = "\ +If the makefile or one it includes can be rebuilt then it is, and make +is reinvoked. We create a rule to rebuild the makefile from a temp +file, then touch the temp file to make it newer than the makefile."; + +$makefile2 = &get_tmpfile; +$makefile_orig = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<EOM; +SHELL = /bin/sh + +all: ; \@echo 'running rules.' + +$makefile $makefile2: $makefile_orig + \@echo 'rebuilding \$\@.' + \@touch \$\@ + +include $makefile2 + +EOM + +close(MAKEFILE); + +&touch($makefile2); + +# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second +# granularity of file times. +sleep(2); + +&touch("$makefile_orig"); + +&run_make_with_options($makefile, "", &get_logfile, 0); + +# Create the answer to what should be produced by this Makefile + +$answer = "rebuilding $makefile2.\nrebuilding $makefile.\nrunning rules.\n"; + +&compare_output($answer,&get_logfile(1)) + && unlink "$makefile_orig"; + +# In this test we create an included file that's out-of-date, but then +# the rule doesn't update it. Make shouldn't re-exec. + +$makefile3 = &get_tmpfile; + +open(MAKEFILE, "> $makefile3"); +print MAKEFILE <<'EOM'; +all: ; @echo hello + +a : b ; touch $@ + +b : c ; [ -f $@ ] || touch $@ + +c: ; touch $@ + +include $(F) +EOM + +close(MAKEFILE); + +&touch('a','b'); +sleep(2); +&touch('c'); + +# First try with the file that's not updated "once removed" from the +# file we're including. + +&run_make_with_options($makefile3, "F=a", &get_logfile, 0); + +$answer = "[ -f b ] || touch b\nhello\n"; +&compare_output($answer,&get_logfile(1)); + +# Now try with the file we're not updating being the actual file we're +# including: this and the previous one test different parts of the code. + +&run_make_with_options($makefile3, "F=b", &get_logfile, 0); + +$answer = "[ -f b ] || touch b\nhello\n"; +&compare_output($answer,&get_logfile(1)); + +unlink('a','b','c'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/statipattrules b/tests/scripts/features/statipattrules new file mode 100644 index 0000000..bf2eae7 --- /dev/null +++ b/tests/scripts/features/statipattrules @@ -0,0 +1,71 @@ +$description = "The following test creates a makefile to test static \n" + ."pattern rules. Static pattern rules are rules which \n" + ."specify multiple targets and construct the dependency \n" + ."names for each target based on the target name. "; + +$details = "The makefile created in this test has three targets. The \n" + ."filter command is used to get those target names ending in \n" + .".o and statically creates a compile command with the target\n" + ."name and the target name with .c. It also does the same thing\n" + ."for another target filtered with .elc and creates a command\n" + ."to emacs a .el file"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "files = foo.elc bar.o lose.o \n\n" + ."\$(filter %.o,\$(files)): %.o: %.c\n" + ."\t\@echo CC -c \$(CFLAGS) \$< -o \$@ \n" + ."\$(filter %.elc,\$(files)): %.elc: %.el \n" + ."\t\@echo emacs \$< \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("bar.c","lose.c"); + +# TEST #1 +# ------- + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "CC -c bar.c -o bar.o\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- +&run_make_with_options($makefile,"lose.o",&get_logfile); + +$answer = "CC -c lose.c -o lose.o\n"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 +# ------- +&touch("foo.el"); + +&run_make_with_options($makefile,"foo.elc",&get_logfile); + +$answer = "emacs foo.el\n"; + +&compare_output($answer,&get_logfile(1)); + + + +unlink("foo.el","bar.c","lose.c"); + +1; + + + + + + diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars new file mode 100644 index 0000000..e9fe092 --- /dev/null +++ b/tests/scripts/features/targetvars @@ -0,0 +1,108 @@ +# -*-perl-*- +$description = "Test target-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of target-specific variable +values, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +SHELL = /bin/sh +export FOO = foo +export BAR = bar +one: override FOO = one +one two: ; @echo $(FOO) $(BAR) +two: BAR = two +three: ; BAR=1000 + @echo $(FOO) $(BAR) +# Some things that shouldn't be target vars +funk : override +funk : override adelic +adelic override : ; echo $@ +# Test per-target recursive variables +four:FOO=x +four:VAR$(FOO)=ok +four: ; @echo '$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)' +five:FOO=x +five six : VAR$(FOO)=good +five six: ;@echo '$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)' +# Test per-target variable inheritance +seven: eight +seven eight: ; @echo $@: $(FOO) $(BAR) +seven: BAR = seven +seven: FOO = seven +eight: BAR = eight +# Test the export keyword with per-target variables +nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR +nine: FOO = wallace +# Test = escaping +EQ = = +ten: one\=two +ten: one \= two +ten one$(EQ)two $(EQ):;@echo $@ +.PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two +# Test target-specific vars with pattern/suffix rules +QVAR = qvar +RVAR = = +%.q : ; @echo $(QVAR) $(RVAR) +foo.q : RVAR += rvar +# Target-specific vars with multiple LHS pattern rules +%.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR) +foo.r : RVAR += rvar +foo.t : TVAR := $(QVAR) +EOF + +close(MAKEFILE); + +# TEST #1 + +&run_make_with_options($makefile, "one two three", &get_logfile); +$answer = "one bar\nfoo two\nBAR=1000\nfoo bar\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #2 + +&run_make_with_options($makefile, "one two FOO=1 BAR=2", &get_logfile); +$answer = "one 2\n1 2\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #3 + +&run_make_with_options($makefile, "four", &get_logfile); +$answer = "x ok ok\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile, "seven", &get_logfile); +$answer = "eight: seven eight\nseven: seven seven\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #5 + +&run_make_with_options($makefile, "nine", &get_logfile); +$answer = "wallace bar wallace bar\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #6 + +&run_make_with_options($makefile, "ten", &get_logfile); +$answer = "one=two\none bar\n=\nfoo two\nten\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #6 + +&run_make_with_options($makefile, "foo.q bar.q", &get_logfile); +$answer = "qvar = rvar\nqvar =\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #7 + +&run_make_with_options($makefile, "foo.t bar.s", &get_logfile); +$answer = "qvar = qvar\nqvar =\n"; +&compare_output($answer,&get_logfile(1)); + + +1; diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting new file mode 100644 index 0000000..15d5071 --- /dev/null +++ b/tests/scripts/features/varnesting @@ -0,0 +1,34 @@ +$description = "The following test creates a makefile to ..."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "x = variable1\n" + ."variable2 := Hello\n" + ."y = \$(subst 1,2,\$(x))\n" + ."z = y\n" + ."a := \$(\$(\$(z)))\n" + ."all: \n" + ."\t\@echo \$(a)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "Hello\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath new file mode 100644 index 0000000..101a25d --- /dev/null +++ b/tests/scripts/features/vpath @@ -0,0 +1,62 @@ +$description = "The following test creates a makefile to test the \n" + ."vpath directive which allows you to specify a search \n" + ."path for a particular class of filenames, those that\n" + ."match a particular pattern."; + +$details = "This tests the vpath directive by specifying search directories\n" + ."for one class of filenames with the form: vpath pattern directories" + ."\nIn this test, we specify the working directory for all files\n" + ."that end in c or h. We also test the variables $@ (which gives\n" + ."target name) and $^ (which is a list of all dependencies \n" + ."including the directories in which they were found). It also\n" + ."uses the function firstword used to extract just the first\n" + ."dependency from the entire list."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n"; +print MAKEFILE "edit: \$(objects)\n"; +print MAKEFILE "\t\@echo cc -o \$@ \$^\n"; +print MAKEFILE "main.o : main.c defs.h\n"; +print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n"; +print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c kbd.c\n"; +print MAKEFILE "commands.o : command.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c commands.c\n"; +print MAKEFILE "display.o : display.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c display.c\n"; +print MAKEFILE "insert.o : insert.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c insert.c\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n" + ."cc -c display.c\n" + ."cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o " + ."insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) +{ + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/features/vpath2 b/tests/scripts/features/vpath2 new file mode 100644 index 0000000..7e970a7 --- /dev/null +++ b/tests/scripts/features/vpath2 @@ -0,0 +1,45 @@ +$description = "This is part 2 in a series to test the vpath directive\n" + ."It tests the three forms of the directive:\n" + ." vpath pattern directive\n" + ." vpath pattern (clears path associated with pattern)\n" + ." vpath (clears all paths specified with vpath)\n"; + +$details = "This test simply adds many search paths using various vpath\n" + ."directive forms and clears them afterwards. It has a simple\n" + ."rule to print a message at the end to confirm that the makefile\n" + ."ran with no errors.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $workdir:$sourcedir\n"; +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.c $sourcedir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "vpath %.c\n"; +print MAKEFILE "vpath\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo ALL IS WELL\n"; +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "ALL IS WELL\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath new file mode 100644 index 0000000..581d16d --- /dev/null +++ b/tests/scripts/features/vpathgpath @@ -0,0 +1,64 @@ +# -*-perl-*- +$description = "Tests VPATH+/GPATH functionality."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +GPATH = $(VPATH) + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b ; cat $^ > $@ +%.b : %.c ; cat $^ > $@ +%.c :: %.d ; cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +sub touchfiles { + foreach (@_) { + ($f = $_) =~ s,VP/,$VP,g; + &touch($f); + push(@touchedfiles, $f); + sleep(1); + } +} + +# Run the general-case test + +&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile()); + +push(@touchedfiles, "bar.c"); + +$answer = "$make_name: Nothing to be done for `general'.\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink(@touchedfiles) unless $keep; + +1; diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus new file mode 100644 index 0000000..6c9a2a0 --- /dev/null +++ b/tests/scripts/features/vpathplus @@ -0,0 +1,125 @@ +# -*-perl-*- +$description = "Tests the new VPATH+ functionality added in 3.76."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +SHELL = /bin/sh + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b + cat $^ > $@ +%.b : %.c + cat $^ > $@ 2>/dev/null || exit 1 +%.c :: %.d + cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +# Rename testing info: + +rename: $(VPATH)/foo.c foo.d + +# Target not made testing info: + +notarget: notarget.b +notarget.c: notarget.d + -@echo "not creating $@ from $^" + +# Intermediate files: + +intermediate: inter.a + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +sub touchfiles { + foreach (@_) { + ($f = $_) =~ s,VP/,$VP,g; + &touch($f); + push(@touchedfiles, $f); + # Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second + # granularity of file times. + sleep(2); + } +} + +# Run the general-case test + +&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile); + +push(@touchedfiles, "bar.c"); + +$answer = "cat bar.d > bar.c +cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1 +"; +&compare_output($answer,&get_logfile(1)); + +# Test rules that don't make the target correctly + +&touchfiles("VP/notarget.c", "notarget.b", "notarget.d"); + +&run_make_with_options($makefile,"notarget",&get_logfile,512); + +$answer = "not creating notarget.c from notarget.d +cat notarget.c > notarget.b 2>/dev/null || exit 1 +$make_name: *** [notarget.b] Error 1 +"; + +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 1) + +&touchfiles("VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +push(@touchedfiles, "inter.a", "inter.b"); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.b inter.c +"; +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 2) + +&touchfiles("VP/inter.b", "VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.c +"; +&compare_output($answer,&get_logfile(1)); + +unlink @touchedfiles unless $keep; + +1; diff --git a/tests/scripts/functions/addprefix b/tests/scripts/functions/addprefix new file mode 100644 index 0000000..1845552 --- /dev/null +++ b/tests/scripts/functions/addprefix @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the addprefix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(addprefix src${pathsep},a.b.z.foo hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/addsuffix b/tests/scripts/functions/addsuffix new file mode 100644 index 0000000..d150f07 --- /dev/null +++ b/tests/scripts/functions/addsuffix @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the addsuffix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(addsuffix .c,src${pathsep}a.b.z.foo hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo.c hacks.c\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/basename b/tests/scripts/functions/basename new file mode 100644 index 0000000..08f2ea5 --- /dev/null +++ b/tests/scripts/functions/basename @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the suffix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(basename src${pathsep}a.b.z.foo.c src${pathsep}hacks src.bar${pathsep}a.b.z.foo.c src.bar${pathsep}hacks hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks src.bar${pathsep}a.b.z.foo src.bar${pathsep}hacks hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call new file mode 100644 index 0000000..3303d5b --- /dev/null +++ b/tests/scripts/functions/call @@ -0,0 +1,38 @@ +# -*-perl-*- +$description = "Test the call function.\n"; + +$details = "Try various uses of call and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +# Simple, just reverse something +# +reverse = $2 $1 + +# A complex `map' function, using recursive `call'. +# +map = $(foreach a,$2,$(call $1,$a)) + +# Test using a builtin; this is silly as it's simpler to do without call +# +my-notdir = $(call notdir,$(1)) + +all: ; @echo '$(call reverse,bar,foo)'; \ + echo '$(call map,origin,MAKE reverse map)'; \ + echo '$(call my-notdir,a/b c/d e/f)' + +EOMAKE + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "foo bar\ndefault file file\nb d f\n"; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/functions/dir b/tests/scripts/functions/dir new file mode 100644 index 0000000..f48fb8c --- /dev/null +++ b/tests/scripts/functions/dir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the dir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(dir src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep} .${pathsep}\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/error b/tests/scripts/functions/error new file mode 100644 index 0000000..ca9b4e4 --- /dev/null +++ b/tests/scripts/functions/error @@ -0,0 +1,63 @@ +$description = "\ +The following test creates a makefile to test the error function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +ifdef ERROR1 +$(error error is $(ERROR1)) +endif + +ifdef ERROR2 +$(error error is $(ERROR2)) +endif + +ifdef ERROR3 +all: some; @echo $(error error is $(ERROR3)) +endif + +ifdef ERROR4 +all: some; @echo error is $(ERROR4) + @echo $(error error is $(ERROR4)) +endif + +some: ; @echo Some stuff + +EOF + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "ERROR1=yes", &get_logfile, 512); +$answer = "$makefile:2: *** error is yes. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "ERROR2=no", &get_logfile, 512); +$answer = "$makefile:6: *** error is no. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "ERROR3=maybe", &get_logfile, 512); +$answer = "Some stuff\n$makefile:10: *** error is maybe. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512); +$answer = "Some stuff\n$makefile:14: *** error is definitely. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/filter-out b/tests/scripts/functions/filter-out new file mode 100644 index 0000000..0559a8d --- /dev/null +++ b/tests/scripts/functions/filter-out @@ -0,0 +1,35 @@ +$description = "The following test creates a makefile to test static \n" + ."pattern rules. Static pattern rules are rules which \n" + ."specify multiple targets and construct the dependency \n" + ."names for each target based on the target name. "; + +$details = "The makefile created in this test has three targets. The \n" + ."filter command is used to get those target names ending in \n" + .".o and statically creates a compile command with the target\n" + ."name and the target name with .c. It also does the same thing\n" + ."for another target filtered with .elc and creates a command\n" + ."to emacs a .el file"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "files := \$(filter-out %.o, foo.elc bar.o lose.o) \n" + ."all: \n" + ."\t\@echo \$(files) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "foo.elc\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/findstring b/tests/scripts/functions/findstring new file mode 100644 index 0000000..48abede --- /dev/null +++ b/tests/scripts/functions/findstring @@ -0,0 +1,47 @@ +$description = "The following test creates a makefile to test the findstring " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(findstring port, reporter)\n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "port\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/foreach b/tests/scripts/functions/foreach new file mode 100644 index 0000000..0c63c47 --- /dev/null +++ b/tests/scripts/functions/foreach @@ -0,0 +1,53 @@ +# -*-perl-*- + +# Updated 6.16.93 variable "MAKE" is default was environment override +# For make 3.63 and above + +$description = "The following test creates a makefile to verify +test the foreach function."; + +$details = "This is a test of the foreach function in gnu make. +This function starts with a space separated list of +names and a variable. Each name in the list is subsituted +into the variable and the given text evaluated. The general +form of the command is $(foreach var,$list,$text). Several +types of foreach loops are tested\n"; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +# On WIN32 systems, the user's path is found in %Path% ($Path) +# +$pathvar = (($osname =~ /Windows/i) ? "Path" : "PATH"); + +print MAKEFILE <<EOF; +foo = bletch null \@ garf +null := +space = ' ' +auto_var = udef space CC null $pathvar MAKE foo CFLAGS WHITE \@ < +av = \$(foreach var, \$(auto_var), \$(origin \$(var)) ) +override WHITE := BLACK +for_var = \$(addsuffix .c,foo \$(null) \$(foo) \$(space) \$(av) ) +fe = \$(foreach var2, \$(for_var),\$(subst .c,.o, \$(var2) ) ) +all: auto for2 +auto : +\t\@echo \$(av) +for2: +\t\@echo \$(fe) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, + "-e WHITE=WHITE CFLAGS=", + &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "undefined file default file environment default file command line override automatic automatic +foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/if b/tests/scripts/functions/if new file mode 100644 index 0000000..cb1f5fc --- /dev/null +++ b/tests/scripts/functions/if @@ -0,0 +1,31 @@ +# -*-perl-*- +$description = "Test the if function.\n"; + +$details = "Try various uses of if and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +print MAKEFILE <<EOMAKE; +NEQ = \$(subst \$1,,\$2) + +all: +\t\@echo \$(if ,true,false) +\t\@echo \$(if ,true,) +\t\@echo \$(if ,true) +\t\@echo \$(if z,true,false) +\t\@echo \$(if z,true,\$(shell echo hi)) +\t\@echo \$(if ,\$(shell echo hi),false) +\t\@echo \$(if \$(call NEQ,a,b),true,false) +\t\@echo \$(if \$(call NEQ,a,a),true,false) +\t\@echo \$(if z,true,fal,se) +\t\@echo \$(if ,true,fal,se) +EOMAKE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "false\n\n\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue\nfal,se\n"; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/functions/join b/tests/scripts/functions/join new file mode 100644 index 0000000..302c307 --- /dev/null +++ b/tests/scripts/functions/join @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the join " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(join a b c,foo hacks .pl1) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "afoo bhacks c.pl1\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/notdir b/tests/scripts/functions/notdir new file mode 100644 index 0000000..4ed8f9c --- /dev/null +++ b/tests/scripts/functions/notdir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the notdir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(notdir ${pathsep}src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "foo.c hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/origin b/tests/scripts/functions/origin new file mode 100644 index 0000000..721d928 --- /dev/null +++ b/tests/scripts/functions/origin @@ -0,0 +1,65 @@ +# -*-perl-*- + +$description = "Test the origin function."; + +$details = "This is a test of the origin function in gnu make. +This function will report on where a variable was +defined per the following list: + +'undefined' never defined +'default' default definition +'environment' environment var without -e +'environment override' environment var with -e +'file' defined in makefile +'command line' defined on the command line +'override' defined by override in makefile +'automatic' Automatic variable\n"; + +# On WIN32 systems, HOME is meaningless. SystemRoot should be defined though. +# With DJGPP, HOME is not guaranteed to be defined. Use DJDIR instead. +# +$homevar = (($osname =~ /Windows/i) + ? "SystemRoot" + : (($osname =~ /DOS/i) ? "DJDIR" : "HOME")); + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<EOF; +foo := bletch garf +auto_var = udef CC $homevar MAKE foo CFLAGS WHITE \@ +av = \$(foreach var, \$(auto_var), \$(origin \$(var)) ) +override WHITE := BLACK +all: auto +\t\@echo \$(origin undefined) +\t\@echo \$(origin CC) +\t\@echo \$(origin $homevar) +\t\@echo \$(origin MAKE) +\t\@echo \$(origin foo) +\t\@echo \$(origin CFLAGS) +\t\@echo \$(origin WHITE) +\t\@echo \$(origin \@) +auto : +\t\@echo \$(av) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, + "-e WHITE=WHITE CFLAGS=", + &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "undefined default environment default file command line override automatic +undefined +default +environment +default +file +command line +override +automatic\n"; + + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/sort b/tests/scripts/functions/sort new file mode 100644 index 0000000..d472102 --- /dev/null +++ b/tests/scripts/functions/sort @@ -0,0 +1,55 @@ +$description = "The following test creates a makefile to verify\n" + ."the ability of make to sort lists of object. Sort\n" + ."will also remove any duplicate entries. This will also\n" + ."be tested."; + +$details = "The make file is built with a list of object in a random order\n" + ."and includes some duplicates. Make should sort all of the elements\n" + ."remove all duplicates\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo := moon_light days \n" + ."foo1:= jazz\n" + ."bar := captured \n" + ."bar2 = boy end, has rise A midnight \n" + ."bar3:= \$(foo)\n" + ."s1 := _by\n" + ."s2 := _and_a\n" + ."t1 := \$(addsuffix \$(s1), \$(bar) )\n" + ."t2 := \$(addsuffix \$(s2), \$(foo1) )\n" + ."t3 := \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \n" + ."t4 := \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \n" + ."t5 := \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \n" + ."t6 := \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \n" + ."t7 := \$(t6) \$(t6) \$(t6) \n" + ."p1 := \$(addprefix \$(foo1), \$(s2) )\n" + ."blank:= \n" + ."all:\n" + ."\t\@echo \$(sort \$(bar2) \$(foo) \$(addsuffix \$(s1), \$(bar) ) \$(t2) \$(bar2) \$(bar3))\n" + ."\t\@echo \$(sort \$(blank) \$(foo) \$(bar2) \$(t1) \$(p1) )\n" + ."\t\@echo \$(sort \$(foo) \$(bar2) \$(t1) \$(t4) \$(t5) \$(t7) \$(t6) )\n"; + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" + ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" + ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/functions/strip b/tests/scripts/functions/strip new file mode 100644 index 0000000..1f487c0 --- /dev/null +++ b/tests/scripts/functions/strip @@ -0,0 +1,53 @@ +# -*-perl-*- +$description = "The following test creates a makefile to verify +the ability of make to strip white space from lists of object.\n"; + + +$details = "The make file is built with a list of objects that contain white space +These are then run through the strip command to remove it. This is then +verified by echoing the result.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +TEST1 := "Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING..." +E := +TEST2 := $E try this and this $E + +define TEST3 + +and these test out + + +some +blank lines + + + +endef + +.PHONY: all +all: + @echo '$(strip $(TEST1) )' + @echo '$(strip $(TEST2) )' + @echo '$(strip $(TEST3) )' + +EOMAKE + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "\"Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING...\" +try this and this +and these test out some blank lines +"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/substitution b/tests/scripts/functions/substitution new file mode 100644 index 0000000..9280dbb --- /dev/null +++ b/tests/scripts/functions/substitution @@ -0,0 +1,37 @@ +$description = "The following test creates a makefile to ..."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo := a.o b.o c.o\n" + ."bar := \$(foo:.o=.c)\n" + ."bar2:= \$(foo:%.o=%.c)\n" + ."bar3:= \$(patsubst %.c,%.o,x.c.c bar.c)\n" + ."all:\n" + ."\t\@echo \$(bar)\n" + ."\t\@echo \$(bar2)\n" + ."\t\@echo \$(bar3)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "a.c b.c c.c\n" + ."a.c b.c c.c\n" + ."x.c.o bar.o\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/functions/suffix b/tests/scripts/functions/suffix new file mode 100644 index 0000000..0c4f919 --- /dev/null +++ b/tests/scripts/functions/suffix @@ -0,0 +1,57 @@ +$description = "The following test creates a makefile to test the suffix\n" + ."function. \n"; + +$details = "The suffix function will return the string following the last _._\n" + ."the list provided. It will provide all of the unique suffixes found\n" + ."in the list. The long strings are sorted to remove duplicates.\n"; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := word.pl general_test2.pl1 FORCE.pl word.pl3 generic_test.perl /tmp.c/bar foo.baz/bar.c MAKEFILES_variable.c\n" + ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" + ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" + ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" + ."all: \n" + ."\t\@echo \$(suffix \$(string)) \n" + ."\t\@echo \$(sort \$(suffix \$(string4))) \n" + ."\t\@echo \$(suffix \$(string) a.out) \n" + ."\t\@echo \$(sort \$(suffix \$(string3))) \n"; + + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile + +# COMPARE RESULTS +$answer = ".pl .pl1 .pl .pl3 .perl .c .c\n" + .".c .perl .pl .pl1 .pl3\n" + .".pl .pl1 .pl .pl3 .perl .c .c .out\n" + .".c .perl .pl .pl1 .pl3\n"; + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/warning b/tests/scripts/functions/warning new file mode 100644 index 0000000..ac0ad64 --- /dev/null +++ b/tests/scripts/functions/warning @@ -0,0 +1,63 @@ +$description = "\ +The following test creates a makefile to test the warning function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +ifdef WARNING1 +$(warning warning is $(WARNING1)) +endif + +ifdef WARNING2 +$(warning warning is $(WARNING2)) +endif + +ifdef WARNING3 +all: some; @echo hi $(warning warning is $(WARNING3)) +endif + +ifdef WARNING4 +all: some; @echo hi + @echo there $(warning warning is $(WARNING4)) +endif + +some: ; @echo Some stuff + +EOF + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "WARNING1=yes", &get_logfile, 0); +$answer = "$makefile:2: warning is yes\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "WARNING2=no", &get_logfile, 0); +$answer = "$makefile:6: warning is no\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "WARNING3=maybe", &get_logfile, 0); +$answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0); +$answer = "Some stuff\n$makefile:14: warning is definitely\nhi\nthere\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard new file mode 100644 index 0000000..d21747f --- /dev/null +++ b/tests/scripts/functions/wildcard @@ -0,0 +1,103 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test wildcard\n" + ."expansions and the ability to put a command on the same\n" + ."line as the target name separated by a semi-colon."; + +$details = "This test creates 4 files by the names of 1.example, \n" + ."two.example and 3.example. We execute three tests. The first\n" + ."executes the print1 target which tests the '*' wildcard by \n" + ."echoing all filenames by the name of '*.example'. The second\n" + ."test echo's all files which match '?.example' and \n" + ."[a-z0-9].example. Lastly we clean up all of the files using\n" + ."the '*' wildcard as in the first test"; + +if ($vos) +{ + $delete_command = "delete_file -no_ask"; +} +else +{ + $delete_command = "rm"; +} + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOM; +print1: ;\@echo \$(wildcard example.*) +print2: +\t\@echo \$(wildcard example.?) +\t\@echo \$(wildcard example.[a-z0-9]) +\t\@echo \$(wildcard example.[!A-Za-z_\\!]) +clean: +\t$delete_command \$(wildcard example.*) +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("example.1"); +&touch("example.two"); +&touch("example.3"); +&touch("example.for"); +&touch("example._"); + +# TEST #1 +# ------- + +$answer = "example.1 example.3 example._ example.for example.two\n"; + +&run_make_with_options($makefile,"print1",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +$answer = "example.1 example.3 example._\n" + ."example.1 example.3\n" + ."example.1 example.3\n"; + +&run_make_with_options($makefile,"print2",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 +# ------- + +$answer = "$delete_command example.1 example.3 example._ example.for example.two"; +if ($vos) +{ + $answer .= " \n"; +} +else +{ + $answer .= "\n"; +} + +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) +{ + $test_passed = 0; +} + + +1; + + + + + + + + + diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word new file mode 100644 index 0000000..f786e47 --- /dev/null +++ b/tests/scripts/functions/word @@ -0,0 +1,70 @@ +$description = "The following test creates a makefile to test the word, words,\n" + ."and wordlist functions.\n"; + +$details = "The word function will return the number of words in a variable or\n" + ."the word specified. The test will produce a variable with a large\n" + ."number of words in it, determine the number of word and then read\n" + ."each one back.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl \n" + ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" + ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" + ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" + ."all: \n" + ."\t\@echo \$(words \$(string)) \n" + ."\t\@echo \$(words \$(string4)) \n" + ."\t\@echo \$(word 1, \$(string)) \n" + ."\t\@echo \$(word 100, \$(string)) \n" + ."\t\@echo \$(word 1, \$(string)) \n" + ."\t\@echo \$(word 1000, \$(string3)) \n" + ."\t\@echo \$(wordlist 3, 4, \$(string)) \n" + ."\t\@echo \$(wordlist 4, 3, \$(string)) \n" + ."\t\@echo \$(wordlist 1, 6, \$(string)) \n" + ."\t\@echo \$(wordlist 7, 5, \$(string)) \n" + ."\t\@echo \$(wordlist 100, 110, \$(string)) \n" + ."\t\@echo \$(wordlist 7, 10, \$(string2)) \n" +; + + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile + +# COMPARE RESULTS +$answer = "6\n" + ."2058\n" + ."word.pl\n" + ."\n" + ."word.pl\n" + ."\n" + ."FORCE.pl word.pl\n" + ."FORCE.pl word.pl\n" + ."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n" + ."generic_test.perl MAKEFILES_variable.pl\n" + ."\n" + ."word.pl general_test2.pl FORCE.pl word.pl\n" +; + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/misc/general1 b/tests/scripts/misc/general1 new file mode 100644 index 0000000..352fc6a --- /dev/null +++ b/tests/scripts/misc/general1 @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It mimics the +rebuilding of a product with dependencies. +It also tests the simple definition of VPATH."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<EOF; +VPATH = $workdir +edit: main.o kbd.o commands.o display.o \\ + insert.o +\t\@echo cc -o edit main.o kbd.o commands.o display.o \\ + insert.o +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +# COMPARE RESULTS + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general2 b/tests/scripts/misc/general2 new file mode 100644 index 0000000..fb5c3aa --- /dev/null +++ b/tests/scripts/misc/general2 @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It is the same as +general_test1 except that this one tests the +definition of a variable to hold the object filenames."; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +VPATH = $workdir +objects = main.o kbd.o commands.o display.o insert.o +edit: \$(objects) +\t\@echo cc -o edit \$(objects) +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general3 b/tests/scripts/misc/general3 new file mode 100644 index 0000000..a265f71 --- /dev/null +++ b/tests/scripts/misc/general3 @@ -0,0 +1,45 @@ +# -*-perl-*- + +$description = "\ +This tests random features of the parser that need to be supported, and +which have either broken at some point in the past or seem likely to +break."; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +\# We want to allow both empty commands _and_ commands that resolve to empty. +EMPTY = + +.PHONY: all a1 a2 a3 a4 +all: a1 a2 a3 a4 + +a1:; +a2: +\t +a3:;\$(EMPTY) +a4: +\t\$(EMPTY) + +\# Non-empty lines that expand to nothing should also be ignored. +STR = \# Some spaces +TAB = \t \# A TAB and some spaces + +\$(STR) + +\$(STR) \$(TAB) + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Nothing to be done for `all'.\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/misc/version b/tests/scripts/misc/version new file mode 100644 index 0000000..d49b153 --- /dev/null +++ b/tests/scripts/misc/version @@ -0,0 +1,35 @@ +$description = "The following test creates a makefile to ... \n"; + +$details = "Fill in Later\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"-v",&get_logfile,0); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + + + + + + + + + + + + diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C new file mode 100644 index 0000000..3f2b3a1 --- /dev/null +++ b/tests/scripts/options/dash-C @@ -0,0 +1,48 @@ +$description = "The following test creates a makefile to test the -C dir \n" + ."option in make. This option tells make to change to \n" + ."directory dir before reading the makefile."; + +$details = "This test is similar to the clean test except that this test\n" + ."creates the file to delete in the work directory instead of\n" + ."the current directory. Make is called from another directory\n" + ."using the -C workdir option so that it can both find the \n" + ."makefile and the file to delete in the work directory. "; + +$example = $workdir . $pathsep . "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir clean", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory `$wpath'\n" + . "$delete_command EXAMPLE_FILE\n" + . "$make_name: Leaving directory `$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + +if (-f $example) +{ + $test_passed = 0; +} + +1; diff --git a/tests/scripts/options/dash-I b/tests/scripts/options/dash-I new file mode 100644 index 0000000..0be0bd7 --- /dev/null +++ b/tests/scripts/options/dash-I @@ -0,0 +1,57 @@ +$description ="The following test creates a makefile to test the -I option."; + +$details = "\ +This test tests the -I option by including a filename in +another directory and giving make that directory name +under -I in the command line. Without this option, the make +would fail to find the included file. It also checks to make +sure that the -I option gets passed to recursive makes."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +$mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1); +print MAKEFILE <<EOF; +include $mf2 +all: +\t\@echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<EOF; +ANOTHER: +\t\@echo This is another included makefile +recurse: +\t\$(MAKE) ANOTHER -f $makefile +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile,"-I $workdir all",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer,&get_logfile(1)); + + +$answer = "This is another included makefile\n"; +&run_make_with_options($makefile,"-I $workdir ANOTHER",&get_logfile); +&compare_output($answer,&get_logfile(1)); + + +$answer = "$mkpath ANOTHER -f $makefile +${make_name}[1]: Entering directory `$pwd' +This is another included makefile +${make_name}[1]: Leaving directory `$pwd'\n"; + +&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile); +&compare_output($answer,&get_logfile(1)); diff --git a/tests/scripts/options/dash-e b/tests/scripts/options/dash-e new file mode 100644 index 0000000..472270d --- /dev/null +++ b/tests/scripts/options/dash-e @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to ..."; + +$details = ""; + +$ENV{GOOGLE} = 'boggle'; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +GOOGLE = bazzle +all:; @echo "$(GOOGLE)" +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, '-e' ,&get_logfile); + +$answer = "boggle\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/options/dash-f b/tests/scripts/options/dash-f new file mode 100644 index 0000000..3aa4746 --- /dev/null +++ b/tests/scripts/options/dash-f @@ -0,0 +1,85 @@ +$description = "The following test tests that if you specify greater \n" + ."than one '-f makefilename' on the command line, \n" + ."that make concatenates them. This test creates three \n" + ."makefiles and specifies all of them with the -f option \n" + ."on the command line. To make sure they were concatenated, \n" + ."we then call make with the rules from the concatenated \n" + ."makefiles one at a time. Finally, it calls all three \n" + ."rules in one call to make and checks that the output\n" + ."is in the correct order."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This is the output from the original makefile\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# Create a second makefile +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "TWO: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 2\n"; +close(MAKEFILE); + +# Create a third makefile +open(MAKEFILE,"> $makefile3"); +print MAKEFILE "THREE: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 3\n"; +close(MAKEFILE); + + +# Create the answer to what should be produced by this Makefile +$answer = "This is the output from the original makefile\n"; + +# Run make to catch the default rule +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the second makefile: TWO +$answer = "This is the output from makefile 2\n"; + +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3 TWO",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the third makefile: THREE + +$answer = "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with ALL three rules in the order 2 1 3 to make sure +# that all rules are executed in the proper order + +$answer = "This is the output from makefile 2\n"; +$answer .= "This is the output from the original makefile\n"; +$answer .= "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 TWO all THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + + + + + + + + + diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k new file mode 100644 index 0000000..a5baaf7 --- /dev/null +++ b/tests/scripts/options/dash-k @@ -0,0 +1,73 @@ +$description = "The following test creates a makefile to test the -k option.\n" + ."Normally, make gives up immediately if an error happens \n" + ."that make has not been told to ignore. However, if the -k\n" + ."option is specified, make continues to consider the other\n" + ."dependencies of the pending targets."; + +$details = "The makefile created in this test is a simulation of building \n" + ."a small product. However, the trick to this one is that one \n" + ."of the dependencies of the main target does not exist. \n" + ."Without the -k option, make would fail immediately and not \n" + ."build any part of the target. What we are looking for here, \n" + ."is that make builds the rest of the dependencies even though \n" + ."it knows that at the end it will fail to rebuild the main target."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $workdir\n"; +print MAKEFILE "edit: main.o kbd.o commands.o display.o \n"; +print MAKEFILE "\t\@echo cc -o edit main.o kbd.o commands.o display.o \n"; + +print MAKEFILE "main.o : main.c defs.h\n"; +print MAKEFILE "\t\@echo cc -c main.c\n"; + +print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c kbd.c\n"; + +print MAKEFILE "commands.o : command.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c commands.c\n"; + +print MAKEFILE "display.o : display.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c display.c\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +if ($vos) +{ + $error_code = 3307; +} +else +{ + $error_code = 512; +} + +&run_make_with_options($makefile,"-k",&get_logfile,$error_code); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\n" + ."$make_name: *** No rule to make target `kbd.c', needed by `kbd.o'.\n" + ."cc -c commands.c\n" + ."cc -c display.c\n" + ."$make_name: Target `edit' not remade because of errors.\n"; + +# COMPARE RESULTS + +if (&compare_output($answer,&get_logfile(1))) +{ + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/options/dash-l b/tests/scripts/options/dash-l new file mode 100644 index 0000000..445b869 --- /dev/null +++ b/tests/scripts/options/dash-l @@ -0,0 +1,55 @@ +# -*-perl-*- +# Date: Tue, 11 Aug 1992 09:34:26 -0400 +# From: pds@lemming.webo.dg.com (Paul D. Smith) + +$description = "Test load balancing (-l) option."; + +$details = "\ +This test creates a makefile where all depends on three rules +which contain the same body. Each rule checks for the existence +of a temporary file; if it exists an error is generated. If it +doesn't exist then it is created, the rule sleeps, then deletes +the temp file again. Thus if any of the rules are run in +parallel the test will fail. When make is called in this test, +it is given the -l option with a value of 0.0001. This ensures +that the load will be above this number and make will therefore +decide that it cannot run more than one job even though -j 4 was +also specified on the command line."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOF'; +SHELL = /bin/sh + +define test +if [ ! -f test-file ]; then \ + touch test-file; sleep 2; rm -f test-file; \ +else \ + echo $@ FAILED; \ +fi +endef + +all : ONE TWO THREE +ONE : ; @$(test) +TWO : ; @$(test) +THREE : ; @$(test) +EOF + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +$mkoptions = "-l 0.0001"; +$mkoptions .= " -j 4" if ($parallel_jobs); + +&run_make_with_options($makefile, $mkoptions, &get_logfile); + +$slurp = &read_file_into_string (&get_logfile(1)); +if ($slurp !~ /cannot enforce load limit/) { + &compare_output("", &get_logfile(1)); +} + +1; diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n new file mode 100644 index 0000000..97dac7a --- /dev/null +++ b/tests/scripts/options/dash-n @@ -0,0 +1,31 @@ +# -*-perl-*- +$description = "Test the -n option.\n"; + +$details = "Try various uses of -n and ensure they all give the correct results.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; + +final: intermediate ; touch $@ +intermediate: orig ; touch $@ + +EOMAKE + +close(MAKEFILE); + +&touch('orig'); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "touch intermediate\ntouch final\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile, "-Worig -n", &get_logfile); +$answer = "touch intermediate\ntouch final\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('orig', 'intermediate', 'final'); + +1; diff --git a/tests/scripts/targets/DEFAULT b/tests/scripts/targets/DEFAULT new file mode 100644 index 0000000..0cabde9 --- /dev/null +++ b/tests/scripts/targets/DEFAULT @@ -0,0 +1,53 @@ +$description = "The following test creates a makefile to override part\n" + ."of one Makefile with Another Makefile with the .DEFAULT\n" + ."rule."; + +$details = "This tests the use of the .DEFAULT special target to say that \n" + ."to remake any target that cannot be made fram the information\n" + ."in the containing makefile, make should look in another makefile\n" + ."This test gives this makefile the target bar which is not \n" + ."defined here but passes the target bar on to another makefile\n" + ."which does have the target bar defined.\n"; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo:\n"; +print MAKEFILE "\t\@echo Executing rule FOO\n\n"; +print MAKEFILE ".DEFAULT:\n"; +print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "bar:\n"; +print MAKEFILE "\t\@echo Executing rule BAR\n\n"; + +close(MAKEFILE); + +&run_make_with_options($makefile,'bar',&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "${make_name}[1]: Entering directory `$pwd'\n" + . "Executing rule BAR\n" + . "${make_name}[1]: Leaving directory `$pwd'\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/targets/FORCE b/tests/scripts/targets/FORCE new file mode 100644 index 0000000..90ee48d --- /dev/null +++ b/tests/scripts/targets/FORCE @@ -0,0 +1,52 @@ +$description = "The following tests rules without Commands or Dependencies."; + +$details = "If the rule ...\n"; + +if ($vos) +{ + $delete_command = "delete_file"; +} +else +{ + $delete_command = "rm"; +} + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".IGNORE :\n"; +print MAKEFILE "clean: FORCE\n"; +print MAKEFILE "\t$delete_command clean\n"; +print MAKEFILE "FORCE:\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +if (-f $example) +{ + $test_passed = 0; +} + +1; + + + + + + + + + diff --git a/tests/scripts/targets/INTERMEDIATE b/tests/scripts/targets/INTERMEDIATE new file mode 100644 index 0000000..3ea6421 --- /dev/null +++ b/tests/scripts/targets/INTERMEDIATE @@ -0,0 +1,86 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .INTERMEDIATE target."; + +$details = "\ +Test the behavior of the .INTERMEDIATE special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .INTERMEDIATE. Build and ensure it's +deleted properly. Rebuild to ensure that it's not created if it doesn't +exist but doesn't need to be built. Change the original and ensure +that the intermediate file and the ultimate target are both rebuilt, and +that the intermediate file is again deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.INTERMEDIATE: foo.e bar.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e bar.e; cat $^ > $@ +EOF + +close(MAKEFILE); + +# TEST #0 + +&touch('foo.f'); +&touch('bar.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #1 + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second +# granularity of file times. +sleep(2); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second +# granularity of file times. +sleep(2); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar.e\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/PHONY b/tests/scripts/targets/PHONY new file mode 100644 index 0000000..14d5ae1 --- /dev/null +++ b/tests/scripts/targets/PHONY @@ -0,0 +1,62 @@ +$description = "The following tests the use of a PHONY target. It makes\n" + ."sure that the rules under a target get executed even if\n" + ."a filename of the same name of the target exists in the\n" + ."directory.\n"; + +$details = "This makefile in this test declares the target clean to be a \n" + ."PHONY target. We then create a file named \"clean\" in the \n" + ."directory. Although this file exists, the rule under the target\n" + ."clean should still execute because of it's phony status."; + +if ($vos) +{ + $delete_command = "delete_file"; +} +else +{ + $delete_command = "rm"; +} + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".PHONY : clean \n"; +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command $example clean\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command $example clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +if (-f $example) +{ + $test_passed = 0; +} + +1; + + + + + + + + + diff --git a/tests/scripts/targets/SECONDARY b/tests/scripts/targets/SECONDARY new file mode 100644 index 0000000..dbf052d --- /dev/null +++ b/tests/scripts/targets/SECONDARY @@ -0,0 +1,89 @@ +#! -*-perl-*- + +$description = "Test the behaviour of the .SECONDARY target."; + +$details = "\ +Test the behavior of the .SECONDARY special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .SECONDARY. Build and note that it's +not automatically deleted. Delete the file. Rebuild to ensure that +it's not created if it doesn't exist but doesn't need to be built. +Change the original and ensure that the secondary file and the ultimate +target are both rebuilt, and that the secondary file is not deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.SECONDARY: foo.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e ; cp $< $@ +EOF + +close(MAKEFILE); + +# TEST #1 + +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second +# granularity of file times. +sleep(2); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 + +# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second +# granularity of file times. +sleep(2); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/SILENT b/tests/scripts/targets/SILENT new file mode 100644 index 0000000..375cad4 --- /dev/null +++ b/tests/scripts/targets/SILENT @@ -0,0 +1,51 @@ +$description = "The following tests the special target .SILENT. By simply\n" + ."mentioning this as a target, it tells make not to print\n" + ."commands before executing them."; + +$details = "This test is the same as the clean test except that it should\n" + ."not echo its command before deleting the specified file.\n"; + +if ($vos) +{ + $delete_command = "delete_file"; +} +else +{ + $delete_command = "rm"; +} + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".SILENT : clean\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +$answer = ""; +&run_make_with_options($makefile,"clean",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); +if (-f $example) +{ + $test_passed = 0; +} + +1; + + + + + + + + + diff --git a/tests/scripts/targets/clean b/tests/scripts/targets/clean new file mode 100644 index 0000000..69f4fd1 --- /dev/null +++ b/tests/scripts/targets/clean @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to delete a \n" + ."file in the directory. It tests to see if make will \n" + ."NOT execute the command unless the rule is given in \n" + ."the make command line."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "This makefile did not clean the dir... good\n"; + +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + + +$answer = "$delete_command $example\n"; +&run_make_with_options($makefile,"clean",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)) || &error ("abort"); +if (-f $example) { + $test_passed = 0; +} + +1; + + + + + + + + + diff --git a/tests/scripts/test_template b/tests/scripts/test_template new file mode 100644 index 0000000..773ced3 --- /dev/null +++ b/tests/scripts/test_template @@ -0,0 +1,70 @@ +$description = "The following test creates a makefile to ... + <FILL IN DESCRIPTION HERE> "; + +$details = "<FILL IN DETAILS OF HOW YOU TEST WHAT YOU SAY YOU ARE TESTING>"; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE " <FILL IN THE CONTENTS OF THE MAKEFILE HERE> \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +# Run make. You may specify a makefile, but if you don't want to, just +# insert "" where $make_filename is now. You may also specify specific +# options to run make with, but you also don't have to. (Insert "" where it +# says <FILL IN OPTIONS HERE>), The last field in this subroutine call +# is the code which is returned from make. If you think that make should +# execute with no errors, you may OPTIONALLY put 0; Otherwise put the +# error code that you expect back from make for this test. + +# Every time you run make, you just need to say &get_logfile and that +# subroutine will get a new logfile name for you in incrementing order +# according to how many times you call it within ONE test. It is +# reset to 0 at the beginning of every new test script. + +&run_make_with_options($makefile, + "<FILL IN OPTIONS HERE>", + &get_logfile, + 0); + + +# THE REST OF THIS FILE DEPENDS HIGHLY ON WHAT KIND OF TEST YOU ARE +# CREATING, SO IT WILL VARY. BASICALLY, YOU MAY INSERT ANYTHING YOU +# WISH AT THIS POINT TO SEE IF THE TEST WORKED OK. IF THERE ARE +# ADDITIONAL TESTS BESIDES &compare_output, AND IT FAILES, YOU +# MUST *** SET $test_passed = 0 !!! *** + +# Create the answer to what should be produced by this Makefile +$answer = "<INSERT ANSWER HERE>"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# If you wish to &error ("abort +") if the compare fails, then add a "|| &error ("abort +")" to the +# end of the previous line. + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/CURDIR b/tests/scripts/variables/CURDIR new file mode 100644 index 0000000..a4054bc --- /dev/null +++ b/tests/scripts/variables/CURDIR @@ -0,0 +1,18 @@ +$description = "This tests the CURDIR varaible."; + +$details = "Echo CURDIR both with and without -C. Also ensure overrides work."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "all: ; \@echo \$(CURDIR)\n"; +close(MAKEFILE); + + +# TEST #1 +# ------- + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "$pwd\n"; +&compare_output($answer,&get_logfile(1)); + + +1; diff --git a/tests/scripts/variables/MAKE b/tests/scripts/variables/MAKE new file mode 100644 index 0000000..7c4cf0a --- /dev/null +++ b/tests/scripts/variables/MAKE @@ -0,0 +1,33 @@ +$description = "The following test creates a makefile to test MAKE \n" + ."(very generic)"; + +$details = "DETAILS"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "TMP := \$(MAKE)\n"; +print MAKEFILE "MAKE := \$(subst X=\$(X),,\$(MAKE))\n\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo \$(TMP)\n"; +print MAKEFILE "\t\$(MAKE) -f $makefile foo\n\n"; +print MAKEFILE "foo:\n"; +print MAKEFILE "\t\@echo \$(MAKE)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# Create the answer to what should be produced by this Makefile +$answer = "$mkpath\n$mkpath -f $makefile foo\n" + . "${make_name}[1]: Entering directory `$pwd'\n" + . "$mkpath\n${make_name}[1]: Leaving directory `$pwd'\n"; + +&run_make_with_options($makefile,"",&get_logfile,0); + +&delete("foo"); +# COMPARE RESULTS +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/MAKECMDGOALS b/tests/scripts/variables/MAKECMDGOALS new file mode 100644 index 0000000..ec33358 --- /dev/null +++ b/tests/scripts/variables/MAKECMDGOALS @@ -0,0 +1,50 @@ +$description = "The following test creates a makefile to test the MAKECMDGOALS variable."; + +$details = "\ +We construct a makefile with various targets, all of which print out +\$(MAKECMDGOALS), then call it different ways."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "\ +.DEFAULT all: + \@echo \$(MAKECMDGOALS) +"; +close(MAKEFILE); + +# TEST #1 + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #2 + +&run_make_with_options($makefile, + "all", + &get_logfile, + 0); +$answer = "all\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 + +&run_make_with_options($makefile, + "foo bar baz yaz", + &get_logfile, + 0); +$answer = "foo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/MAKEFILES b/tests/scripts/variables/MAKEFILES new file mode 100644 index 0000000..d42909c --- /dev/null +++ b/tests/scripts/variables/MAKEFILES @@ -0,0 +1,37 @@ +$description = "The following test creates a makefile to test "; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +# The Contents of the MAKEFILE ... +print MAKEFILE "MAKEFILES = work/MAKEFILES_variable.mk.2\n\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo THIS IS THE DEFAULT RULE\n"; +# END of Contents of MAKEFILE +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "NDEF:\n"; +print MAKEFILE "\t\@echo THIS IS THE RULE FROM MAKEFILE 2\n"; +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = "THIS IS THE DEFAULT RULE\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. + +&compare_output($answer,&get_logfile(1)); + +# If you wish to stop if the compare fails, then add +# a "|| &error ("abort")" to the +# end of the previous line. + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/variables/MAKELEVEL b/tests/scripts/variables/MAKELEVEL new file mode 100644 index 0000000..79a184e --- /dev/null +++ b/tests/scripts/variables/MAKELEVEL @@ -0,0 +1,34 @@ +# -*-perl-mode-*- + +$description = "The following test creates a makefile to test +makelevels in Make. It prints \$(MAKELEVEL) and then +prints the environment variable MAKELEVEL"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +SHELL = /bin/sh +all: +\t\@echo MAKELEVEL is \$(MAKELEVEL) +\techo \$\$MAKELEVEL +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# RUN MAKE + +&run_make_with_options($makefile,"",&get_logfile); + +# SET ANSWER + +$answer = "MAKELEVEL is 0\necho \$MAKELEVEL\n1\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors new file mode 100644 index 0000000..7642636 --- /dev/null +++ b/tests/scripts/variables/flavors @@ -0,0 +1,68 @@ +# -*-perl-*- + +$description = "Test various flavors of make variable setting."; + +$details = ""; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOF'; +foo = $(bar) +bar = ${ugh} +ugh = Hello + +all: multi ; @echo $(foo) + +multi: ; $(multi) + +x := foo +y := $(x) bar +x := later + +nullstring := +space := $(nullstring) $(nullstring) + +next: ; @echo $x$(space)$y + +define multi +@echo hi +@echo there +endef + +ifdef BOGUS +define +@echo error +endef +endif + +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# TEST #1 +# ------- + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "hi\nthere\nHello\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 +# ------- + +&run_make_with_options($makefile, "next", &get_logfile); +$answer = "later foo bar\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 +# ------- + +&run_make_with_options($makefile, "BOGUS=true", &get_logfile, 512); +$answer = "$makefile:23: *** empty variable name. Stop.\n"; +&compare_output($answer, &get_logfile(1)); + + +1; diff --git a/tests/test_driver.pl b/tests/test_driver.pl new file mode 100644 index 0000000..914e0c6 --- /dev/null +++ b/tests/test_driver.pl @@ -0,0 +1,1059 @@ +#!/usr/local/bin/perl +# -*-perl-*- + +# Modification history: +# Written 91-12-02 through 92-01-01 by Stephen McGee. +# Modified 92-02-11 through 92-02-22 by Chris Arthur to further generalize. +# End of modification history + +# Test driver routines used by a number of test suites, including +# those for SCS, make, roll_dir, and scan_deps (?). + +# this routine controls the whole mess; each test suite sets up a few +# variables and then calls &toplevel, which does all the real work. + +sub toplevel +{ + # Get a clean environment + + %makeENV = (); + + # Pull in benign variables from the user's environment + # + foreach (# UNIX-specific things + 'TZ', 'LANG', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH', + # Purify things + 'PURIFYOPTIONS', + # Windows NT-specific stuff + 'Path', 'SystemRoot', + # DJGPP-specific stuff + 'DJDIR', 'DJGPP', 'SHELL', 'COMSPEC', 'HOSTNAME', 'LFN', + 'FNCASE', '387', 'EMU387', 'GROUP' + ) { + $makeENV{$_} = $ENV{$_} if $ENV{$_}; + } + + # Replace the environment with the new one + # + %origENV = %ENV; + %ENV = (); + %ENV = %makeENV; + + $| = 1; # unbuffered output + + $debug = 0; # debug flag + $profile = 0; # profiling flag + $verbose = 0; # verbose mode flag + $detail = 0; # detailed verbosity + $keep = 0; # keep temp files around + $workdir = "work"; # The directory where the test will start running + $scriptdir = "scripts"; # The directory where we find the test scripts + $tmpfilesuffix = "t"; # the suffix used on tmpfiles + $default_output_stack_level = 0; # used by attach_default_output, etc. + $default_input_stack_level = 0; # used by attach_default_input, etc. + $cwd = "."; # don't we wish we knew + $cwdslash = ""; # $cwd . $pathsep, but "" rather than "./" + + &get_osname; # sets $osname, $vos, $pathsep, and $fancy_file_names + + &set_defaults; # suite-defined + + &parse_command_line (@ARGV); + + print "OS name = `$osname'\n" if $debug; + + $workpath = "$cwdslash$workdir"; + $scriptpath = "$cwdslash$scriptdir"; + + &set_more_defaults; # suite-defined + + &print_banner; + + if (-d $workpath) + { + print "Clearing $workpath...\n"; + &remove_directory_tree("$workpath/") + || &error ("Couldn't wipe out $workpath\n"); + } + else + { + mkdir ($workpath, 0777) || &error ("Couldn't mkdir $workpath: $!\n"); + } + + if (!-d $scriptpath) + { + &error ("Failed to find $scriptpath containing perl test scripts.\n"); + } + + if (@TESTS) + { + print "Making work dirs...\n"; + foreach $test (@TESTS) + { + if ($test =~ /^([^\/]+)\//) + { + $dir = $1; + push (@rmdirs, $dir); + -d "$workpath/$dir" + || mkdir ("$workpath/$dir", 0777) + || &error ("Couldn't mkdir $workpath/$dir: $!\n"); + } + } + } + else + { + print "Finding tests...\n"; + opendir (SCRIPTDIR, $scriptpath) + || &error ("Couldn't opendir $scriptpath: $!\n"); + @dirs = readdir (SCRIPTDIR); + closedir (SCRIPTDIR); + foreach $dir (@dirs) + { + next if ! -d "$scriptpath/$dir" || $dir =~ /^\.\.?$/ || $dir eq 'CVS'; + push (@rmdirs, $dir); + mkdir ("$workpath/$dir", 0777) + || &error ("Couldn't mkdir $workpath/$dir: $!\n"); + opendir (SCRIPTDIR, "$scriptpath/$dir") + || &error ("Couldn't opendir $scriptpath/$dir: $!\n"); + @files = readdir (SCRIPTDIR); + closedir (SCRIPTDIR); + foreach $test (@files) + { + next if $test =~ /^\.\.?$/ || $test =~ /~$/ || $test eq 'CVS'; + push (@TESTS, "$dir/$test"); + } + } + } + + if (@TESTS == 0) + { + &error ("\nNo tests in $scriptpath, and none were specified.\n"); + } + + print "\n"; + + &run_each_test; + + foreach $dir (@rmdirs) + { + rmdir ("$workpath/$dir"); + } + + $| = 1; + + if ($num_failed) + { + print "\n$num_failed Test"; + print "s" unless $num_failed == 1; + print " Failed (See .diff files in $workdir dir for details) :-(\n\n"; + return 0; + } + else + { + print "\n$counter Test"; + print "s" unless $counter == 1; + print " Complete ... No Failures :-)\n\n"; + return 1; + } +} + +sub get_osname +{ + # Set up an initial value. In perl5 we can do it the easy way. + # + $osname = defined($^O) ? $^O : ''; + + # See if the filesystem supports long file names with multiple + # dots. DOS doesn't. + $fancy_file_names = 1; + (open (TOUCHFD, "> fancy.file.name") && close (TOUCHFD)) + || ($fancy_file_names = 0); + unlink ("fancy.file.name") || ($fancy_file_names = 0); + + if ($fancy_file_names) { + # Thanks go to meyering@cs.utexas.edu (Jim Meyering) for suggesting a + # better way of doing this. (We used to test for existence of a /mnt + # dir, but that apparently fails on an SGI Indigo (whatever that is).) + # Because perl on VOS translates /'s to >'s, we need to test for + # VOSness rather than testing for Unixness (ie, try > instead of /). + + mkdir (".ostest", 0777) || &error ("Couldn't create .ostest: $!\n", 1); + open (TOUCHFD, "> .ostest>ick") && close (TOUCHFD); + chdir (".ostest") || &error ("Couldn't chdir to .ostest: $!\n", 1); + } + + if ($fancy_file_names && -f "ick") + { + $osname = "vos"; + $vos = 1; + $pathsep = ">"; + } + else + { + # the following is regrettably knarly, but it seems to be the only way + # to not get ugly error messages if uname can't be found. + # Hmmm, BSD/OS 2.0's uname -a is excessively verbose. Let's try it + # with switches first. + eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)"; + if ($osname =~ /not found/i) + { + $osname = "(something unixy with no uname)"; + } + elsif ($@ ne "" || $?) + { + eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)"; + if ($@ ne "" || $?) + { + $osname = "(something unixy)"; + } + } + $vos = 0; + $pathsep = "/"; + } + + if ($fancy_file_names) { + chdir ("..") || &error ("Couldn't chdir to ..: $!\n", 1); + unlink (".ostest>ick"); + rmdir (".ostest") || &error ("Couldn't rmdir .ostest: $!\n", 1); + } +} + +sub parse_command_line +{ + @argv = @_; + + # use @ARGV if no args were passed in + + if (@argv == 0) + { + @argv = @ARGV; + } + + # look at each option; if we don't recognize it, maybe the suite-specific + # command line parsing code will... + + while (@argv) + { + $option = shift @argv; + if ($option =~ /^-debug$/i) + { + print "\nDEBUG ON\n"; + $debug = 1; + } + elsif ($option =~ /^-usage$/i) + { + &print_usage; + exit 0; + } + elsif ($option =~ /^-(h|help)$/i) + { + &print_help; + exit 0; + } + elsif ($option =~ /^-profile$/i) + { + $profile = 1; + } + elsif ($option =~ /^-verbose$/i) + { + $verbose = 1; + } + elsif ($option =~ /^-detail$/i) + { + $detail = 1; + $verbose = 1; + } + elsif ($option =~ /^-keep$/i) + { + $keep = 1; + } + elsif (&valid_option($option)) + { + # The suite-defined subroutine takes care of the option + } + elsif ($option =~ /^-/) + { + print "Invalid option: $option\n"; + &print_usage; + exit 0; + } + else # must be the name of a test + { + $option =~ s/\.pl$//; + push(@TESTS,$option); + } + } +} + +sub max +{ + local($num) = shift @_; + local($newnum); + + while (@_) + { + $newnum = shift @_; + if ($newnum > $num) + { + $num = $newnum; + } + } + + return $num; +} + +sub print_centered +{ + local($width, $string) = @_; + local($pad); + + if (length ($string)) + { + $pad = " " x ( ($width - length ($string) + 1) / 2); + print "$pad$string"; + } +} + +sub print_banner +{ + local($info); + local($line); + local($len); + + $info = "Running tests for $testee on $osname\n"; # $testee is suite-defined + $len = &max (length ($line), length ($testee_version), + length ($banner_info), 73) + 5; + $line = ("-" x $len) . "\n"; + if ($len < 78) + { + $len = 78; + } + + &print_centered ($len, $line); + &print_centered ($len, $info); + &print_centered ($len, $testee_version); # suite-defined + &print_centered ($len, $banner_info); # suite-defined + &print_centered ($len, $line); + print "\n"; +} + +sub run_each_test +{ + $counter = 0; + + foreach $testname (sort @TESTS) + { + $counter++; + $test_passed = 1; # reset by test on failure + $num_of_logfiles = 0; + $num_of_tmpfiles = 0; + $description = ""; + $details = ""; + $testname =~ s/^$scriptpath$pathsep//; + $perl_testname = "$scriptpath$pathsep$testname"; + $testname =~ s/(\.pl|\.perl)$//; + $testpath = "$workpath$pathsep$testname"; + # Leave enough space in the extensions to append a number, even + # though it needs to fit into 8+3 limits. + $log_filename = "$testpath.l"; + $diff_filename = "$testpath.d"; + $base_filename = "$testpath.b"; + $tmp_filename = "$testpath.$tmpfilesuffix"; + + &setup_for_test; # suite-defined + + $output = "........................................................ "; + + substr($output,0,length($testname)) = "$testname "; + + print $output; + + # Run the actual test! + # + $code = do $perl_testname; + if (!defined($code)) + { + $test_passed = 0; + if (length ($@)) + { + warn "\n*** Test died ($testname): $@\n"; + } + else + { + warn "\n*** Couldn't run $perl_testname\n"; + } + } + elsif ($code == -1) { + $test_passed = 0; + } + elsif ($code != 1 && $code != -1) { + $test_passed = 0; + warn "\n*** Test returned $code\n"; + } + + if ($test_passed) { + $status = "ok"; + for ($i = $num_of_tmpfiles; $i; $i--) + { + &delete ($tmp_filename . &num_suffix ($i) ); + } + + for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) + { + &delete ($log_filename . &num_suffix ($i) ); + &delete ($base_filename . &num_suffix ($i) ); + } + } + elsif ($code > 0) { + $status = "FAILED"; + $num_failed++; + } + elsif ($code < 0) { + $status = "N/A"; + --$counter; + } + + # If the verbose option has been specified, then a short description + # of each test is printed before displaying the results of each test + # describing WHAT is being tested. + + if ($verbose) + { + if ($detail) + { + print "\nWHAT IS BEING TESTED\n"; + print "--------------------"; + } + print "\n\n$description\n\n"; + } + + # If the detail option has been specified, then the details of HOW + # the test is testing what it says it is testing in the verbose output + # will be displayed here before the results of the test are displayed. + + if ($detail) + { + print "\nHOW IT IS TESTED\n"; + print "----------------"; + print "\n\n$details\n\n"; + } + + print "$status\n"; + } +} + +# If the keep flag is not set, this subroutine deletes all filenames that +# are sent to it. + +sub delete +{ + local(@files) = @_; + + if (!$keep) + { + return (unlink @files); + } + + return 1; +} + +sub print_standard_usage +{ + local($plname,@moreusage) = @_; + local($line); + + print "Usage: perl $plname [testname] [-verbose] [-detail] [-keep]\n"; + print " [-profile] [-usage] [-help] " + . "[-debug]\n"; + foreach $line (@moreusage) + { + print " $line\n"; + } +} + +sub print_standard_help +{ + local(@morehelp) = @_; + local($line); + local($tline); + local($t) = " "; + + $line = "Test Driver For $testee"; + print "$line\n"; + $line = "=" x length ($line); + print "$line\n"; + + &print_usage; + + print "\ntestname\n" + . "${t}You may, if you wish, run only ONE test if you know the name\n" + . "${t}of that test and specify this name anywhere on the command\n" + . "${t}line. Otherwise ALL existing tests in the scripts directory\n" + . "${t}will be run.\n" + . "-verbose\n" + . "${t}If this option is given, a description of every test is\n" + . "${t}displayed before the test is run. (Not all tests may have\n" + . "${t}descriptions at this time)\n" + . "-detail\n" + . "${t}If this option is given, a detailed description of every\n" + . "${t}test is displayed before the test is run. (Not all tests\n" + . "${t}have descriptions at this time)\n" + . "-profile\n" + . "${t}If this option is given, then the profile file\n" + . "${t}is added to other profiles every time $testee is run.\n" + . "${t}This option only works on VOS at this time.\n" + . "-keep\n" + . "${t}You may give this option if you DO NOT want ANY\n" + . "${t}of the files generated by the tests to be deleted. \n" + . "${t}Without this option, all files generated by the test will\n" + . "${t}be deleted IF THE TEST PASSES.\n" + . "-debug\n" + . "${t}Use this option if you would like to see all of the system\n" + . "${t}calls issued and their return status while running the tests\n" + . "${t}This can be helpful if you're having a problem adding a test\n" + . "${t}to the suite, or if the test fails!\n"; + + foreach $line (@morehelp) + { + $tline = $line; + if (substr ($tline, 0, 1) eq "\t") + { + substr ($tline, 0, 1) = $t; + } + print "$tline\n"; + } +} + +####################################################################### +########### Generic Test Driver Subroutines ########### +####################################################################### + +sub get_caller +{ + local($depth); + local($package); + local($filename); + local($linenum); + + $depth = defined ($_[0]) ? $_[0] : 1; + ($package, $filename, $linenum) = caller ($depth + 1); + return "$filename: $linenum"; +} + +sub error +{ + local($message) = $_[0]; + local($caller) = &get_caller (1); + + if (defined ($_[1])) + { + $caller = &get_caller ($_[1] + 1) . " -> $caller"; + } + + die "$caller: $message"; +} + +sub compare_output +{ + local($answer,$logfile) = @_; + local($slurp); + + if ($debug) + { + print "Comparing Output ........ "; + } + + $slurp = &read_file_into_string ($logfile); + + # For make, get rid of any time skew error before comparing--too bad this + # has to go into the "generic" driver code :-/ + $slurp =~ s/^.*modification time in the future.*\n//g; + $slurp =~ s/\n.*modification time in the future.*//g; + $slurp =~ s/^.*Clock skew detected.*\n//g; + $slurp =~ s/\n.*Clock skew detected.*//g; + + if ($slurp eq $answer) + { + if ($debug) + { + print "ok\n"; + } + return 1; + } + else + { + if ($debug) + { + print "DIFFERENT OUTPUT\n"; + } + $test_passed = 0; + &create_file (&get_basefile, $answer); + + if ($debug) + { + print "\nCreating Difference File ...\n"; + } + # Create the difference file + local($command) = "diff -u " . &get_basefile . " " . $logfile; + &run_command_with_output(&get_difffile,$command); + + return 0; + } +} + +sub read_file_into_string +{ + local($filename) = @_; + local($oldslash) = $/; + + undef $/; + + open (RFISFILE, $filename) || return ""; + local ($slurp) = <RFISFILE>; + close (RFISFILE); + + $/ = $oldslash; + + return $slurp; +} + +sub attach_default_output +{ + local ($filename) = @_; + local ($code); + + if ($vos) + { + $code = system "++attach_default_output_hack $filename"; + $code == -2 || &error ("adoh death\n", 1); + return 1; + } + + open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT") + || &error ("ado: $! duping STDOUT\n", 1); + open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR") + || &error ("ado: $! duping STDERR\n", 1); + + open (STDOUT, "> " . $filename) + || &error ("ado: $filename: $!\n", 1); + open (STDERR, ">&STDOUT") + || &error ("ado: $filename: $!\n", 1); + + $default_output_stack_level++; +} + +# close the current stdout/stderr, and restore the previous ones from +# the "stack." + +sub detach_default_output +{ + local ($code); + + if ($vos) + { + $code = system "++detach_default_output_hack"; + $code == -2 || &error ("ddoh death\n", 1); + return 1; + } + + if (--$default_output_stack_level < 0) + { + &error ("default output stack has flown under!\n", 1); + } + + close (STDOUT); + close (STDERR); + + open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out") + || &error ("ddo: $! duping STDOUT\n", 1); + open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err") + || &error ("ddo: $! duping STDERR\n", 1); + + close ("SAVEDOS" . $default_output_stack_level . "out") + || &error ("ddo: $! closing SCSDOSout\n", 1); + close ("SAVEDOS" . $default_output_stack_level . "err") + || &error ("ddo: $! closing SAVEDOSerr\n", 1); +} + +# run one command (passed as a list of arg 0 - n), returning 0 on success +# and nonzero on failure. + +sub run_command +{ + local ($code); + + if ($debug) + { + print "\nrun_command: @_\n"; + $code = system @_; + print "run_command: \"@_\" returned $code.\n"; + return $code; + } + + return system @_; +} + +# run one command (passed as a list of arg 0 - n, with arg 0 being the +# second arg to this routine), returning 0 on success and non-zero on failure. +# The first arg to this routine is a filename to connect to the stdout +# & stderr of the child process. + +sub run_command_with_output +{ + local ($filename) = shift; + local ($code); + + &attach_default_output ($filename); + $code = system @_; + &detach_default_output; + if ($debug) + { + print "run_command_with_output: \"@_\" returned $code.\n"; + } + + return $code; +} + +# performs the equivalent of an "rm -rf" on the first argument. Like +# rm, if the path ends in /, leaves the (now empty) directory; otherwise +# deletes it, too. + +sub remove_directory_tree +{ + local ($targetdir) = @_; + local ($nuketop) = 1; + local ($ch); + + $ch = substr ($targetdir, length ($targetdir) - 1); + if ($ch eq "/" || $ch eq $pathsep) + { + $targetdir = substr ($targetdir, 0, length ($targetdir) - 1); + $nuketop = 0; + } + + if (! -e $targetdir) + { + return 1; + } + + &remove_directory_tree_inner ("RDT00", $targetdir) || return 0; + if ($nuketop) + { + rmdir $targetdir || return 0; + } + + return 1; +} + +sub remove_directory_tree_inner +{ + local ($dirhandle, $targetdir) = @_; + local ($object); + local ($subdirhandle); + + opendir ($dirhandle, $targetdir) || return 0; + $subdirhandle = $dirhandle; + $subdirhandle++; + while ($object = readdir ($dirhandle)) + { + if ($object eq "." || $object eq "..") + { + next; + } + + $object = "$targetdir$pathsep$object"; + lstat ($object); + + if (-d _ && &remove_directory_tree_inner ($subdirhandle, $object)) + { + rmdir $object || return 0; + } + else + { + unlink $object || return 0; + } + } + closedir ($dirhandle); + return 1; +} + +sub touch +{ + local (@filenames) = @_; + local ($now) = time; + local ($file); + + foreach $file (@filenames) + { + utime ($now, $now, $file) + || (open (TOUCHFD, ">> $file") && close (TOUCHFD)) + || &error ("Couldn't touch $file: $!\n", 1); + } + return 1; +} + +# open a file, write some stuff to it, and close it. + +sub create_file +{ + local ($filename, @lines) = @_; + + open (CF, "> $filename") || &error ("Couldn't open $filename: $!\n", 1); + foreach $line (@lines) + { + print CF $line; + } + close (CF); +} + +# create a directory tree described by an associative array, wherein each +# key is a relative pathname (using slashes) and its associated value is +# one of: +# DIR indicates a directory +# FILE:contents indicates a file, which should contain contents +\n +# LINK:target indicates a symlink, pointing to $basedir/target +# The first argument is the dir under which the structure will be created +# (the dir will be made and/or cleaned if necessary); the second argument +# is the associative array. + +sub create_dir_tree +{ + local ($basedir, %dirtree) = @_; + local ($path); + + &remove_directory_tree ("$basedir"); + mkdir ($basedir, 0777) || &error ("Couldn't mkdir $basedir: $!\n", 1); + + foreach $path (sort keys (%dirtree)) + { + if ($dirtree {$path} =~ /^DIR$/) + { + mkdir ("$basedir/$path", 0777) + || &error ("Couldn't mkdir $basedir/$path: $!\n", 1); + } + elsif ($dirtree {$path} =~ /^FILE:(.*)$/) + { + &create_file ("$basedir/$path", $1 . "\n"); + } + elsif ($dirtree {$path} =~ /^LINK:(.*)$/) + { + symlink ("$basedir/$1", "$basedir/$path") + || &error ("Couldn't symlink $basedir/$path -> $basedir/$1: $!\n", 1); + } + else + { + &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); + } + } + if ($just_setup_tree) + { + die "Tree is setup...\n"; + } +} + +# compare a directory tree with an associative array in the format used +# by create_dir_tree, above. +# The first argument is the dir under which the structure should be found; +# the second argument is the associative array. + +sub compare_dir_tree +{ + local ($basedir, %dirtree) = @_; + local ($path); + local ($i); + local ($bogus) = 0; + local ($contents); + local ($target); + local ($fulltarget); + local ($found); + local (@files); + local (@allfiles); + + opendir (DIR, $basedir) || &error ("Couldn't open $basedir: $!\n", 1); + @allfiles = grep (!/^\.\.?$/, readdir (DIR) ); + closedir (DIR); + if ($debug) + { + print "dirtree: (%dirtree)\n$basedir: (@allfiles)\n"; + } + + foreach $path (sort keys (%dirtree)) + { + if ($debug) + { + print "Checking $path ($dirtree{$path}).\n"; + } + + $found = 0; + foreach $i (0 .. $#allfiles) + { + if ($allfiles[$i] eq $path) + { + splice (@allfiles, $i, 1); # delete it + if ($debug) + { + print " Zapped $path; files now (@allfiles).\n"; + } + lstat ("$basedir/$path"); + $found = 1; + last; + } + } + + if (!$found) + { + print "compare_dir_tree: $path does not exist.\n"; + $bogus = 1; + next; + } + + if ($dirtree {$path} =~ /^DIR$/) + { + if (-d _ && opendir (DIR, "$basedir/$path") ) + { + @files = readdir (DIR); + closedir (DIR); + @files = grep (!/^\.\.?$/ && ($_ = "$path/$_"), @files); + push (@allfiles, @files); + if ($debug) + { + print " Read in $path; new files (@files).\n"; + } + } + else + { + print "compare_dir_tree: $path is not a dir.\n"; + $bogus = 1; + } + } + elsif ($dirtree {$path} =~ /^FILE:(.*)$/) + { + if (-l _ || !-f _) + { + print "compare_dir_tree: $path is not a file.\n"; + $bogus = 1; + next; + } + + if ($1 ne "*") + { + $contents = &read_file_into_string ("$basedir/$path"); + if ($contents ne "$1\n") + { + print "compare_dir_tree: $path contains wrong stuff." + . " Is:\n$contentsShould be:\n$1\n"; + $bogus = 1; + } + } + } + elsif ($dirtree {$path} =~ /^LINK:(.*)$/) + { + $target = $1; + if (!-l _) + { + print "compare_dir_tree: $path is not a link.\n"; + $bogus = 1; + next; + } + + $contents = readlink ("$basedir/$path"); + $contents =~ tr/>/\//; + $fulltarget = "$basedir/$target"; + $fulltarget =~ tr/>/\//; + if (!($contents =~ /$fulltarget$/)) + { + if ($debug) + { + $target = $fulltarget; + } + print "compare_dir_tree: $path should be link to $target, " + . "not $contents.\n"; + $bogus = 1; + } + } + else + { + &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); + } + } + + if ($debug) + { + print "leftovers: (@allfiles).\n"; + } + + foreach $file (@allfiles) + { + print "compare_dir_tree: $file should not exist.\n"; + $bogus = 1; + } + + return !$bogus; +} + +# this subroutine generates the numeric suffix used to keep tmp filenames, +# log filenames, etc., unique. If the number passed in is 1, then a null +# string is returned; otherwise, we return ".n", where n + 1 is the number +# we were given. + +sub num_suffix +{ + local($num) = @_; + + if (--$num > 0) { + return "$num"; + } + + return ""; +} + +# This subroutine returns a log filename with a number appended to +# the end corresponding to how many logfiles have been created in the +# current running test. An optional parameter may be passed (0 or 1). +# If a 1 is passed, then it does NOT increment the logfile counter +# and returns the name of the latest logfile. If either no parameter +# is passed at all or a 0 is passed, then the logfile counter is +# incremented and the new name is returned. + +sub get_logfile +{ + local($no_increment) = @_; + + $num_of_logfiles += !$no_increment; + + return ($log_filename . &num_suffix ($num_of_logfiles)); +} + +# This subroutine returns a base (answer) filename with a number +# appended to the end corresponding to how many logfiles (and thus +# base files) have been created in the current running test. +# NO PARAMETERS ARE PASSED TO THIS SUBROUTINE. + +sub get_basefile +{ + return ($base_filename . &num_suffix ($num_of_logfiles)); +} + +# This subroutine returns a difference filename with a number appended +# to the end corresponding to how many logfiles (and thus diff files) +# have been created in the current running test. + +sub get_difffile +{ + return ($diff_filename . &num_suffix ($num_of_logfiles)); +} + +# just like logfile, only a generic tmp filename for use by the test. +# they are automatically cleaned up unless -keep was used, or the test fails. +# Pass an argument of 1 to return the same filename as the previous call. + +sub get_tmpfile +{ + local($no_increment) = @_; + + $num_of_tmpfiles += !$no_increment; + + return ($tmp_filename . &num_suffix ($num_of_tmpfiles)); +} + +1; |