| # Hand crafted tests for GNU M4. -*- Autotest -*- |
| # Copyright (C) 2006, 2007, 2008 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([Freezing state.]) |
| |
| ## --------------- ## |
| ## large diversion ## |
| ## --------------- ## |
| |
| AT_SETUP([large diversion]) |
| AT_KEYWORDS([frozen]) |
| |
| # Check that large diversions are handled across freeze boundaries. |
| |
| AT_DATA([[frozen.m4]], [M4_ONE_MEG_DEFN[divert(2)f |
| divert(1)hi |
| ]]) |
| |
| AT_DATA([[unfrozen.m4]], |
| [[divert(3)bye |
| ]]) |
| |
| # First generate the `expout' output by running over the sources before |
| # freezing. |
| AT_CHECK_M4([frozen.m4 unfrozen.m4], [0], |
| [stdout], [stderr]) |
| |
| mv stdout expout |
| mv stderr experr |
| |
| # Now freeze the first source file. |
| AT_CHECK_M4([-F frozen.m4f frozen.m4], [0]) |
| |
| # Now rerun the original sequence, but using the frozen file. |
| AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], |
| [expout], [experr]) |
| |
| AT_CLEANUP |
| |
| |
| ## ---------------- ## |
| ## loading format 1 ## |
| ## ---------------- ## |
| |
| AT_SETUP([loading format 1]) |
| AT_KEYWORDS([frozen]) |
| |
| m4_if([ |
| Note: frozen.m4f was obtained by deleting unneeded lines from the output of |
| a version of m4 1.4.5 with changeword support. Deleting lines is in effect |
| equivalent to using undefine(name) in the input. This test ensures we |
| behave well with the old format, including \ parsing, disappearing builtins |
| (okay so long as the input does not try to use them), and restoring sane |
| defaults for features that were only added in version 2 frozen format. |
| |
| $ m4 --version | head -n1 |
| GNU M4 1.4.5 |
| $ cat frozen.m4 |
| divert(`-1') |
| define(`foo', `\FOO') |
| pushdef(`foo', `bar${1}') |
| define(`my_define', defn(`define')) |
| define(`my_changeword', defn(`changeword')) |
| pushdef(`my_define', `define') |
| pushdef(`my_define', defn(`define')) |
| divert(`1')dnl |
| foo |
| divert`'dnl |
| changequote([,])dnl |
| changecom([/*], [*/])dnl |
| dnl Implied sequence of undefine(`name') due to hand-edits |
| $ m4 -F frozen.m4f frozen.m4 |
| $ |
| ]) |
| AT_DATA([frozen.m4f], |
| [[# This is a frozen state file generated by GNU M4 1.4.5 |
| V1 |
| Q1,1 |
| [] |
| C2,2 |
| /**/ |
| F6,6 |
| popdefpopdef |
| F13,10 |
| my_changewordchangeword |
| F9,6 |
| my_definedefine |
| T9,6 |
| my_definedefine |
| F9,6 |
| my_definedefine |
| T3,4 |
| foo\FOO |
| T3,7 |
| foobar${1} |
| F3,3 |
| dnldnl |
| D1,8 |
| bar${1} |
| |
| D0,0 |
| |
| # End of frozen state file |
| ]]) |
| |
| AT_DATA([input.m4], |
| [[foo([2]) /* foo */ popdef([foo])foo |
| my_define([bar], [1])[]popdef([my_define]) bar |
| my_define([bar], [2])[]popdef([my_define]) bar |
| my_define([bar], [3])[]popdef([my_define]) bar |
| my_define([bar], [4])[]popdef([my_define]) bar |
| ]]) |
| |
| AT_CHECK_M4([-R frozen.m4f input.m4], [0], |
| [[bar${1} /* foo */ \FOO |
| 1 |
| define 1 |
| 3 |
| my_define(bar, 4) 3 |
| bar${1} |
| ]], |
| [[m4:input.m4:5: Warning: popdef: undefined macro `my_define' |
| ]]) |
| |
| AT_CLEANUP |
| |
| |
| ## ---------------- ## |
| ## loading format 2 ## |
| ## ---------------- ## |
| |
| AT_SETUP([loading format 2]) |
| AT_KEYWORDS([frozen]) |
| |
| AT_DATA([frozen.m4f], |
| [[# Handcrafted file, obeying the version 2 spec |
| V2 |
| # missing close quote should be supplied |
| Q1,0 |
| > |
| # missing close comment should be supplied |
| C1,0 |
| < |
| M2 |
| m4 |
| M3 |
| gnu |
| F7,7,3 |
| builtinbuiltingnu |
| # Text to negative diversion must not crash. Catches a regression |
| # introduced 2007-05-28 and fixed 2007-05-31. |
| D-1,5 |
| 12345 |
| D0,0 |
| |
| # Testing escape sequences |
| T4,5 |
| blah\t\477\040\X5C |
| # Long macro definition. Catches a regression introduced on 2007-01-20 |
| # and patched 2007-02-25. |
| T4,122 |
| long01234567890123456789012345678901234567890123456789 |
| 01234567890123456789012345678901234567890123456789 |
| 01234567890123456789 |
| ]]) |
| |
| AT_DATA([input.m4], |
| [[< comment: builtin() |
| builtin(>define', foo, bar) |
| foo |
| blah |
| ]]) |
| |
| AT_CHECK_M4([-R frozen.m4f input.m4], [0], |
| [[< comment: builtin() |
| |
| bar |
| '7 \ |
| ]]) |
| |
| dnl We don't support anything larger than format 2; make sure of that... |
| AT_DATA([bogus.m4f], [[V3 |
| ]]) |
| AT_CHECK_M4([-R bogus.m4f], [63], [], |
| [[m4: frozen file version 3 greater than max supported of 2 |
| ]]) |
| |
| AT_CLEANUP |
| |
| |
| ## --------- ## |
| ## changecom ## |
| ## --------- ## |
| |
| AT_SETUP([reloading changecom]) |
| AT_KEYWORDS([frozen]) |
| |
| # Check that changesyntax is maintained across freeze boundaries. |
| |
| AT_DATA([[frozen.m4]], |
| [[changecom`'changequote(<,>)dnl |
| ]]) |
| |
| AT_DATA([[unfrozen.m4]], |
| [[define(<foo>, <bar>) |
| foo # foo |
| ]]) |
| |
| # First generate the `expout' output by running over the sources before |
| # freezing. |
| AT_CHECK_M4([frozen.m4 unfrozen.m4], [0], |
| [stdout], [stderr]) |
| |
| mv stdout expout |
| mv stderr experr |
| |
| # Now freeze the first source file. |
| AT_CHECK_M4([-F frozen.m4f frozen.m4], [0]) |
| |
| # Now rerun the original sequence, but using the frozen file. |
| AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], |
| [expout], [experr]) |
| |
| AT_CLEANUP |
| |
| |
| ## ------------ ## |
| ## changesyntax ## |
| ## ------------ ## |
| |
| AT_SETUP([reloading changesyntax]) |
| AT_KEYWORDS([frozen]) |
| |
| # Check that changesyntax is maintained across freeze boundaries. |
| |
| AT_DATA([[frozen.m4]], |
| [[changesyntax(`W+.', `({', `)}')dnl |
| define{`a.b', `hello $1'}dnl |
| ]]) |
| |
| AT_DATA([[unfrozen.m4]], |
| [[a.b{world} |
| ]]) |
| |
| # First generate the `expout' output by running over the sources before |
| # freezing. |
| AT_CHECK_M4([frozen.m4 unfrozen.m4], [0], |
| [stdout], [stderr]) |
| |
| mv stdout expout |
| mv stderr experr |
| |
| # Now freeze the first source file. |
| AT_CHECK_M4([-F frozen.m4f frozen.m4], [0]) |
| |
| # Now rerun the original sequence, but using the frozen file. |
| AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], |
| [expout], [experr]) |
| |
| AT_CLEANUP |
| |
| |
| ## ------------- ## |
| ## regexp syntax ## |
| ## ------------- ## |
| |
| AT_SETUP([reloading regexp syntax]) |
| AT_KEYWORDS([frozen]) |
| |
| # Check that regular expression syntax is maintained across freeze boundaries. |
| |
| AT_DATA([[frozen.m4]], |
| [[changeresyntax(`POSIX_EXTENDED')dnl |
| ]]) |
| |
| AT_DATA([[unfrozen.m4]], |
| [[regexp(`GNUs not Unix', `\w(\w*)$') |
| regexp(`GNUs not Unix', `\w\(\w*\)$', `GNU_M4') |
| ]]) |
| |
| # First generate the `expout' output by running over the sources before |
| # freezing. |
| AT_CHECK_M4([frozen.m4 unfrozen.m4], [0], |
| [stdout], [stderr]) |
| |
| mv stdout expout |
| mv stderr experr |
| |
| # Now freeze the first source file. |
| AT_CHECK_M4([-F frozen.m4f frozen.m4], [0], |
| [ignore], [ignore]) |
| |
| # Now rerun the original sequence, but using the frozen file. |
| AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], |
| [expout], [experr]) |
| |
| AT_CLEANUP |
| |
| |
| ## ---------------- ## |
| ## unknown builtins ## |
| ## ---------------- ## |
| |
| AT_SETUP([reloading unknown builtin]) |
| AT_KEYWORDS([frozen]) |
| |
| AT_DATA([[empty.m4]]) |
| |
| # Freeze default state. Also check for bug fixed 18 Oct, 2007. |
| AT_CHECK_M4([-F frozen.m4f -t undefined empty.m4]) |
| |
| # Add an unknown builtin. |
| echo 'F1,1' >> frozen.m4f |
| echo 'ab' >> frozen.m4f |
| |
| AT_DATA([[input.m4]], |
| [[dnl The macro is defined; checking this is safe |
| ifdef(`a', `yes', `no') |
| dnl Grabbing the definition must warn; and the copy is the empty string |
| define(`c', defn(`a')) |
| dnl Invoking the macro directly must warn |
| a |
| dnl Invoking it indirectly must warn |
| indir(`a') |
| dnl The copy is a text string, not a placeholder |
| c |
| dnl Since it is defined, it must have a definition |
| dumpdef(`a', `c') |
| dnl Deleting it is safe |
| popdef(`a') |
| a |
| ]]) |
| |
| AT_CHECK_M4([-R frozen.m4f input.m4], 0, |
| [[yes |
| |
| |
| |
| |
| |
| |
| a |
| ]], |
| [[m4:input.m4:4: Warning: a: builtin `b' requested by frozen file not found |
| m4:input.m4:6: Warning: a: builtin `b' requested by frozen file not found |
| m4:input.m4:8: Warning: a: builtin `b' requested by frozen file not found |
| a: <<b>> |
| c: `' |
| ]]) |
| |
| AT_CLEANUP |