⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m4sugar.m4

📁 autoconf是一个产生可以自动配置源代码包
💻 M4
📖 第 1 页 / 共 4 页
字号:
# If you strictly apply the rules given in the previous section you get:##	   GROW - 2: TEST3#	   GROW - 1: TEST2a; TEST2b#	   GROW:     TEST1#	   BODY:## (TEST2a, although required by TEST3 is not expanded in GROW - 3# because is has already been expanded before in GROW - 1, so it has# been AC_PROVIDE'd, so it is not expanded again) so when you undivert# the stack of diversions, you get:##	   GROW - 2:#	   GROW - 1:#	   GROW:#	   BODY:        TEST3; TEST2a; TEST2b; TEST1## i.e., TEST2a is expanded after TEST3 although the latter required the# former.## Starting from 2.50, uses an implementation provided by Axel Thimm.# The idea is simple: the order in which macros are emitted must be the# same as the one in which macro are expanded.  (The bug above can# indeed be described as: a macro has been AC_PROVIDE'd, but it is# emitted after: the lack of correlation between emission and expansion# order is guilty).## How to do that?  You keeping the stack of diversions to elaborate the# macros, but each time a macro is fully expanded, emit it immediately.## In the example above, when TEST2a is expanded, but it's epilogue is# not run yet, you have:##	   GROW - 2:#	   GROW - 1: TEST2a#	   GROW:     Elaboration of TEST1#	   BODY:## The epilogue of TEST2a emits it immediately:##	   GROW - 2:#	   GROW - 1:#	   GROW:     Elaboration of TEST1#	   BODY:     TEST2a## TEST2b then requires TEST3, so right before the epilogue of TEST3, you# have:##	   GROW - 2: TEST3#	   GROW - 1: Elaboration of TEST2b#	   GROW:     Elaboration of TEST1#	   BODY:      TEST2a## The epilogue of TEST3 emits it:##	   GROW - 2:#	   GROW - 1: Elaboration of TEST2b#	   GROW:     Elaboration of TEST1#	   BODY:     TEST2a; TEST3## TEST2b is now completely expanded, and emitted:##	   GROW - 2:#	   GROW - 1:#	   GROW:     Elaboration of TEST1#	   BODY:     TEST2a; TEST3; TEST2b## and finally, TEST1 is finished and emitted:##	   GROW - 2:#	   GROW - 1:#	   GROW:#	   BODY:     TEST2a; TEST3; TEST2b: TEST1## The idea is simple, but the implementation is a bit evolved.  If you# are like me, you will want to see the actual functioning of this# implementation to be convinced.  The next section gives the full# details.### The Axel Thimm implementation at work# -------------------------------------## We consider the macros above, and this configure.ac:##	    AC_INIT#	    TEST1## You should keep the definitions of _m4_defun_pro, _m4_defun_epi, and# m4_require at hand to follow the steps.## This implements tries not to assume that the current diversion is# BODY, so as soon as a macro (m4_defun'd) is expanded, we first# record the current diversion under the name _m4_divert_dump (denoted# DUMP below for short).  This introduces an important difference with# the previous versions of Autoconf: you cannot use m4_require if you# are not inside an m4_defun'd macro, and especially, you cannot# m4_require directly from the top level.## We have not tried to simulate the old behavior (better yet, we# diagnose it), because it is too dangerous: a macro m4_require'd from# the top level is expanded before the body of `configure', i.e., before# any other test was run.  I let you imagine the result of requiring# AC_STDC_HEADERS for instance, before AC_PROG_CC was actually run....## After AC_INIT was run, the current diversion is BODY.# * AC_INIT was run#   DUMP:                undefined#   diversion stack:     BODY |-## * TEST1 is expanded# The prologue of TEST1 sets _m4_divert_dump, which is the diversion# where the current elaboration will be dumped, to the current# diversion.  It also m4_divert_push to GROW, where the full# expansion of TEST1 and its dependencies will be elaborated.#   DUMP:        BODY#   BODY:        empty#   diversions:  GROW, BODY |-## * TEST1 requires TEST2a# _m4_require_call m4_divert_pushes another temporary diversion,# GROW - 1, and expands TEST2a in there.#   DUMP:        BODY#   BODY:        empty#   GROW - 1:    TEST2a#   diversions:  GROW - 1, GROW, BODY |-# Than the content of the temporary diversion is moved to DUMP and the# temporary diversion is popped.#   DUMP:        BODY#   BODY:        TEST2a#   diversions:  GROW, BODY |-## * TEST1 requires TEST2b# Again, _m4_require_call pushes GROW - 1 and heads to expand TEST2b.#   DUMP:        BODY#   BODY:        TEST2a#   diversions:  GROW - 1, GROW, BODY |-## * TEST2b requires TEST3# _m4_require_call pushes GROW - 2 and expands TEST3 here.# (TEST3 requires TEST2a, but TEST2a has already been m4_provide'd, so# nothing happens.)#   DUMP:        BODY#   BODY:        TEST2a#   GROW - 2:    TEST3#   diversions:  GROW - 2, GROW - 1, GROW, BODY |-# Than the diversion is appended to DUMP, and popped.#   DUMP:        BODY#   BODY:        TEST2a; TEST3#   diversions:  GROW - 1, GROW, BODY |-## * TEST1 requires TEST2b (contd.)# The content of TEST2b is expanded...#   DUMP:        BODY#   BODY:        TEST2a; TEST3#   GROW - 1:    TEST2b,#   diversions:  GROW - 1, GROW, BODY |-# ... and moved to DUMP.#   DUMP:        BODY#   BODY:        TEST2a; TEST3; TEST2b#   diversions:  GROW, BODY |-## * TEST1 is expanded: epilogue# TEST1's own content is in GROW...#   DUMP:        BODY#   BODY:        TEST2a; TEST3; TEST2b#   GROW:        TEST1#   diversions:  BODY |-# ... and it's epilogue moves it to DUMP and then undefines DUMP.#   DUMP:       undefined#   BODY:       TEST2a; TEST3; TEST2b; TEST1#   diversions: BODY |-### 2. Keeping track of the expansion stack# =======================================## When M4 expansion goes wrong it is often extremely hard to find the# path amongst macros that drove to the failure.  What is needed is# the stack of macro `calls'. One could imagine that GNU M4 would# maintain a stack of macro expansions, unfortunately it doesn't, so# we do it by hand.  This is of course extremely costly, but the help# this stack provides is worth it.  Nevertheless to limit the# performance penalty this is implemented only for m4_defun'd macros,# not for define'd macros.## The scheme is simplistic: each time we enter an m4_defun'd macros,# we prepend its name in m4_expansion_stack, and when we exit the# macro, we remove it (thanks to pushdef/popdef).## In addition, we want to detect circular m4_require dependencies.# Each time we expand a macro FOO we define _m4_expanding(FOO); and# m4_require(BAR) simply checks whether _m4_expanding(BAR) is defined.# m4_expansion_stack_push(TEXT)# -----------------------------m4_define([m4_expansion_stack_push],[m4_pushdef([m4_expansion_stack],	    [$1]m4_ifdef([m4_expansion_stack], [m4_defn([m4_expansion_stack])]))])# m4_expansion_stack_pop# ----------------------m4_define([m4_expansion_stack_pop],[m4_popdef([m4_expansion_stack])])# m4_expansion_stack_dump# -----------------------# Dump the expansion stack.m4_define([m4_expansion_stack_dump],[m4_ifdef([m4_expansion_stack],	  [m4_errprintn(m4_defn([m4_expansion_stack]))])dnlm4_errprintn(m4_location[: the top level])])# _m4_divert(GROW)# ----------------# This diversion is used by the m4_defun/m4_require machinery.  It is# important to keep room before GROW because for each nested# AC_REQUIRE we use an additional diversion (i.e., two m4_require's# will use GROW - 2.  More than 3 levels has never seemed to be# needed.)## ...# - GROW - 2#   m4_require'd code, 2 level deep# - GROW - 1#   m4_require'd code, 1 level deep# - GROW#   m4_defun'd macros are elaborated here.m4_define([_m4_divert(GROW)],       10000)# _m4_defun_pro(MACRO-NAME)# -------------------------# The prologue for Autoconf macros.m4_define([_m4_defun_pro],[m4_ifndef([m4_expansion_stack], [_m4_defun_pro_outer[]])dnlm4_expansion_stack_push(m4_defn([m4_location($1)])[: $1 is expanded from...])dnlm4_pushdef([_m4_expanding($1)])dnl])m4_define([_m4_defun_pro_outer],[m4_copy([_m4_divert_diversion], [_m4_divert_dump])dnlm4_divert_push([GROW])dnl])# _m4_defun_epi(MACRO-NAME)# -------------------------# The Epilogue for Autoconf macros.  MACRO-NAME only helps tracing# the PRO/EPI pairs.m4_define([_m4_defun_epi],[m4_popdef([_m4_expanding($1)])dnlm4_expansion_stack_pop()dnlm4_ifndef([m4_expansion_stack], [_m4_defun_epi_outer[]])dnlm4_provide([$1])dnl])m4_define([_m4_defun_epi_outer],[m4_undefine([_m4_divert_dump])dnlm4_divert_pop([GROW])dnlm4_undivert([GROW])dnl])# m4_defun(NAME, EXPANSION)# -------------------------# Define a macro which automatically provides itself.  Add machinery# so the macro automatically switches expansion to the diversion# stack if it is not already using it.  In this case, once finished,# it will bring back all the code accumulated in the diversion stack.# This, combined with m4_require, achieves the topological ordering of# macros.  We don't use this macro to define some frequently called# macros that are not involved in ordering constraints, to save m4# processing.m4_define([m4_defun],[m4_define([m4_location($1)], m4_location)dnlm4_define([$1],	  [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])# m4_defun_once(NAME, EXPANSION)# ------------------------------# As m4_defun, but issues the EXPANSION only once, and warns if used# several times.m4_define([m4_defun_once],[m4_define([m4_location($1)], m4_location)dnlm4_define([$1],	  [m4_provide_if([$1],			 [m4_warn([syntax], [$1 invoked multiple times])],			 [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])])# m4_pattern_forbid(ERE, [WHY])# -----------------------------# Declare that no token matching the extended regular expression ERE# should be seen in the output but if...m4_define([m4_pattern_forbid], [])# m4_pattern_allow(ERE)# ---------------------# ... but if that token matches the extended regular expression ERE.# Both used via traces.m4_define([m4_pattern_allow], [])## ----------------------------- #### Dependencies between macros.  #### ----------------------------- ### m4_before(THIS-MACRO-NAME, CALLED-MACRO-NAME)# ---------------------------------------------m4_define([m4_before],[m4_provide_if([$2],	       [m4_warn([syntax], [$2 was called before $1])])])# m4_require(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK])# -----------------------------------------------------------# If NAME-TO-CHECK has never been expanded (actually, if it is not# m4_provide'd), expand BODY-TO-EXPAND *before* the current macro# expansion.  Once expanded, emit it in _m4_divert_dump.  Keep track# of the m4_require chain in m4_expansion_stack.## The normal cases are:## - NAME-TO-CHECK == BODY-TO-EXPAND#   Which you can use for regular macros with or without arguments, e.g.,#     m4_require([AC_PROG_CC], [AC_PROG_CC])#     m4_require([AC_CHECK_HEADERS(limits.h)], [AC_CHECK_HEADERS(limits.h)])#   which is just the same as#     m4_require([AC_PROG_CC])#     m4_require([AC_CHECK_HEADERS(limits.h)])## - BODY-TO-EXPAND == m4_indir([NAME-TO-CHECK])#   In the case of macros with irregular names.  For instance:#     m4_require([AC_LANG_COMPILER(C)], [indir([AC_LANG_COMPILER(C)])])#   which means `if the macro named `AC_LANG_COMPILER(C)' (the parens are#   part of the name, it is not an argument) has not been run, then#   call it.'#   Had you used#     m4_require([AC_LANG_COMPILER(C)], [AC_LANG_COMPILER(C)])#   then m4_require would have tried to expand `AC_LANG_COMPILER(C)', i.e.,#   call the macro `AC_LANG_COMPILER' with `C' as argument.##   You could argue that `AC_LANG_COMPILER', when it receives an argument#   such as `C' should dispatch the call to `AC_LANG_COMPILER(C)'.  But this#   `extension' prevents `AC_LANG_COMPILER' from having actual arguments that#   it passes to `AC_LANG_COMPILER(C)'.m4_define([m4_require],[m4_ifdef([_m4_expanding($1)],	 [m4_fatal([$0: circular dependency of $1])])dnlm4_ifndef([_m4_divert_dump],	  [m4_fatal([$0($1): cannot be used outside of an ]dnlm4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])dnlm4_provide_if([$1],	      [],	      [_m4_require_call([$1], [$2])])dnl])# _m4_require_call(BODY-TO-EXPAND)# --------------------------------# If m4_require decides to expand the body, it calls this macro.m4_define([_m4_require_call],[m4_define([_m4_divert_grow], m4_decr(_m4_divert_grow))dnlm4_divert_push(_m4_divert_grow)dnlm4_default([$2], [$1])m4_provide_if([$1],	      [],	      [m4_warn([syntax],		       [$1 is m4_require'd but not m4_defun'd])])dnlm4_divert(m4_defn([_m4_divert_dump]))dnlm4_undivert(_m4_divert_grow)dnlm4_divert_pop(_m4_divert_grow)dnlm4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))dnl])# _m4_divert_grow# ---------------# The counter for _m4_require_call.m4_define([_m4_divert_grow], _m4_divert([GROW]))# m4_expand_once(TEXT, [WITNESS = TEXT])# --------------------------------------# If TEXT has never been expanded, expand it *here*.  Use WITNESS as# as a memory that TEXT has already been expanded.m4_define([m4_expand_once],[m4_provide_if(m4_ifval([$2], [[$2]], [[$1]]),	       [],	       [m4_provide(m4_ifval([$2], [[$2]], [[$1]]))[]$1])])# m4_provide(MACRO-NAME)# ----------------------m4_define([m4_provide],[m4_define([m4_provide($1)])])# m4_provide_if(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)# -------------------------------------------------------# If MACRO-NAME is provided do IF-PROVIDED, else IF-NOT-PROVIDED.# The purpose of this macro is to provide the user with a means to# check macros which are provided without letting her know how the# information is coded.m4_define([m4_provide_if],[m4_ifdef([m4_provide($1)],	  [$2], [$3])])## -------------------- #### 9. Text processing.  #### -------------------- ### m4_cr_letters# m4_cr_LETTERS# m4_cr_Letters# -------------m4_define([m4_cr_letters], [abcdefghijklmnopqrstuvwxyz])m4_define([m4_cr_LETTERS], [ABCDEFGHIJKLMNOPQRSTUVWXYZ])m4_define([m4_cr_Letters],m4_defn([m4_cr_letters])dnlm4_defn([m4_cr_LETTERS])dnl)# m4_cr_digits# ------------m4_define([m4_cr_digits], [0123456789])# m4_cr_symbols1 & m4_cr_symbols2# -------------------------------m4_define([m4_cr_symbols1],m4_defn([m4_cr_Letters])dnl_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -