| # Hand crafted tests for GNU M4. -*- Autotest -*- | |
| # Copyright (C) 2001, 2006-2008, 2010, 2013-2014, 2017 Free Software | |
| # Foundation, Inc. | |
| # This file is part of GNU M4. | |
| # | |
| # GNU M4 is free software: you can redistribute it and/or modify | |
| # it under the terms of the GNU General Public License as published by | |
| # the Free Software Foundation, either version 3 of the License, or | |
| # (at your option) any later version. | |
| # | |
| # GNU M4 is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| # GNU General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU General Public License | |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| AT_BANNER([Module support.]) | |
| ## --------- ## | |
| ## modfreeze ## | |
| ## --------- ## | |
| AT_SETUP([Freezing modules]) | |
| AT_KEYWORDS([frozen]) | |
| AT_DATA([[frozen.m4]], | |
| [[divert(1)dnl | |
| define(`test', `local::`test'')dnl | |
| define(`test1', defn(`test'))dnl | |
| ->test | |
| include(`modtest') | |
| define(`test2', defn(`test'))dnl | |
| ->test | |
| include(`shadow') | |
| define(`test3', defn(`test'))dnl | |
| ->test | |
| ]]) | |
| AT_DATA([[unfrozen.m4]], | |
| [[undivert(1)dnl | |
| test1 | |
| test2 | |
| test3 | |
| ]]) | |
| # First generate the `expout' ouput by running over the sources before | |
| # freezing. | |
| AT_CHECK_M4([-I "$abs_builddir" frozen.m4 unfrozen.m4], | |
| [0], [stdout], [stderr]) | |
| mv stdout expout | |
| mv stderr experr | |
| # Now freeze the first source file. | |
| AT_CHECK_M4([-I "$abs_builddir" -F frozen.m4f frozen.m4], | |
| [0], [], [ignore]) | |
| # Now rerun the original sequence, but using the frozen file. | |
| AT_CHECK_M4([-I "$abs_builddir" -R frozen.m4f unfrozen.m4], | |
| [0], [expout], [experr]) | |
| AT_CLEANUP([frozen.m4f]) | |
| ## ---------------------------- ## | |
| ## Exercising the test module. ## | |
| ## ---------------------------- ## | |
| # AT_CHECK_M4_MODTEST(TITLE, ENV-VARS, M4-OPTIONS) | |
| # ------------------------------------------------ | |
| # Add a test named TITLE, running m4 with either ENV-VARS in the environment | |
| # or M4-OPTIONS set to pick up test modules. | |
| m4_define([AT_CHECK_M4_MODTEST], | |
| [AT_SETUP([$1]) | |
| AT_DATA([input.m4], | |
| [[test | |
| Dumpdef: dumpdef(`test'). | |
| include(`modtest') | |
| test | |
| Dumpdef: dumpdef(`test'). | |
| ]]) | |
| dnl Fortunately, all tests within AT_SETUP are in the same subshell, so | |
| dnl setting the environment now will impact the AT_CHECK_M4, but not | |
| dnl carry over to the next AT_SETUP. | |
| m4_ifval([$2], [$2 | |
| export m4_substr([$2], [0], m4_index([$2], [=]))]) | |
| AT_CHECK_M4([$3 input.m4], [0], | |
| [[test | |
| Dumpdef: . | |
| Test module called. | |
| Dumpdef: . | |
| ]], | |
| [[m4:input.m4:2: warning: dumpdef: undefined macro 'test' | |
| Test module loaded. | |
| test: <test> | |
| ]]) | |
| AT_CLEANUP | |
| ]) | |
| AT_CHECK_M4_MODTEST([--include: absolute path], | |
| [], [-I "$abs_builddir"]) | |
| AT_CHECK_M4_MODTEST([--include: relative path], | |
| [], [-I "$top_build_prefix/tests"]) | |
| AT_CHECK_M4_MODTEST([M4PATH: absolute path], | |
| [M4PATH="$abs_builddir:"], []) | |
| AT_CHECK_M4_MODTEST([M4PATH: relative path], | |
| [M4PATH="$top_build_prefix/tests:"], []) | |
| ## ------ ## | |
| ## shadow ## | |
| ## ------ ## | |
| AT_SETUP([modules: shadow]) | |
| AT_DATA([[input.m4]], | |
| [[# no modules loaded yet | |
| test | |
| shadow | |
| # define our own macros for `test' and `shadow' | |
| define(`test', `local::`test'') | |
| define(`shadow', `local::`shadow'') | |
| test | |
| shadow | |
| # module Shadow defines `shadow' and `test' macros | |
| include(`shadow') | |
| dumpdef(`test') | |
| dumpdef(`shadow') | |
| test | |
| shadow | |
| # save the definition of `test' from the Shadow module | |
| define(`Shadow::test', defn(`test')) | |
| # module Modtest also defines a `test' macro | |
| include(`modtest') | |
| dumpdef(`test') | |
| dumpdef(`shadow') | |
| test | |
| shadow | |
| # Reloading Shadow shouldn't affect anything | |
| include(`shadow') | |
| dumpdef(`test') | |
| dumpdef(`shadow') | |
| test | |
| shadow | |
| ]]) | |
| AT_DATA([[expout]], | |
| [[# no modules loaded yet | |
| test | |
| shadow | |
| # define our own macros for `test' and `shadow' | |
| local::test | |
| local::shadow | |
| # module Shadow defines `shadow' and `test' macros | |
| Shadow module loaded. | |
| Shadow::test called. | |
| Shadow::shadow called. | |
| # save the definition of `test' from the Shadow module | |
| # module Modtest also defines a `test' macro | |
| Test module called. | |
| Shadow::shadow called. | |
| # Reloading Shadow shouldn't affect anything | |
| Test module called. | |
| Shadow::shadow called. | |
| ]]) | |
| AT_DATA([[experr]], | |
| [[test: <test> | |
| shadow: <shadow> | |
| Test module loaded. | |
| test: <test> | |
| shadow: <shadow> | |
| test: <test> | |
| shadow: <shadow> | |
| ]]) | |
| AT_CHECK_M4([-I "$abs_builddir" input.m4], [0], | |
| [expout], [experr]) | |
| AT_CLEANUP | |
| ## ----------------------- ## | |
| ## module symbol importing ## | |
| ## ----------------------- ## | |
| # Importing a symbol from a not yet loaded module | |
| # This test is ugly, because we need to canonicalize strerror strings | |
| # to match our test. So we save STDERR to a file, and run another check | |
| # which edits that file and compares it to the canonical STDERR output | |
| # from the first command: | |
| AT_SETUP([modules: importing]) | |
| AT_DATA([[input.m4]], | |
| [[import | |
| include(`import') | |
| import | |
| import | |
| symbol_fail | |
| module_fail | |
| ]]) | |
| AT_DATA([[expout]], | |
| [[import | |
| import::import called. | |
| import::import called. | |
| import::symbol_fail called. | |
| ]]) | |
| AT_DATA([[experr]], | |
| [[Test module loaded. | |
| TRUE | |
| TRUE | |
| m4:input.m4:5: cannot load symbol `no_such' from module `modtest' | |
| m4:input.m4:6: cannot open module `no_such' | |
| ]]) | |
| ls "$abs_builddir" | |
| AT_CHECK_M4([-I "$abs_builddir" input.m4], | |
| [1], [expout], [experr]) | |
| AT_CLEANUP | |
| ## ------------------- ## | |
| ## text module symbols ## | |
| ## ------------------- ## | |
| # Support text macros with requested numbers of parameters. | |
| AT_SETUP([modules: text]) | |
| AT_DATA([input.m4], | |
| [[__test__ | |
| __test__(1) | |
| __test__(1,2) | |
| onearg | |
| onearg(1) | |
| onearg(1,2) | |
| manyargs | |
| manyargs(1) | |
| manyargs(1,2) | |
| ]]) | |
| AT_CHECK_M4([-I "$abs_builddir" modtest input.m4], [0], | |
| [[modtest | |
| modtest | |
| modtest | |
| 1 | |
| 1 | |
| 1 | |
| 1,2 | |
| ]], [[Test module loaded. | |
| m4:input.m4:2: warning: __test__: extra arguments ignored: 1 > 0 | |
| m4:input.m4:3: warning: __test__: extra arguments ignored: 2 > 0 | |
| m4:input.m4:4: warning: onearg: too few arguments: 0 < 1 | |
| m4:input.m4:6: warning: onearg: extra arguments ignored: 2 > 1 | |
| ]]) | |
| AT_CLEANUP | |
| ## -------------------- ## | |
| ## trace module symbols ## | |
| ## -------------------- ## | |
| # The trace bit should not be lost if a builtin is unloaded from | |
| # memory and then redefined by a subsequent load. | |
| AT_SETUP([modules: trace]) | |
| AT_DATA([[input.m4]], | |
| [[test | |
| include(`shadow') | |
| test | |
| include(`shadow') | |
| test | |
| ]]) | |
| AT_DATA([[expout]], | |
| [[test | |
| Shadow module loaded. | |
| Shadow::test called. | |
| Shadow::test called. | |
| ]]) | |
| AT_DATA([[experr]], | |
| [[m4trace: -1- test -> `Shadow::`test' called.' | |
| m4trace: -1- test -> `Shadow::`test' called.' | |
| ]]) | |
| AT_CHECK_M4([-I "$abs_builddir" -t test input.m4], | |
| [0], [expout], [experr]) | |
| AT_CLEANUP |