📄 m4sugar.m4
字号:
divert(-1)# -*- Autoconf -*-# This file is part of Autoconf.# Base M4 layer.# Requires GNU M4.## Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software# Foundation, Inc.## 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA# 02110-1301, USA.## As a special exception, the Free Software Foundation gives unlimited# permission to copy, distribute and modify the configure scripts that# are the output of Autoconf. You need not follow the terms of the GNU# General Public License when using or distributing such scripts, even# though portions of the text of Autoconf appear in them. The GNU# General Public License (GPL) does govern all other use of the material# that constitutes the Autoconf program.## Certain portions of the Autoconf source text are designed to be copied# (in certain cases, depending on the input) into the output of# Autoconf. We call these the "data" portions. The rest of the Autoconf# source text consists of comments plus executable code that decides which# of the data portions to output in any given case. We call these# comments and executable code the "non-data" portions. Autoconf never# copies any of the non-data portions into its output.## This special exception to the GPL applies to versions of Autoconf# released by the Free Software Foundation. When you make and# distribute a modified version of Autoconf, you may extend this special# exception to the GPL to apply to your modified version as well, *unless*# your modified version has the potential to copy into its output some# of the text that was the non-data portion of the version that you started# with. (In other words, unless your change moves or copies text from# the non-data portions to the data portions.) If your modification has# such potential, you must delete any notice of this special exception# to the GPL from your modified version.## Written by Akim Demaille.## Set the quotes, whatever the current quoting system.changequote()changequote([, ])# Some old m4's don't support m4exit. But they provide# equivalent functionality by core dumping because of the# long macros we define.ifdef([__gnu__], ,[errprint(M4sugar requires GNU M4. Install it before installing M4sugar orset the M4 environment variable to its absolute file name.)m4exit(2)])## ------------------------------- #### 1. Simulate --prefix-builtins. #### ------------------------------- ### m4_define# m4_defn# m4_undefinedefine([m4_define], defn([define]))define([m4_defn], defn([defn]))define([m4_undefine], defn([undefine]))m4_undefine([define])m4_undefine([defn])m4_undefine([undefine])# m4_copy(SRC, DST)# -----------------# Define DST as the definition of SRC.# What's the difference between:# 1. m4_copy([from], [to])# 2. m4_define([to], [from($@)])# Well, obviously 1 is more expensive in space. Maybe 2 is more expensive# in time, but because of the space cost of 1, it's not that obvious.# Nevertheless, one huge difference is the handling of `$0'. If `from'# uses `$0', then with 1, `to''s `$0' is `to', while it is `from' in 2.# The user will certainly prefer to see `to'.m4_define([m4_copy],[m4_define([$2], m4_defn([$1]))])# m4_rename(SRC, DST)# -------------------# Rename the macro SRC as DST.m4_define([m4_rename],[m4_copy([$1], [$2])m4_undefine([$1])])# m4_rename_m4(MACRO-NAME)# ------------------------# Rename MACRO-NAME as m4_MACRO-NAME.m4_define([m4_rename_m4],[m4_rename([$1], [m4_$1])])# m4_copy_unm4(m4_MACRO-NAME)# ---------------------------# Copy m4_MACRO-NAME as MACRO-NAME.m4_define([m4_copy_unm4],[m4_copy([$1], m4_bpatsubst([$1], [^m4_\(.*\)], [[\1]]))])# Some m4 internals have names colliding with tokens we might use.# Rename them a` la `m4 --prefix-builtins'.m4_rename_m4([builtin])m4_rename_m4([changecom])m4_rename_m4([changequote])m4_rename_m4([debugfile])m4_rename_m4([debugmode])m4_rename_m4([decr])m4_undefine([divert])m4_rename_m4([divnum])m4_rename_m4([dumpdef])m4_rename_m4([errprint])m4_rename_m4([esyscmd])m4_rename_m4([eval])m4_rename_m4([format])m4_rename_m4([ifdef])m4_rename([ifelse], [m4_if])m4_undefine([include])m4_rename_m4([incr])m4_rename_m4([index])m4_rename_m4([indir])m4_rename_m4([len])m4_rename([m4exit], [m4_exit])m4_rename([m4wrap], [m4_wrap])m4_rename_m4([maketemp])m4_rename([patsubst], [m4_bpatsubst])m4_undefine([popdef])m4_rename_m4([pushdef])m4_rename([regexp], [m4_bregexp])m4_rename_m4([shift])m4_undefine([sinclude])m4_rename_m4([substr])m4_rename_m4([symbols])m4_rename_m4([syscmd])m4_rename_m4([sysval])m4_rename_m4([traceoff])m4_rename_m4([traceon])m4_rename_m4([translit])m4_undefine([undivert])## ------------------- #### 2. Error messages. #### ------------------- ### m4_location# -----------m4_define([m4_location],[__file__:__line__])# m4_errprintn(MSG)# -----------------# Same as `errprint', but with the missing end of line.m4_define([m4_errprintn],[m4_errprint([$1])])# m4_warning(MSG)# ---------------# Warn the user.m4_define([m4_warning],[m4_errprintn(m4_location[: warning: $1])])# m4_fatal(MSG, [EXIT-STATUS])# ----------------------------# Fatal the user. :)m4_define([m4_fatal],[m4_errprintn(m4_location[: error: $1])dnlm4_expansion_stack_dump()dnlm4_exit(m4_if([$2],, 1, [$2]))])# m4_assert(EXPRESSION, [EXIT-STATUS = 1])# ----------------------------------------# This macro ensures that EXPRESSION evaluates to true, and exits if# EXPRESSION evaluates to false.m4_define([m4_assert],[m4_if(m4_eval([$1]), 0, [m4_fatal([assert failed: $1], [$2])])])## ------------- #### 3. Warnings. #### ------------- ### _m4_warn(CATEGORY, MESSAGE, STACK-TRACE)# ----------------------------------------# Report a MESSAGE to the user if the CATEGORY of warnings is enabled.# This is for traces only.# The STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE".m4_define([_m4_warn], [])# m4_warn(CATEGORY, MESSAGE)# --------------------------# Report a MESSAGE to the user if the CATEGORY of warnings is enabled.m4_define([m4_warn],[_m4_warn([$1], [$2],m4_ifdef([m4_expansion_stack], [m4_defn([m4_expansion_stack])m4_location[: the top level]]))dnl])## ------------------- #### 4. File inclusion. #### ------------------- ### We also want to neutralize include (and sinclude for symmetry),# but we want to extend them slightly: warn when a file is included# several times. This is in general a dangerous operation because# quite nobody quotes the first argument of m4_define.## For instance in the following case:# m4_define(foo, [bar])# then a second reading will turn into# m4_define(bar, [bar])# which is certainly not what was meant.# m4_include_unique(FILE)# -----------------------# Declare that the FILE was loading; and warn if it has already# been included.m4_define([m4_include_unique],[m4_ifdef([m4_include($1)], [m4_warn([syntax], [file `$1' included several times])])dnlm4_define([m4_include($1)])])# m4_include(FILE)# ----------------# As the builtin include, but warns against multiple inclusions.m4_define([m4_include],[m4_include_unique([$1])dnlm4_builtin([include], [$1])])# m4_sinclude(FILE)# -----------------# As the builtin sinclude, but warns against multiple inclusions.m4_define([m4_sinclude],[m4_include_unique([$1])dnlm4_builtin([sinclude], [$1])])## ------------------------------------ #### 5. Additional branching constructs. #### ------------------------------------ ### Both `m4_ifval' and `m4_ifset' tests against the empty string. The# difference is that `m4_ifset' is specialized on macros.## In case of arguments of macros, eg $[1], it makes little difference.# In the case of a macro `FOO', you don't want to check `m4_ifval(FOO,# TRUE)', because if `FOO' expands with commas, there is a shifting of# the arguments. So you want to run `m4_ifval([FOO])', but then you just# compare the *string* `FOO' against `', which, of course fails.## So you want a variation of `m4_ifset' that expects a macro name as $[1].# If this macro is both defined and defined to a non empty value, then# it runs TRUE etc.# m4_ifval(COND, [IF-TRUE], [IF-FALSE])# -------------------------------------# If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE.# Comparable to m4_ifdef.m4_define([m4_ifval],[m4_if([$1], [], [$3], [$2])])# m4_n(TEXT)# ----------# If TEXT is not empty, return TEXT and a new line, otherwise nothing.m4_define([m4_n],[m4_if([$1], [], [], [$1])])# m4_ifvaln(COND, [IF-TRUE], [IF-FALSE])# --------------------------------------# Same as `m4_ifval', but add an extra newline to IF-TRUE or IF-FALSE# unless that argument is empty.m4_define([m4_ifvaln],[m4_if([$1], [], [m4_n([$3])], [m4_n([$2])])])# m4_ifset(MACRO, [IF-TRUE], [IF-FALSE])# --------------------------------------# If MACRO has no definition, or of its definition is the empty string,# expand IF-FALSE, otherwise IF-TRUE.m4_define([m4_ifset],[m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])])# m4_ifndef(NAME, [IF-NOT-DEFINED], [IF-DEFINED])# -----------------------------------------------m4_define([m4_ifndef],[m4_ifdef([$1], [$3], [$2])])# m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT)# -----------------------------------------------------------# m4 equivalent of# switch (SWITCH)# {# case VAL1:# IF-VAL1;# break;# case VAL2:# IF-VAL2;# break;# ...# default:# DEFAULT;# break;# }.# All the values are optional, and the macro is robust to active# symbols properly quoted.m4_define([m4_case],[m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2], [$1], [$2], [$3], [$0([$1], m4_shiftn(3, $@))])])# m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT)# -----------------------------------------------------# m4 equivalent of## if (SWITCH =~ RE1)# VAL1;# elif (SWITCH =~ RE2)# VAL2;# elif ...# ...# else# DEFAULT## All the values are optional, and the macro is robust to active symbols# properly quoted.m4_define([m4_bmatch],[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], [$#], 2, [$2], [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shiftn(3, $@))], [$3])])])# m4_car(LIST)# m4_cdr(LIST)# ------------# Manipulate m4 lists.m4_define([m4_car], [[$1]])m4_define([m4_cdr],[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])])# m4_map(MACRO, LIST)# -------------------# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements# of LIST (which can be lists themselves, for multiple arguments MACROs).m4_define([m4_fst], [$1])m4_define([m4_map],[m4_if([$2], [[]], [], [_m4_map([$1], [$2])])])m4_define([_m4_map],[m4_ifval([$2], [$1(m4_fst($2))[]_m4_map([$1], m4_cdr($2))])])# m4_map_sep(MACRO, SEPARATOR, LIST)# ----------------------------------# Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1, $2... $N# are the elements of LIST (which can be lists themselves, for multiple# arguments MACROs).m4_define([m4_map_sep],[m4_if([$3], [[]], [], [$1(m4_fst($3))[]_m4_map([$2[]$1], m4_cdr($3))])])## ---------------------------------------- #### 6. Enhanced version of some primitives. #### ---------------------------------------- ### m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...)# ----------------------------------------------------# m4 equivalent of## $_ = STRING;# s/RE1/SUBST1/g;# s/RE2/SUBST2/g;# ...## All the values are optional, and the macro is robust to active symbols# properly quoted.## I would have liked to name this macro `m4_bpatsubst', unfortunately,# due to quotation problems, I need to double quote $1 below, therefore# the anchors are broken :( I can't let users be trapped by that.m4_define([m4_bpatsubsts],[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], [$#], 2, [m4_builtin([patsubst], $@)], [$0(m4_builtin([patsubst], [[$1]], [$2], [$3]), m4_shiftn(3, $@))])])# m4_do(STRING, ...)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -