~ubuntu-branches/ubuntu/lucid/autoconf/lucid

« back to all changes in this revision

Viewing changes to bin/autoupdate.in

  • Committer: Bazaar Package Importer
  • Author(s): Ben Pfaff
  • Date: 2002-03-27 21:52:33 UTC
  • Revision ID: james.westby@ubuntu.com-20020327215233-r3gmxall0x27s306
Tags: upstream-2.53
ImportĀ upstreamĀ versionĀ 2.53

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! @PERL@ -w
 
2
# -*- perl -*-
 
3
# autoupdate - modernize an Autoconf file.
 
4
# Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
 
5
 
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2, or (at your option)
 
9
# any later version.
 
10
 
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
 
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program; if not, write to the Free Software
 
18
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
# 02111-1307, USA.
 
20
 
 
21
# Originally written by David MacKenzie <djm@gnu.ai.mit.edu>.
 
22
# Rewritten by Akim Demaille <akim@freefriends.org>.
 
23
 
 
24
eval 'exec @PERL@ -S $0 ${1+"$@"}'
 
25
    if 0;
 
26
 
 
27
BEGIN
 
28
{
 
29
  my $perllibdir = $ENV{'autom4te_perllibdir'} || "@datadir@";
 
30
  unshift @INC, "$perllibdir";
 
31
}
 
32
 
 
33
use File::Basename;
 
34
use Autom4te::General;
 
35
use Autom4te::XFile;
 
36
use strict;
 
37
 
 
38
# Lib files.
 
39
my $autom4te = $ENV{'AUTOM4TE'} || '@autom4te-name@';
 
40
my $autoconf = "$autom4te --language=autoconf";
 
41
# We need to find m4sugar.
 
42
my @include = ('@datadir@');
 
43
my $force = 0;
 
44
# m4.
 
45
my $m4 = $ENV{"M4"} || "@M4@";
 
46
 
 
47
 
 
48
# $HELP
 
49
# -----
 
50
$help = "Usage: $0 [OPTION] ...  [TEMPLATE-FILE...]
 
51
 
 
52
Update the TEMPLATE-FILE... if given, or `configure.ac' if present,
 
53
or else `configure.in', to the syntax of the current version of
 
54
Autoconf.  The original files are backed up.
 
55
 
 
56
Operation modes:
 
57
  -h, --help           print this help, then exit
 
58
  -V, --version        print version number, then exit
 
59
  -v, --verbose        verbosely report processing
 
60
  -d, --debug          don't remove temporary files
 
61
  -I, --include=DIR    look for input files in DIR (cumulative)
 
62
  -f, --force          consider all files obsolete
 
63
 
 
64
Report bugs to <bug-autoconf\@gnu.org>.
 
65
";
 
66
 
 
67
# $VERSION
 
68
# --------
 
69
$version = "autoupdate (@PACKAGE_NAME@) @VERSION@
 
70
Written by David J. MacKenzie and Akim Demaille.
 
71
 
 
72
Copyright 2002 Free Software Foundation, Inc.
 
73
This is free software; see the source for copying conditions.  There is NO
 
74
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
75
";
 
76
 
 
77
## ---------- ##
 
78
## Routines.  ##
 
79
## ---------- ##
 
80
 
 
81
 
 
82
# parse_args ()
 
83
# -------------
 
84
# Process any command line arguments.
 
85
sub parse_args ()
 
86
{
 
87
  my $srcdir;
 
88
 
 
89
  getopt ('I|include|A|autoconf-dir|m|macrodir|l|localdir=s' => \@include,
 
90
          'f|force' => \$force);
 
91
 
 
92
  if (! @ARGV)
 
93
    {
 
94
      my $configure_ac = find_configure_ac;
 
95
      die "$me: no input file\n"
 
96
        unless $configure_ac;
 
97
      push @ARGV, $configure_ac;
 
98
    }
 
99
}
 
100
 
 
101
 
 
102
# ------------- #
 
103
# M4 builtins.  #
 
104
# ------------- #
 
105
 
 
106
my @m4_builtins;
 
107
 
 
108
# &handle_m4_symbols ()
 
109
# ---------------------
 
110
# Create the following $tmp files:
 
111
# m4.m4 -- enable the m4 builtins.
 
112
# unm4.m4 -- disable the m4 builtins.
 
113
# savem4.m4 -- save the m4 builtins.
 
114
sub handle_m4_macros ()
 
115
{
 
116
  # Get the list of builtins.
 
117
  xsystem ("echo dumpdef | $m4 2>$tmp/m4.defs >/dev/null");
 
118
  my $m4_defs = new Autom4te::XFile "$tmp/m4.defs";
 
119
  while ($_ = $m4_defs->getline)
 
120
    {
 
121
      push @m4_builtins, $1
 
122
        if /^(\w+):/;
 
123
    }
 
124
  $m4_defs->close;
 
125
 
 
126
  # Output the files.
 
127
  my $m4_m4 = new Autom4te::XFile ">$tmp/m4.m4";
 
128
  print $m4_m4 "# m4.m4 -- enable the m4 builtins.\n";
 
129
  my $unm4_m4 = new Autom4te::XFile ">$tmp/unm4.m4";
 
130
  print $unm4_m4 "# unm4.m4 -- disable the m4 builtins.\n";
 
131
  print $unm4_m4 "# Because Autoconf, via M4sugar, redefines some of these\n";
 
132
  print $unm4_m4 "# macros, and therefore since unac.m4 disables them,\n";
 
133
  print $unm4_m4 "# disable only if defined.\n";
 
134
  my $m4save_m4 = new Autom4te::XFile ">$tmp/m4save.m4";
 
135
  print $m4save_m4 "# savem4.m4 -- save the m4 builtins.\n";
 
136
  foreach (@m4_builtins)
 
137
    {
 
138
      print $m4save_m4 "define([_au_$_], defn([$_]))\n";
 
139
      print $unm4_m4   "_au_ifdef([$_], [_au_undefine([$_])])\n";
 
140
      print $m4_m4     "_au_define([$_], _au_defn([_au_$_]))\n";
 
141
    }
 
142
}
 
143
 
 
144
 
 
145
 
 
146
# ----------------- #
 
147
# Autoconf macros.  #
 
148
# ----------------- #
 
149
 
 
150
 
 
151
# @AU_MACROS & AC_MACROS -- AU and AC macros and yet another useful comment.
 
152
my (%ac_macros, %au_macros);
 
153
 
 
154
 
 
155
# HANDLE_AUTOCONF_MACROS ()
 
156
# -------------------------
 
157
# @M4_BUILTINS -- M4 builtins and a useful comment.
 
158
sub handle_autoconf_macros ()
 
159
{
 
160
  my $macros = new Autom4te::XFile ("$autoconf"
 
161
                             . " --trace AU_DEFUN:'AU:\$f:\$1'"
 
162
                             . " --trace define:'AC:\$f:\$1'"
 
163
                             . " --melt /dev/null |");
 
164
  while ($_ = $macros->getline)
 
165
    {
 
166
      chomp;
 
167
      my ($domain, $file, $macro) = /^(AC|AU):(.*):([^:]*)$/ or next;
 
168
      # ../lib/m4sugar/m4sugar.m4  -> m4sugar
 
169
      # ../lib/autoconf/general.m4 -> autoconf
 
170
      # aclocal.m4 -> ignore
 
171
      next
 
172
        if $file eq 'aclocal.m4';
 
173
      my $set = basename (dirname ($file));
 
174
      die "$me: unknown set: $set: $_\n"
 
175
        unless $set =~ /^(m4sugar|autoconf)$/;
 
176
      if ($domain eq "AC")
 
177
        {
 
178
          $ac_macros{$macro} = $set;
 
179
        }
 
180
      else
 
181
        {
 
182
          $au_macros{$macro} = $set;
 
183
        }
 
184
    }
 
185
  $macros->close;
 
186
 
 
187
  # Don't keep AU macros in @AC_MACROS.
 
188
  delete $ac_macros{$_}
 
189
    foreach (keys %au_macros);
 
190
  # Don't keep M4sugar macros which are redefined by Autoconf,
 
191
  # such as `builtin', `changequote' etc.  See autoconf/autoconf.m4.
 
192
  delete $ac_macros{$_}
 
193
    foreach (@m4_builtins);
 
194
  die "$me: no current Autoconf macros found\n"
 
195
    unless keys %ac_macros;
 
196
  die "$me: no obsolete Autoconf macros found\n"
 
197
    unless keys %au_macros;
 
198
 
 
199
  if ($debug)
 
200
    {
 
201
      print STDERR "Current Autoconf macros:\n";
 
202
      print STDERR join (' ', sort keys %ac_macros) . "\n\n";
 
203
      print STDERR "Obsolete Autoconf macros:\n";
 
204
      print STDERR join (' ', sort keys %au_macros) . "\n\n";
 
205
    }
 
206
 
 
207
  # ac.m4 -- autoquoting definitions of the AC macros (M4sugar excluded).
 
208
  # unac.m4 -- undefine the AC macros.
 
209
  my $ac_m4 = new Autom4te::XFile ">$tmp/ac.m4";
 
210
  print $ac_m4 "# ac.m4 -- autoquoting definitions of the AC macros.\n";
 
211
  my $unac_m4 = new Autom4te::XFile ">$tmp/unac.m4";
 
212
  print $unac_m4 "# unac.m4 -- undefine the AC macros.\n";
 
213
  foreach (sort grep { $ac_macros{$_} ne 'm4sugar' } keys %ac_macros)
 
214
    {
 
215
      print $ac_m4   "_au_define([$_], [[\$0(\$\@)]])\n";
 
216
      print $unac_m4 "_au_undefine([$_])\n";
 
217
    }
 
218
}
 
219
 
 
220
 
 
221
## -------------- ##
 
222
## Main program.  ##
 
223
## -------------- ##
 
224
 
 
225
parse_args;
 
226
$autoconf .= " --debug" if $debug;
 
227
$autoconf .= " --force" if $force;
 
228
$autoconf .= " --verbose" if $verbose;
 
229
$autoconf .= join (' --include=', '', @include);
 
230
 
 
231
mktmpdir ('au');
 
232
handle_m4_macros;
 
233
handle_autoconf_macros;
 
234
 
 
235
# $au_changequote -- enable the quote `[', `]' right before any AU macro.
 
236
my $au_changequote =
 
237
  's/\b(' . join ('|', keys %au_macros) . ')\b/_au_changequote([,])$1/g';
 
238
 
 
239
# au.m4 -- definitions the AU macros.
 
240
xsystem ("$autoconf --trace AU_DEFUN:'_au_defun(\@<:\@\$1\@:>\@,
 
241
\@<:\@\$2\@:>\@)' --melt /dev/null "
 
242
        . ">$tmp/au.m4");
 
243
 
 
244
 
 
245
 
 
246
## ------------------- ##
 
247
## Process the files.  ##
 
248
## ------------------- ##
 
249
 
 
250
foreach my $file (@ARGV)
 
