# 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 .
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:
]])
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:
shadow:
Test module loaded.
test:
shadow:
test:
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