251
  {
 
252
    my $filename = $file;
 
253
    # We need an actual file.
 
254
    if ($file eq '-')
 
255
      {
 
256
        $file = "$tmp/stdin";
 
257
        system "cat >$file";
 
258
      }
 
259
    elsif (! -r "$file")
 
260
      {
 
261
        die "$me: $file: No such file or directory";
 
262
      }
 
263
 
 
264
    # input.m4 -- m4 program to produce the updated file.
 
265
    # Load the values, the dispatcher, neutralize m4, and the prepared
 
266
    # input file.
 
267
    my $input_m4 = <<\EOF;
 
268
      divert(-1)                                            -*- Autoconf -*-
 
269
      changequote([, ])
 
270
 
 
271
      # Move all the builtins into the `_au_' pseudo namespace
 
272
      include([m4save.m4])
 
273
 
 
274
      # _au_defun(NAME, BODY)
 
275
      # ---------------------
 
276
      # Define NAME to BODY, plus AU activation/deactivation.
 
277
      _au_define([_au_defun],
 
278
      [_au_define([$1],
 
279
      [_au_enable()dnl
 
280
      $2[]dnl
 
281
      _au_disable()])])
 
282
 
 
283
      # Import the definition of the obsolete macros.
 
284
      _au_include([au.m4])
 
285
 
 
286
 
 
287
      ## ------------------------ ##
 
288
      ## _au_enable/_au_disable.  ##
 
289
      ## ------------------------ ##
 
290
 
 
291
      # They work by pair: each time an AU macro is activated, it runs
 
292
      # _au_enable, and at its end its runs _au_disable (see _au_defun
 
293
      # above).  But since AU macros might use AU macros, which should
 
294
      # enable/disable only for the outter AU macros.
 
295
      #
 
296
      # `_au_enabled' is used to this end, condionning whether we really
 
297
      # enable/disable.
 
298
 
 
299
 
 
300
      # __au_enable
 
301
      # -----------
 
302
      # Reenable the builtins, and m4sugar.
 
303
      _au_define([__au_enable],
 
304
      [_au_divert(-1)
 
305
      # Enable special characters.
 
306
      _au_changecom([#])
 
307
 
 
308
      # Enable the m4 builtins, m4sugar and the autoquoting AC macros.
 
309
      _au_include([m4.m4])
 
310
      _au_include([m4sugar/m4sugar.m4])
 
311
      _au_include([ac.m4])
 
312
 
 
313
      _au_divert(0)])
 
314
 
 
315
      # _au_enable
 
316
      # ----------
 
317
      # Called at the beginning of all the obsolete macros.  Reenable the
 
318
      # builtins, and m4sugar if needed.
 
319
      _au_define([_au_enable],
 
320
      [_au_ifdef([_au_enabled],
 
321
                 [],
 
322
                 [__au_enable()])_au_dnl
 
323
      _au_pushdef([_au_enabled])])
 
324
 
 
325
 
 
326
      # __au_disable
 
327
      # ------------
 
328
      # Disable the builtins, and m4sugar.
 
329
      _au_define([__au_disable],
 
330
      [_au_divert(-1)
 
331
      # Disable m4sugar, the AC autoquoting macros, and m4.
 
332
      _au_include([unac.m4])
 
333
      _au_include([unm4.m4])
 
334
 
 
335
      # Disable special characters.
 
336
      _au_changequote()
 
337
      _au_changecom()
 
338
 
 
339
      _au_divert(0)])
 
340
 
 
341
      # _au_disable
 
342
      # -----------
 
343
      # Called at the end of all the obsolete macros.  Disable the
 
344
      # builtins, and m4sugar if needed..
 
345
      _au_define([_au_disable],
 
346
      [_au_popdef([_au_enabled])_au_dnl
 
347
      _au_ifdef([_au_enabled],
 
348
                [],
 
349
                [__au_disable()])])
 
350
 
 
351
 
 
352
      ## ------------------------------- ##
 
353
      ## Disable, and process the file.  ##
 
354
      ## ------------------------------- ##
 
355
      _au_divert(-1)
 
356
      # Disable m4: M4sugar and the AC autoquoting macros are not loaded yet,
 
357
      # hence invoking `_au_disable' is wrong.
 
358
      _au_include([unm4.m4])
 
359
 
 
360
      # Disable special characters.
 
361
      _au_changequote()
 
362
      _au_changecom()
 
363
 
 
364
      _au_divert(0)_au_dnl
 
365
EOF
 
366
 
 
367
    $input_m4 =~ s/^      //mg;
 
368
 
 
369
    # prepared input -- input, but reenables the quote before each AU macro.
 
370
    open INPUT_M4, ">$tmp/input.m4"
 
371
       or die "$me: cannot open: $!\n";
 
372
    open FILE, "<$file"
 
373
       or die "$me: cannot open: $!\n";
 
374
    print INPUT_M4 "$input_m4";
 
375
    while (<FILE>)
 
376
       {
 
377
         eval $au_changequote;
 
378
         print INPUT_M4;
 
379
       }
 
380
    close FILE
 
381
       or die "$me: cannot close $file: $!\n";
 
382
    close INPUT_M4
 
383
       or die "$me: cannot close $tmp/input.m4: $!\n";
 
384
 
 
385
    # Now ask m4 to perform the update.
 
386
    # M4 and I don't agree on the associativity of `--include': reverse!
 
387
    xsystem ("$m4"
 
388
             . join (' --include=', '', reverse (@include, $tmp))
 
389
             . " $tmp/input.m4 >$tmp/updated");
 
390
    update_file ("$tmp/updated",
 
391
                 "$file" eq "$tmp/stdin" ? '-' : "$file");
 
392
  }
 
393
exit 0;
 
394
 
 
395
 
 
396
#                 ## ---------------------------- ##
 
397
#                 ## How `autoupdate' functions.  ##
 
398
#                 ## ---------------------------- ##
 
399
#
 
400
# The task of `autoupdate' is not trivial: the biggest difficulty being
 
401
# that you must limit the changes to the parts that really need to be
 
402
# updated.  Finding a satisfying implementation proved to be quite hard,
 
403
# as this is the fourth implementation of `autoupdate'.
 
404
#
 
405
# Below, we will use a simple example of obsolete macro:
 
406
#
 
407
#     AU_DEFUN([OLD], [NEW([$1, $2], m4_eval([$1 + $2]))])
 
408
#     AC_DEFUN([NEW], [echo "sum($1) = $2"])
 
409
#
 
410
# the input file contains
 
411
#
 
412
#     dnl The Unbelievable Truth
 
413
#     OLD(1, 2)
 
414
#     NEW([0, 0], [0])
 
415
#
 
416
# Of course the expected output is
 
417
#
 
418
#     dnl The Unbelievable Truth
 
419
#     NEW([1, 2], [3])
 
420
#     NEW([0, 0], [0])
 
421
#
 
422
#
 
423
# # First implementation: sed
 
424
# # =========================
 
425
#
 
426
# The first implementation was only able to change the name of obsolete
 
427
# macros.
 
428
#
 
429
# The file `acoldnames.m4' defined the old names based on the new names.
 
430
# It was simple then to produce a sed script such as:
 
431
#
 
432
#     s/OLD/NEW/g
 
433
#
 
434
# Updating merely consisted in running this script on the file to
 
435
# update.
 
436
#
 
437
# This scheme suffers an obvious limitation: that `autoupdate' was
 
438
# unable to cope with new macros that just swap some of its arguments
 
439
# compared to the old macro.  Fortunately, that was enough to upgrade
 
440
# from Autoconf 1 to Autoconf 2.  (But I have no idea whether the
 
441
# changes in Autoconf 2 were precisely limited by this constraint.)
 
442
#
 
443
#
 
444
# # Second implementation: hooks
 
445
# # ============================
 
446
#
 
447
# The version 2.15 of Autoconf brought a vast number of changes compared
 
448
# to 2.13, so a solution was needed.  One could think to extend the
 
449
# `sed' scripts with specialized code for complex macros.  But this
 
450
# approach is of course full of flaws:
 
451
#
 
452
# a. the Autoconf maintainers have to write these snippets, which we
 
453
#    just don't want to,
 
454
#
 
455
# b. I really don't think you'll ever manage to handle the quoting of
 
456
#    m4 from sed.
 
457
#
 
458
# To satisfy a., let's remark that the code which implements the old
 
459
# features in term of the new feature is exactly the code which should
 
460
# replace the old code.
 
461
#
 
462
# To answer point b, as usual in the history of Autoconf, the answer, at
 
463
# least on the paper, is simple: m4 is the best tool to parse m4, so
 
464
# let's use m4.
 
465
#
 
466
# Therefore the specification is:
 
467
#
 
468
#     I want to be able to tell Autoconf, well, m4, that the macro I
 
469
#     am currently defining is an obsolete macro (so that the user is
 
470
#     warned), which code is the code to use when running autoconf,
 
471
#     but that the very same code has to be used when running
 
472
#     autoupdate.  To summarize, the interface I want is
 
473
#     `AU_DEFUN(OLD-NAME, NEW-CODE)'.
 
474
#
 
475
#
 
476
# Now for the technical details.
 
477
#
 
478
# When running autoconf, except for the warning, AU_DEFUN is basically
 
479
# AC_DEFUN.
 
480
#
 
481
# When running autoupdate, we want *only* OLD-NAMEs to be expanded.
 
482
# This obviously means that acgeneral.m4 and acspecific.m4 must not be
 
483
# loaded.  Nonetheless, because we want to use a rich set of m4
 
484
# features, m4sugar.m4 is needed.  Please note that the fact that
 
485
# Autoconf's macros are not loaded is positive on two points:
 
486
#
 
487
# - we do get an updated `configure.ac', not a `configure'!
 
488
#
 
489
# - the old macros are replaced by *calls* to the new-macros, not the
 
490
#   body of the new macros, since their body is not defined!!!
 
491
#   (Whoa, that's really beautiful!).
 
492
#
 
493
# Additionally we need to disable the quotes when reading the input for
 
494
# two reasons: first because otherwise `m4' will swallow the quotes of
 
495
# other macros:
 
496
#
 
497
#     NEW([1, 2], 3)
 
498
#     => NEW(1, 2, 3)
 
499
#
 
500
# and second, because we want to update the macro calls which are
 
501
# quoted, i.e., we want
 
502
#
 
503
#     FOO([OLD(1, 2)])
 
504
#     => FOO([NEW([1, 2], [3])])
 
505
#
 
506
# If we don't disable the quotes, only the macros called at the top
 
507
# level would be updated.
 
508
#
 
509
# So, let's disable the quotes.
 
510
#
 
511
# Well, not quite: m4sugar.m4 still needs to use quotes for some macros.
 
512
# Well, in this case, when running in autoupdate code, each macro first
 
513
# reestablishes the quotes, expands itself, and disables the quotes.
 
514
#
 
515
# Thinking a bit more, you realize that in fact, people may use `define'
 
516
# `ifelse' etc. in their files, and you certainly don't want to process
 
517
# them.  Another example is `dnl': you don't want to remove the
 
518
# comments.  You then realize you don't want exactly to import m4sugar:
 
519
# you want to specify when it is enabled (macros active), and disabled.
 
520
# m4sugar provides m4_disable/m4_enable to this end.
 
521
#
 
522
# You're getting close to it.  Now remains one task: how to handle
 
523
# twofold definitions?
 
524
#
 
525
# Remember that the same AU_DEFUN must be understood in two different
 
526
# ways, the AC way, and the AU way.
 
527
#
 
528
# One first solution is to check whether acgeneral.m4 was loaded.  But
 
529
# that's definitely not cute.  Another is simply to install `hooks',
 
530
# that is to say, to keep in some place m4 knows, late `define' to be
 
531
# triggered *only* in AU mode.
 
532
#
 
533
# You first think to design AU_DEFUN like this:
 
534
#
 
535
# 1. AC_DEFUN(OLD-NAME,
 
536
#             [Warn the user OLD-NAME is obsolete.
 
537
#              NEW-CODE])
 
538
#
 
539
# 2. Store for late AU binding([define(OLD_NAME,
 
540
#                               [Reestablish the quotes.
 
541
#                                NEW-CODE
 
542
#                                Disable the quotes.])])
 
543
#
 
544
# but this will not work: NEW-CODE has probably $1, $2 etc. and these
 
545
# guys will be replaced with the argument of `Store for late AU binding'
 
546
# when you call it.
 
547
#
 
548
# I don't think there is a means to avoid this using this technology
 
549
# (remember that $1 etc. are *always* expanded in m4).  You may also try
 
550
# to replace them with $[1] to preserve them for a later evaluation, but
 
551
# if `Store for late AU binding' is properly written, it will remain
 
552
# quoted till the end...
 
553
#
 
554
# You have to change technology.  Since the problem is that `$1'
 
555
# etc. should be `consumed' right away, one solution is to define now a
 
556
# second macro, `AU_OLD-NAME', and to install a hook than binds OLD-NAME
 
557
# to AU_OLD-NAME.  Then, autoupdate.m4 just need to run the hooks.  By
 
558
# the way, the same method was used in autoheader.
 
559
#
 
560
#
 
561
# # Third implementation: m4 namespaces by m4sugar
 
562
# # ==============================================
 
563
#
 
564
# Actually, this implementation was just a clean up of the previous
 
565
# implementation: instead of defining hooks by hand, m4sugar was equipped
 
566
# with `namespaces'.  What are they?
 
567
#
 
568
# Sometimes we want to disable some *set* of macros, and restore them
 
569
# later.  We provide support for this via namespaces.
 
570
#
 
571
# There are basically three characters playing this scene: defining a
 
572
# macro in a namespace, disabling a namespace, and restoring a namespace
 
573
# (i.e., all the definitions it holds).
 
574
#
 
575
# Technically, to define a MACRO in NAMESPACE means to define the macro
 
576
# named `NAMESPACE::MACRO' to the VALUE.  At the same time, we append
 
577
# `undefine(NAME)' in the macro named `m4_disable(NAMESPACE)', and
 
578
# similarly a binding of NAME to the value of `NAMESPACE::MACRO' in
 
579
# `m4_enable(NAMESPACE)'.  These mechanisms allow to bind the macro of
 
580
# NAMESPACE and to unbind them at will.
 
581
#
 
582
# Of course this implementation is really inefficient: m4 has to grow
 
583
# strings which can become quickly huge, which slows it significantly.
 
584
#
 
585
# In particular one should avoid as much as possible to use `define' for
 
586
# temporaries.  Now that `define' as quite a complex meaning, it is an
 
587
# expensive operations that should be limited to macros.  Use
 
588
# `m4_define' for temporaries.
 
589
#
 
590
# Private copies of the macros we used in entering / exiting the m4sugar
 
591
# namespace.  It is much more convenient than fighting with the renamed
 
592
# version of define etc.
 
593
#
 
594
#
 
595
#
 
596
# Those two implementations suffered from serious problems:
 
597
#
 
598
# - namespaces were really expensive, and incurred a major performance
 
599
#   loss on `autoconf' itself, not only `autoupdate'.  One solution
 
600
#   would have been the limit the use of namespaces to `autoupdate', but
 
601
#   that's again some complications on m4sugar, which really doesn't need
 
602
#   this.  So we wanted to get rid of the namespaces.
 
603
#
 
604
# - since the quotes were disabled, autoupdate was sometimes making
 
605
#   wrong guesses, for instance on:
 
606
#
 
607
#     foo([1, 2])
 
608
#
 
609
#   m4 saw 2 arguments: `[1'and `2]'.  A simple solution, somewhat
 
610
#   fragile, is to reestablish the quotes right before all the obsolete
 
611
#   macros, i.e., to use sed so that the previous text becomes
 
612
#
 
613
#     changequote([, ])foo([1, 2])
 
614
#
 
615
#   To this end, one wants to trace the definition of obsolete macros.
 
616
#
 
617
# It was there that the limitations of the namespace approach became
 
618
# painful: because it was a complex machinery playing a lot with the
 
619
# builtins of m4 (hence, quite fragile), tracing was almost impossible.
 
620
#
 
621
#
 
622
# So this approach was dropped.
 
623
#
 
624
#
 
625
# # The fourth implementation: two steps
 
626
# # ====================================
 
627
#
 
628
# If you drop the uses of namespaces, you no longer can compute the
 
629
# updated value, and replace the old call with it simultaneously.
 
630
#
 
631
# Obviously you will use m4 to compute the updated values, but you may
 
632
# use some other tool to achieve the replacement.  Personally, I trust
 
633
# nobody but m4 to parse m4, so below, m4 will perform the two tasks.
 
634
#
 
635
# How can m4 be used to replace *some* macros calls with newer values.
 
636
# Well, that's dead simple: m4 should learn the definitions of obsolete
 
637
# macros, forget its builtins, disable the quotes, and then run on the
 
638
# input file, which amounts to doing this:
 
639
#
 
640
#     divert(-1)dnl
 
641
#     changequote([, ])
 
642
#     define([OLD], [NEW([$1, $2], m4_eval([$1 + $2]))changequote()])
 
643
#     undefine([dnl])
 
644
#     undefine([m4_eval])
 
645
#     # Some more undefines...
 
646
#     changequote()
 
647
#     divert(0)dnl
 
648
#     dnl The Unbelievable Truth
 
649
#     changequote([, ])OLD(1, 2)
 
650
#     NEW([0, 0],
 
651
#         0)
 
652
#
 
653
# which will result in
 
654
#
 
655
#     dnl The Unbelievable Truth
 
656
#     NEW(1, 2, m4_eval(1 + 2))
 
657
#     NEW([0, 0],
 
658
#         0)
 
659
#
 
660
# Grpmh.  Two problems.  A minor problem: it would have been much better
 
661
# to have the `m4_eval' computed, and a major problem: you lost the
 
662
# quotation in the result.
 
663
#
 
664
# Let's address the big problem first.  One solution is to define any
 
665
# modern macro to rewrite its calls with the proper quotation, thanks to
 
666
# `$@'.  Again, tracing the `define's makes it possible to know which
 
667
# are these macros, so you input is:
 
668
#
 
669
#     divert(-1)dnl
 
670
#     changequote([, ])
 
671
#     define([OLD], [NEW([$1, $2], m4_eval([$1 + $2]))changequote()])
 
672
#     define([NEW], [[NEW($@)]changequote()])
 
673
#     undefine([dnl])
 
674
#     undefine([m4_eval])
 
675
#     # Some more undefines...
 
676
#     changequote()
 
677
#     divert(0)dnl
 
678
#     dnl The Unbelievable Truth
 
679
#     changequote([, ])OLD(1, 2)
 
680
#     changequote([, ])NEW([0, 0],
 
681
#         0)
 
682
#
 
683
# which results in
 
684
#
 
685
#     dnl The Unbelievable Truth
 
686
#     NEW([1, 2],[m4_eval(1 + 2)])
 
687
#     NEW([0, 0],[0])
 
688
#
 
689
# Our problem is solved, i.e., the first call to `NEW' is properly
 
690
# quoted, but introduced another problem: we changed the layout of the
 
691
# second calls, which can be a drama in the case of huge macro calls
 
692
# (think of `AC_TRY_RUN' for instance).  This example didn't show it,
 
693
# but we also introduced parens to macros which did not have some:
 
694
#
 
695
#     AC_INIT
 
696
#     => AC_INIT()
 
697
#
 
698
# No big deal for the semantics (unless the macro depends upon $#, which
 
699
# is bad), but the users would not be happy.
 
700
#
 
701
# Additionally, we introduced quotes that we not there before, which is
 
702
# OK in most cases, but could change the semantics of the file.
 
703
#
 
704
# Cruel dilemma: we do want the auto-quoting definition of `NEW' when
 
705
# evaluating `OLD', but we don't when we evaluate the second `NEW'.
 
706
# Back to namespaces?
 
707
#
 
708
# No.
 
709
#
 
710
#
 
711
# # Second step: replacement
 
712
# # ------------------------
 
713
#
 
714
# No, as announced above, we will work in two steps: in a first step we
 
715
# compute the updated values, and in a second step we replace them.  Our
 
716
# goal is something like this:
 
717
#
 
718
#     divert(-1)dnl
 
719
#     changequote([, ])
 
720
#     define([OLD], [NEW([1, 2], [3])changequote()])
 
721
#     undefine([dnl])
 
722
#     undefine([m4_eval])
 
723
#     # Some more undefines...
 
724
#     changequote()
 
725
#     divert(0)dnl
 
726
#     dnl The Unbelievable Truth
 
727
#     changequote([, ])OLD(1, 2)
 
728
#     NEW([0, 0],
 
729
#         0)
 
730
#
 
731
# i.e., the new value of `OLD' is precomputed using the auto-quoting
 
732
# definition of `NEW' and the m4 builtins.  We'll see how afterwards,
 
733
# let's finish with the replacement.
 
734
#
 
735
# Of course the solution above is wrong: if there were other calls to
 
736
# `OLD' with different values, we would smash them to the same value.
 
737
# But it is quite easy to generalize the scheme above:
 
738
#
 
739
#     divert(-1)dnl
 
740
#     changequote([, ])
 
741
#     define([OLD([1],[2])], [NEW([1, 2], [3])])
 
742
#     define([OLD], [defn([OLD($@)])changequote()])
 
743
#     undefine([dnl])
 
744
#     undefine([m4_eval])
 
745
#     # Some more undefines...
 
746
#     changequote()
 
747
#     divert(0)dnl
 
748
#     dnl The Unbelievable Truth
 
749
#     changequote([, ])OLD(1, 2)
 
750
#     NEW([0, 0],
 
751
#         0)
 
752
#
 
753
# i.e., for each call to obsolete macros, we build an array `call =>
 
754
# value', and use a macro to dispatch these values.  This results in:
 
755
#
 
756
#     dnl The Unbelievable Truth
 
757
#     NEW([1, 2], [3])
 
758
#     NEW([0, 0],
 
759
#         0)
 
760
#
 
761
# In French, we say `Youpi !', which you might roughly translate as
 
762
# `yipeee!'.
 
763
#
 
764
#
 
765
# # First step: computation
 
766
# # -----------------------
 
767
#
 
768
# Let's study the anatomy of the file, and name its sections:
 
769
#
 
770
# prologue
 
771
#     divert(-1)dnl
 
772
#     changequote([, ])
 
773
# values
 
774
#     define([OLD([1],[2])], [NEW([1, 2], [3])])
 
775
# dispatcher
 
776
#     define([OLD], [defn([OLD($@)])changequote()])
 
777
# disabler
 
778
#     undefine([dnl])
 
779
#     undefine([m4_eval])
 
780
#     # Some more undefines...
 
781
#     changequote()
 
782
#     divert(0)dnl
 
783
# input
 
784
#     dnl The Unbelievable Truth
 
785
#     changequote([, ])OLD(1, 2)
 
786
#     NEW([0, 0],
 
787
#         0)
 
788
#
 
789
#
 
790
# # Computing the `values' section
 
791
# # ..............................
 
792
#
 
793
# First we need to get the list of all the AU macro uses.  To this end,
 
794
# first get the list of all the AU macros names by tracing `AU_DEFUN' in
 
795
# the initialization of autoconf.  This list is computed in the file
 
796
# `au.txt' below.
 
797
#
 
798
# Then use this list to trace all the AU macro uses in the input.  The
 
799
# goal is obtain in the case of our example:
 
800
#
 
801
#     [define([OLD([1],[2])],]@<<@OLD([1],[2])@>>@[)]
 
802
#
 
803
# This is the file `values.in' below.
 
804
#
 
805
# We want to evaluate this with only the builtins (in fact m4sugar), the
 
806
# auto-quoting definitions of the new macros (`new.m4'), and the
 
807
# definition of the old macros (`old.m4').  Computing these last two
 
808
# files is easy: it's just a matter of using the right `--trace' option.
 
809
#
 
810
# So the content of `values.in' is:
 
811
#
 
812
#     include($autoconf_dir/m4sugar.m4)
 
813
#     m4_include(new.m4)
 
814
#     m4_include(old.m4)
 
815
#     divert(0)dnl
 
816
#     [define([OLD([1],[2])],]@<<@OLD([1],[2])@>>@[)]
 
817
#
 
818
# We run m4 on it, which yields:
 
819
#
 
820
#     define([OLD([1],[2])],@<<@NEW([1, 2], [3])@>>@)
 
821
#
 
822
# Transform `@<<@' and `@>>@' into quotes and we get
 
823
#
 
824
#     define([OLD([1],[2])],[NEW([1, 2], [3])])
 
825
#
 
826
# This is `values.m4'.
 
827
#
 
828
#
 
829
# # Computing the `dispatcher' section
 
830
# # ..................................
 
831
#
 
832
# The `prologue', and the `disabler' are simple and need no commenting.
 
833
#
 
834
# To compute the `dispatcher' (`dispatch.m4'), again, it is a simple
 
835
# matter of using the right `--trace'.
 
836
#
 
837
# Finally, the input is not exactly the input file, rather it is the
 
838
# input file with the added `changequote'.  To this end, we build
 
839
# `quote.sed'.
 
840
#
 
841
#
 
842
# # Putting it all together
 
843
# # .......................
 
844
#
 
845
# We build the file `input.m4' which contains:
 
846
#
 
847
#     divert(-1)dnl
 
848
#     changequote([, ])
 
849
#     include(values.m4)
 
850
#     include(dispatch.m4)
 
851
#     undefine([dnl])
 
852
#     undefine([eval])
 
853
#     # Some more undefines...
 
854
#     changequote()
 
855
#     divert(0)dnl
 
856
#     dnl The Unbelievable Truth
 
857
#     changequote([, ])OLD(1, 2)
 
858
#     NEW([0, 0],
 
859
#         0)
 
860
#
 
861
# And we just run m4 on it.  Et voila`, Monsieur !  Mais oui, mais oui.
 
862
#
 
863
# Well, there are a few additional technicalities.  For instance, we
 
864
# rely on `changequote', `ifelse' and `defn', but we don't want to
 
865
# interpret the changequotes of the user, so we simply use another name:
 
866
# `_au_changequote' etc.
 
867
#
 
868
#
 
869
# # Failure of the fourth approach
 
870
# # ------------------------------
 
871
#
 
872
# This approach is heavily based on traces, but then there is an obvious
 
873
# problem: non expanded code will never be seen/ In particular, the body
 
874
# of a `define' definition is not seen, so on the input
 
875
#
 
876
#         define([idem], [OLD(0, [$1])])
 
877
#
 
878
# autoupdate would never see the `OLD', and wouldn't have updated it.
 
879
# Worse yet, if `idem(0)' was used later, then autoupdate sees that
 
880
# `OLD' is used, computes the result for `OLD(0, 0)' and sets up a
 
881
# dispatcher for `OLD'.  Since there was no computed value for `OLD(0,
 
882
# [$1])', the dispatcher would have replaced with... nothinhg, leading
 
883
# to
 
884
#
 
885
#         define([idem], [])
 
886
#
 
887
# With some more thinking, you see that the two step approach is wrong,
 
888
# the namespace approach was much saner.
 
889
#
 
890
# But you learned a lot, in particular you realized that using traces
 
891
# can make it possible to simulate namespaces!
 
892
#
 
893
#
 
894
#
 
895
# # The fifth implementation: m4 namespaces by files
 
896
# # ================================================
 
897
#
 
898
# The fourth implementation demonstrated something unsurprising: you
 
899
# cannot precompute, i.e., the namespace approach was the right one.
 
900
# Still, we no longer want them, they're too expensive.  Let's have a
 
901
# look at the way it worked.
 
902
#
 
903
# When updating
 
904
#
 
905
#     dnl The Unbelievable Truth
 
906
#     OLD(1, 2)
 
907
#     NEW([0, 0], [0])
 
908
#
 
909
# you evaluate `input.m4':
 
910
#
 
911
#     divert(-1)
 
912
#     changequote([, ])
 
913
#     define([OLD],
 
914
#     [m4_enable()NEW([$1, $2], m4_eval([$1 + $2]))m4_disable()])
 
915
#     ...
 
916
#     m4_disable()
 
917
#     dnl The Unbelievable Truth
 
918
#     OLD(1, 2)
 
919
#     NEW([0, 0], [0])
 
920
#
 
921
# where `m4_disable' undefines the m4 and m4sugar, and disables the quotes
 
922
# and comments:
 
923
#
 
924
#     define([m4_disable],
 
925
#     [undefine([__file__])
 
926
#     ...
 
927
#     changecom(#)
 
928
#     changequote()])
 
929
#
 
930
# `m4_enable' does the converse: reestablish quotes and comments
 
931
# --easy--, reestablish m4sugar --easy: just load `m4sugar.m4' again-- and
 
932
# reenable the builtins.  This later task requires that you first save
 
933
# the builtins.  And BTW, the definition above of `m4_disable' cannot
 
934
# work: you undefined `changequote' before using it!  So you need to use
 
935
# your privates copies of the builtins.  Let's introduce three files for
 
936
# this:
 
937
#
 
938
#  `m4save.m4'
 
939
#    moves the m4 builtins into the `_au_' pseudo namespace
 
940
#  `unm4.m4'
 
941
#    undefines the builtins
 
942
#  `m4.m4'
 
943
#    restores them
 
944
#
 
945
# So `input.m4' is:
 
946
#
 
947
#     divert(-1)
 
948
#     changequote([, ])
 
949
#
 
950
#     include([m4save.m4])
 
951
#
 
952
#     # Import AU.
 
953
#     define([OLD],
 
954
#     [m4_enable()NEW([$1, $2], m4_eval([$1 + $2]))m4_disable()])
 
955
#
 
956
#     define([_au_enable],
 
957
#     [_au_changecom([#])
 
958
#     _au_include([m4.m4])
 
959
#     _au_include(m4sugar.m4)])
 
960
#
 
961
#     define([_au_disable],
 
962
#     [# Disable m4sugar.
 
963
#     # Disable the m4 builtins.
 
964
#     _au_include([unm4.m4])
 
965
#     # 1. Disable special characters.
 
966
#     _au_changequote()
 
967
#     _au_changecom()])
 
968
#
 
969
#     m4_disable()
 
970
#     dnl The Unbelievable Truth
 
971
#     OLD(1, 2)
 
972
#     NEW([0, 0], [0])
 
973
#
 
974
# Based on what we learned in the fourth implementation we know that we
 
975
# have to enable the quotes *before* any AU macro, and we know we need
 
976
# to build autoquoting versions of the AC macros.  But the autoquoting
 
977
# AC definitions must be disabled in the rest of the file, and enabled
 
978
# inside AU macros.
 
979
#
 
980
# Using `autoconf --trace' it is easy to build the files
 
981
#
 
982
#   `ac.m4'
 
983
#     define the autoquoting AC fake macros
 
984
#   `disable.m4'
 
985
#     undefine the m4sugar and AC autoquoting macros.
 
986
#   `au.m4'
 
987
#     definitions of the AU macros (such as `OLD' above).
 
988
#
 
989
# Now, `input.m4' is:
 
990
#
 
991
#     divert(-1)
 
992
#     changequote([, ])
 
993
#
 
994
#     include([m4save.m4])
 
995
#     # Import AU.
 
996
#     include([au.m4])
 
997
#
 
998
#     define([_au_enable],
 
999
#     [_au_changecom([#])
 
1000
#     _au_include([m4.m4])
 
1001
#     _au_include(m4sugar.m4)
 
1002
#     _au_include(ac.m4)])
 
1003
#
 
1004
#     define([_au_disable],
 
1005
#     [_au_include([disable.m4])
 
1006
#     _au_include([unm4.m4])
 
1007
#     # 1. Disable special characters.
 
1008
#     _au_changequote()
 
1009
#     _au_changecom()])
 
1010
#
 
1011
#     m4_disable()
 
1012
#     dnl The Unbelievable Truth
 
1013
#     _au_changequote([, ])OLD(1, 2)
 
1014
#     NEW([0, 0], [0])
 
1015
#
 
1016
# Finally, version V is ready.
 
1017
#
 
1018
# Well... almost.
 
1019
#
 
1020
# There is a slight problem that remains: if an AU macro OUTTER includes
 
1021
# an AU macro INNER, then _au_enable will be run when entering OUTTER
 
1022
# and when entering INNER (not good, but not too bad yet).  But when
 
1023
# getting out of INNER, _au_disable will disable everything while we
 
1024
# were still in OUTTER.  Badaboom.
 
1025
#
 
1026
# Therefore _au_enable and _au_disable have to be written to work by
 
1027
# pairs: each _au_enable pushdef's _au_enabled, and each _au_disable
 
1028
# popdef's _au_enabled.  And of course _au_enable and _au_disable are
 
1029
# effective when _au_enabled is *not* defined.
 
1030
#
 
1031
# Finally, version V' is ready.  And there is much rejoicing.  (And I
 
1032
# have free time again.  I think.  Yeah, right.)