-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Gary V. Vaughan on 6/23/2006 4:43 AM:
>>
>>      * src/builtin.c: Unify error message style.
> 
> Don't forget to update the error messages in the tests to match,
> or we will get spurious failures.

That, and I didn't complete the job.  Sorry for mixing too many patches
into one commit previously.  This is three separate commits.

patch 64:
2006-06-23  Eric Blake  <[EMAIL PROTECTED]>

        * src/builtin.c (builtin_tab): Make format and indir blind.
        (substitute): Prefer "Warning:" vs. "ERROR:" in warnings.
        * NEWS: Mention the change to builtins.

patch 65:
2006-06-23  Eric Blake  <[EMAIL PROTECTED]>

        Make error messages more consistent with GNU coding standards -
        start with lower case, and don't end sentence with punctuation.
        * src/debug.c (trace_pre): Update message wording.
        * src/eval.c (evaluate, cmp_term, shift_term, mult_term):
        Likewise.
        * src/freeze.c (produce_frozen_state, issue_expect_message),
        (reload_frozen_state): Likewise.
        * src/input.c (push_string_init, pop_init, init_macro_token),
        (peek_input, next_char_1, set_word_regexp, next_token): Likewise.
        * src/m4.c (stackovf_handler, main): Likewise.
        * src/macro.c (expand_token, expand_argument, call_macro),
        (expand_macro): Likewise.
        * src/output.c (make_room_for, output_text, insert_file),
        (freeze_diversions): Likewise.
        * src/symtab.c (symtab_init, lookup_symbol): Likewise.

patch 66:
2006-06-23  Eric Blake  <[EMAIL PROTECTED]>

        * doc/m4.texinfo: Quoting cleanup throughout - follow
        autoconf-recommended style of one level of quote per parenthesis
        in the normal case.  Adjust error messages to match GNU coding
        standards (and to allow 'make check' to pass again).
        (Quoted strings, Inhibiting Invocation): Turn more examples into
        tests.
        (Comments): Resolve FIXME by adding example.
        (Define): Add example about underquoting.
        (Defn): Add example about use of $0.
        (Indir, Format): Resolve FIXME done in last commit.
        (Ifelse): Add example about creating blind macro.
        (Debugging): Fix grammar.
        (Dnl): Add example about dnl with arguments.
        (M4wrap): Be explicit that LIFO order is non compliant, and will
        change in m4 2.0.
        (Undivert): Resolve FIXME by adding example.
        (Frozen files): Document that m4wrap and sysval will not work
        consistently until m4 2.0.
        (Incompatibilities): Document another POSIX compliance bug, this
        time with changequote.  Document a traditional incompatibility
        with partial input spanning file boundaries.

- --
Life is short - so eat dessert first!

Eric Blake             [EMAIL PROTECTED]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEm+p084KuGfSFAYARAmqpAKDOMGfFsc2La37Xb0ySRObHOdE3UQCgoHoP
Hly5SGkZfAneqBuqcTZtugQ=
=KlQK
-----END PGP SIGNATURE-----
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.24
diff -u -p -r1.1.1.1.2.24 NEWS
--- NEWS        22 Jun 2006 23:17:21 -0000      1.1.1.1.2.24
+++ NEWS        23 Jun 2006 12:56:34 -0000
@@ -15,6 +15,7 @@ Version 1.4.5 - ?? 2006, by ???  (CVS ve
   warning is deferred until an attempt is made to actually use the builtin.
   This allows downgrading from beta m4-1.4o to m4-1.4.5 without breaking
   autoconf.
+* The format and indir macros are now recognized only with arguments.
 
 Version 1.4.4b - 17 June 2006, by Eric Blake  (CVS version 1.4.4a)
 
Index: src/builtin.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/builtin.c,v
retrieving revision 1.1.1.1.2.13
diff -u -p -r1.1.1.1.2.13 builtin.c
--- src/builtin.c       22 Jun 2006 23:17:22 -0000      1.1.1.1.2.13
+++ src/builtin.c       23 Jun 2006 12:56:35 -0000
@@ -111,13 +111,13 @@ builtin_tab[] =
   { "errprint",                FALSE,  FALSE,  FALSE,  m4_errprint },
   { "esyscmd",         TRUE,   FALSE,  TRUE,   m4_esyscmd },
   { "eval",            FALSE,  FALSE,  TRUE,   m4_eval },
-  { "format",          TRUE,   FALSE,  FALSE,  m4_format },
+  { "format",          TRUE,   FALSE,  TRUE,   m4_format },
   { "ifdef",           FALSE,  FALSE,  TRUE,   m4_ifdef },
   { "ifelse",          FALSE,  FALSE,  TRUE,   m4_ifelse },
   { "include",         FALSE,  FALSE,  TRUE,   m4_include },
   { "incr",            FALSE,  FALSE,  TRUE,   m4_incr },
   { "index",           FALSE,  FALSE,  TRUE,   m4_index },
-  { "indir",           TRUE,   FALSE,  FALSE,  m4_indir },
+  { "indir",           TRUE,   FALSE,  TRUE,   m4_indir },
   { "len",             FALSE,  FALSE,  TRUE,   m4_len },
   { "m4exit",          FALSE,  FALSE,  FALSE,  m4_m4exit },
   { "m4wrap",          FALSE,  FALSE,  FALSE,  m4_m4wrap },
@@ -1529,7 +1529,7 @@ substitute (struct obstack *obs, const c
          if (!substitute_warned)
            {
              M4ERROR ((warning_status, 0, "\
-WARNING: \\0 will disappear, use \\& instead in replacements"));
+Warning: \\0 will disappear, use \\& instead in replacements"));
              substitute_warned = 1;
            }
          /* Fall through.  */
Index: src/debug.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/debug.c,v
retrieving revision 1.1.1.1.2.2
diff -u -p -p -r1.1.1.1.2.2 debug.c
--- src/debug.c 1 May 2005 11:54:12 -0000       1.1.1.1.2.2
+++ src/debug.c 23 Jun 2006 12:59:23 -0000
@@ -1,6 +1,7 @@
 /* GNU m4 -- A simple macro processor
 
-   Copyright (C) 1991, 1992, 1993, 1994, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1992, 1993, 1994, 2004, 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
@@ -379,7 +380,7 @@ trace_pre (const char *name, int id, int
              if (bp == NULL)
                {
                  M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"));
+INTERNAL ERROR: builtin not found in builtin table! (trace_pre ())"));
                  abort ();
                }
              trace_format ("<%s>", bp->name);
@@ -387,7 +388,7 @@ INTERNAL ERROR: Builtin not found in bui
 
            default:
              M4ERROR ((warning_status, 0,
-                       "INTERNAL ERROR: Bad token data type (trace_pre ())"));
+                       "INTERNAL ERROR: bad token data type (trace_pre ())"));
              abort ();
            }
 
Index: src/eval.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/eval.c,v
retrieving revision 1.1.1.1.2.2
diff -u -p -p -r1.1.1.1.2.2 eval.c
--- src/eval.c  15 Jun 2006 21:51:37 -0000      1.1.1.1.2.2
+++ src/eval.c  23 Jun 2006 12:59:23 -0000
@@ -277,38 +277,38 @@ evaluate (const char *expr, eval_t *val)
 
     case MISSING_RIGHT:
       M4ERROR ((warning_status, 0,
-               "Bad expression in eval (missing right parenthesis): %s",
+               "bad expression in eval (missing right parenthesis): %s",
                expr));
       break;
 
     case SYNTAX_ERROR:
       M4ERROR ((warning_status, 0,
-               "Bad expression in eval: %s", expr));
+               "bad expression in eval: %s", expr));
       break;
 
     case UNKNOWN_INPUT:
       M4ERROR ((warning_status, 0,
-               "Bad expression in eval (bad input): %s", expr));
+               "bad expression in eval (bad input): %s", expr));
       break;
 
     case EXCESS_INPUT:
       M4ERROR ((warning_status, 0,
-               "Bad expression in eval (excess input): %s", expr));
+               "bad expression in eval (excess input): %s", expr));
       break;
 
     case DIVIDE_ZERO:
       M4ERROR ((warning_status, 0,
-               "Divide by zero in eval: %s", expr));
+               "divide by zero in eval: %s", expr));
       break;
 
     case MODULO_ZERO:
       M4ERROR ((warning_status, 0,
-               "Modulo by zero in eval: %s", expr));
+               "modulo by zero in eval: %s", expr));
       break;
 
     default:
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Bad error code in evaluate ()"));
+               "INTERNAL ERROR: bad error code in evaluate ()"));
       abort ();
     }
 
@@ -548,7 +548,7 @@ cmp_term (eval_token et, eval_t *v1)
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Bad comparison operator in cmp_term ()"));
+                   "INTERNAL ERROR: bad comparison operator in cmp_term ()"));
          abort ();
        }
     }
@@ -591,7 +591,7 @@ shift_term (eval_token et, eval_t *v1)
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Bad shift operator in shift_term ()"));
+                   "INTERNAL ERROR: bad shift operator in shift_term ()"));
          abort ();
        }
     }
@@ -674,7 +674,7 @@ mult_term (eval_token et, eval_t *v1)
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Bad operator in mult_term ()"));
+                   "INTERNAL ERROR: bad operator in mult_term ()"));
          abort ();
        }
     }
Index: src/freeze.c
===================================================================
RCS file: /sources/m4/m4/src/freeze.c,v
retrieving revision 1.1.1.1.2.6
diff -u -p -p -r1.1.1.1.2.6 freeze.c
--- src/freeze.c        22 Jun 2006 23:17:22 -0000      1.1.1.1.2.6
+++ src/freeze.c        23 Jun 2006 12:59:23 -0000
@@ -122,7 +122,7 @@ produce_frozen_state (const char *name)
              if (bp == NULL)
                {
                  M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: Builtin not found in builtin table!"));
+INTERNAL ERROR: builtin not found in builtin table!"));
                  abort ();
                }
              fprintf (file, "F%d,%d\n",
@@ -135,7 +135,7 @@ INTERNAL ERROR: Builtin not found in bui
 
            default:
              M4ERROR ((warning_status, 0, "\
-INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"));
+INTERNAL ERROR: bad token data type in freeze_one_symbol ()"));
              abort ();
              break;
            }
@@ -165,9 +165,9 @@ static void
 issue_expect_message (int expected)
 {
   if (expected == '\n')
-    M4ERROR ((EXIT_FAILURE, 0, "Expecting line feed in frozen file"));
+    M4ERROR ((EXIT_FAILURE, 0, "expecting line feed in frozen file"));
   else
-    M4ERROR ((EXIT_FAILURE, 0, "Expecting character `%c' in frozen file",
+    M4ERROR ((EXIT_FAILURE, 0, "expecting character `%c' in frozen file",
              expected));
 }
 
@@ -229,7 +229,7 @@ reload_frozen_state (const char *name)
 
   file = path_search (name);
   if (file == NULL)
-    M4ERROR ((EXIT_FAILURE, errno, "Cannot open %s", name));
+    M4ERROR ((EXIT_FAILURE, errno, "cannot open %s", name));
 
   allocated[0] = 100;
   string[0] = xmalloc ((size_t) allocated[0]);
@@ -250,7 +250,7 @@ reload_frozen_state (const char *name)
       switch (character)
         {
         default:
-          M4ERROR ((EXIT_FAILURE, 0, "Ill-formed frozen file"));
+          M4ERROR ((EXIT_FAILURE, 0, "ill-formed frozen file"));
 
         case 'C':
         case 'D':
@@ -289,7 +289,7 @@ reload_frozen_state (const char *name)
 
               if (number[0] > 0)
                 if (!fread (string[0], (size_t) number[0], 1, file))
-                  M4ERROR ((EXIT_FAILURE, 0, "Premature end of frozen file"));
+                  M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
 
               string[0][number[0]] = '\0';
             }
@@ -305,7 +305,7 @@ reload_frozen_state (const char *name)
 
           if (number[1] > 0)
             if (!fread (string[1], (size_t) number[1], 1, file))
-              M4ERROR ((EXIT_FAILURE, 0, "Premature end of frozen file"));
+              M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
 
           string[1][number[1]] = '\0';
           GET_CHARACTER;
Index: src/input.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/input.c,v
retrieving revision 1.1.1.1.2.7
diff -u -p -p -r1.1.1.1.2.7 input.c
--- src/input.c 22 Jun 2006 17:43:05 -0000      1.1.1.1.2.7
+++ src/input.c 23 Jun 2006 12:59:23 -0000
@@ -224,7 +224,7 @@ push_string_init (void)
   if (next != NULL)
     {
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Recursive push_string!"));
+               "INTERNAL ERROR: recursive push_string!"));
       abort ();
     }
 
@@ -318,7 +318,7 @@ pop_input (void)
 
     default:
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Input stack botch in pop_input ()"));
+               "INTERNAL ERROR: input stack botch in pop_input ()"));
       abort ();
     }
   obstack_free (current_input, isp);
@@ -367,7 +367,7 @@ init_macro_token (token_data *td)
   if (isp->type != INPUT_MACRO)
     {
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Bad call to init_macro_token ()"));
+               "INTERNAL ERROR: bad call to init_macro_token ()"));
       abort ();
     }
 
@@ -415,7 +415,7 @@ peek_input (void)
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Input stack botch in peek_input ()"));
+                   "INTERNAL ERROR: input stack botch in peek_input ()"));
          abort ();
        }
       /* End of input source --- pop one level.  */
@@ -479,7 +479,7 @@ next_char_1 (void)
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Input stack botch in next_char ()"));
+                   "INTERNAL ERROR: input stack botch in next_char ()"));
          abort ();
        }
 
@@ -663,7 +663,7 @@ set_word_regexp (const char *regexp)
   if (msg != NULL)
     {
       M4ERROR ((warning_status, 0,
-               "Bad regular expression `%s': %s", regexp, msg));
+               "bad regular expression `%s': %s", regexp, msg));
       return;
     }
 
@@ -674,7 +674,7 @@ set_word_regexp (const char *regexp)
   if (msg != NULL)
     {
       M4ERROR ((EXIT_FAILURE, 0,
-               "Internal error: Expression recompilation `%s': %s",
+               "INTERNAL ERROR: expression recompilation `%s': %s",
                regexp, msg));
     }
 
@@ -816,7 +816,7 @@ next_token (token_data *td)
          ch = next_char ();
          if (ch == CHAR_EOF)
            M4ERROR ((EXIT_FAILURE, 0,
-                     "ERROR: EOF in string"));
+                     "ERROR: end of file in string"));
 
          if (MATCH (ch, rquote.string))
            {
Index: src/m4.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/m4.c,v
retrieving revision 1.1.1.1.2.11
diff -u -p -p -r1.1.1.1.2.11 m4.c
--- src/m4.c    22 Jun 2006 03:29:36 -0000      1.1.1.1.2.11
+++ src/m4.c    23 Jun 2006 12:59:23 -0000
@@ -110,7 +110,7 @@ static void
 stackovf_handler (void)
 {
   M4ERROR ((EXIT_FAILURE, 0,
-           "ERROR: Stack overflow.  (Infinite define recursion?)"));
+           "ERROR: stack overflow.  (Infinite define recursion?)"));
 }
 
 #endif /* USE_STACKOV */
@@ -445,7 +445,7 @@ warranty; not even for MERCHANTABILITY o
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Bad code in deferred arguments"));
+                   "INTERNAL ERROR: bad code in deferred arguments"));
          abort ();
        }
 
Index: src/macro.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/macro.c,v
retrieving revision 1.1.1.1.2.4
diff -u -p -p -r1.1.1.1.2.4 macro.c
--- src/macro.c 15 Jun 2006 21:51:37 -0000      1.1.1.1.2.4
+++ src/macro.c 23 Jun 2006 12:59:23 -0000
@@ -92,7 +92,7 @@ expand_token (struct obstack *obs, token
 
     default:
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Bad token type in expand_token ()"));
+               "INTERNAL ERROR: bad token type in expand_token ()"));
       abort ();
     }
 }
@@ -158,7 +158,7 @@ expand_argument (struct obstack *obs, to
 
        case TOKEN_EOF:
          M4ERROR ((EXIT_FAILURE, 0,
-                   "ERROR: EOF in argument list"));
+                   "ERROR: end of file in argument list"));
          break;
 
        case TOKEN_WORD:
@@ -176,7 +176,7 @@ expand_argument (struct obstack *obs, to
 
        default:
          M4ERROR ((warning_status, 0,
-                   "INTERNAL ERROR: Bad token type in expand_argument ()"));
+                   "INTERNAL ERROR: bad token type in expand_argument ()"));
          abort ();
        }
 
@@ -252,7 +252,7 @@ call_macro (symbol *sym, int argc, token
 
     default:
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Bad symbol type in call_macro ()"));
+               "INTERNAL ERROR: bad symbol type in call_macro ()"));
       abort ();
     }
 }
@@ -283,7 +283,7 @@ expand_macro (symbol *sym)
   expansion_level++;
   if (expansion_level > nesting_limit)
     M4ERROR ((EXIT_FAILURE, 0,
-             "ERROR: Recursion limit of %d exceeded, use -L<N> to change it",
+             "ERROR: recursion limit of %d exceeded, use -L<N> to change it",
              nesting_limit));
 
   macro_call_id++;
Index: src/output.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/output.c,v
retrieving revision 1.1.1.1.2.5
diff -u -p -p -r1.1.1.1.2.5 output.c
--- src/output.c        22 Jun 2006 14:55:48 -0000      1.1.1.1.2.5
+++ src/output.c        23 Jun 2006 12:59:23 -0000
@@ -182,7 +182,7 @@ make_room_for (int length)
       selected_diversion->file = tmpfile ();
       if (selected_diversion->file == NULL)
        M4ERROR ((EXIT_FAILURE, errno,
-                 "ERROR: Cannot create temporary file for diversion"));
+                 "ERROR: cannot create temporary file for diversion"));
 
       if (selected_diversion->used > 0)
        {
@@ -192,7 +192,7 @@ make_room_for (int length)
                          selected_diversion->file);
          if (count != 1)
            M4ERROR ((EXIT_FAILURE, errno,
-                     "ERROR: Cannot flush diversion to temporary file"));
+                     "ERROR: cannot flush diversion to temporary file"));
        }
 
       /* Reclaim the buffer space for other diversions.  */
@@ -276,7 +276,7 @@ output_text (const char *text, int lengt
     {
       count = fwrite (text, length, 1, output_file);
       if (count != 1)
-       M4ERROR ((EXIT_FAILURE, errno, "ERROR: Copying inserted file"));
+       M4ERROR ((EXIT_FAILURE, errno, "ERROR: copying inserted file"));
     }
   else
     {
@@ -458,7 +458,7 @@ insert_file (FILE *file)
     {
       length = fread (buffer, 1, COPY_BUFFER_SIZE, file);
       if (ferror (file))
-       M4ERROR ((EXIT_FAILURE, errno, "ERROR: Reading inserted file"));
+       M4ERROR ((EXIT_FAILURE, errno, "ERROR: reading inserted file"));
       if (length == 0)
        break;
       output_text (buffer, length);
@@ -559,7 +559,7 @@ freeze_diversions (FILE *file)
            {
              fflush (diversion->file);
              if (fstat (fileno (diversion->file), &file_stat) < 0)
-               M4ERROR ((EXIT_FAILURE, errno, "Cannot stat diversion"));
+               M4ERROR ((EXIT_FAILURE, errno, "cannot stat diversion"));
              fprintf (file, "D%d,%d", divnum, (int) file_stat.st_size);
            }
          else
Index: src/symtab.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/symtab.c,v
retrieving revision 1.1.1.1.2.10
diff -u -p -p -r1.1.1.1.2.10 symtab.c
--- src/symtab.c        22 Jun 2006 17:43:05 -0000      1.1.1.1.2.10
+++ src/symtab.c        23 Jun 2006 12:59:23 -0000
@@ -111,7 +111,7 @@ symtab_init (void)
     int e = atexit(show_profile);
     if (e != 0)
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Unable to show symtab profile"));
+               "INTERNAL ERROR: unable to show symtab profile"));
   }
 #endif /* DEBUG_SYM */
 }
@@ -309,7 +309,7 @@ lookup_symbol (const char *name, symbol_
 
     default:
       M4ERROR ((warning_status, 0,
-               "INTERNAL ERROR: Invalid mode to symbol_lookup ()"));
+               "INTERNAL ERROR: invalid mode to symbol_lookup ()"));
       abort ();
     }
 }
Index: ChangeLog
===================================================================
RCS file: /sources/m4/m4/ChangeLog,v
retrieving revision 1.1.1.1.2.84
diff -u -p -r1.1.1.1.2.84 ChangeLog
--- ChangeLog   23 Jun 2006 13:06:10 -0000      1.1.1.1.2.84
+++ ChangeLog   23 Jun 2006 13:18:44 -0000
@@ -1,5 +1,27 @@
 2006-06-23  Eric Blake  <[EMAIL PROTECTED]>
 
+       * doc/m4.texinfo: Quoting cleanup throughout - follow
+       autoconf-recommended style of one level of quote per parenthesis
+       in the normal case.  Adjust error messages to match GNU coding
+       standards (and to allow 'make check' to pass again).
+       (Quoted strings, Inhibiting Invocation): Turn more examples into
+       tests.
+       (Comments): Resolve FIXME by adding example.
+       (Define): Add example about underquoting.
+       (Defn): Add example about use of $0.
+       (Indir, Format): Resolve FIXME done in last commit.
+       (Ifelse): Add example about creating blind macro.
+       (Debugging): Fix grammar.
+       (Dnl): Add example about dnl with arguments.
+       (M4wrap): Be explicit that LIFO order is non compliant, and will
+       change in m4 2.0.
+       (Undivert): Resolve FIXME by adding example.
+       (Frozen files): Document that m4wrap and sysval will not work
+       consistently until m4 2.0.
+       (Incompatibilities): Document another POSIX compliance bug, this
+       time with changequote.  Document a traditional incompatibility
+       with partial input spanning file boundaries.
+
        Make error messages more consistent with GNU coding standards -
        start with lower case, and don't end sentence with punctuation.
        * src/debug.c (trace_pre): Update message wording.
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.23
diff -u -p -r1.1.1.1.2.23 m4.texinfo
--- doc/m4.texinfo      22 Jun 2006 23:17:22 -0000      1.1.1.1.2.23
+++ doc/m4.texinfo      23 Jun 2006 13:18:44 -0000
@@ -651,20 +651,16 @@ level of quotes stripped off.  Thus
 @comment ignore
 @example
 `'
[EMAIL PROTECTED]
 @end example
 
-is the empty string, and
-
[EMAIL PROTECTED] ignore
[EMAIL PROTECTED]
[EMAIL PROTECTED]'@w{}'
[EMAIL PROTECTED] example
-
-is the string
[EMAIL PROTECTED]
+is the empty string, and double-quoting turns into single-quoting.
 
 @comment ignore
 @example
-`quoted'
+``quoted''
[EMAIL PROTECTED]'
 @end example
 
 The quote characters can be changed at any time, using the builtin macro
@@ -689,12 +685,17 @@ Comments cannot be nested, so the first 
 the comment.  The commenting effect of the begin comment character
 can be inhibited by quoting it.
 
[EMAIL PROTECTED]
+`quoted text' # `commented text'
[EMAIL PROTECTED] text # `commented text'
+`quoting inhibits' `#' `comments'
[EMAIL PROTECTED] inhibits # comments
[EMAIL PROTECTED] example
+
 The comment delimiters can be changed to any string at any time, using
 the builtin macro @code{changecom}.  @xref{Changecom}, for more
 information.
 
[EMAIL PROTECTED] FIXME: more examples would be useful here --ADR
-
 @node Macros, Definitions, Syntax, Top
 @chapter How to invoke macros
 
@@ -792,9 +793,13 @@ For example:
 @comment ignore
 @example
 `divert'
[EMAIL PROTECTED]
 `d'ivert
[EMAIL PROTECTED]
 di`ver't
[EMAIL PROTECTED]
 div`'ert
[EMAIL PROTECTED]
 @end example
 
 @noindent
@@ -803,7 +808,9 @@ all yield the string @samp{divert}.  Whi
 @comment ignore
 @example
 `'divert
[EMAIL PROTECTED]
 divert`'
[EMAIL PROTECTED]
 @end example
 
 @noindent
@@ -811,12 +818,12 @@ the @code{divert} builtin macro will be 
 
 The output of macro evaluations is always rescanned.  The following
 example would yield the string @samp{de}, exactly as if @code{m4}
-has been given @[EMAIL PROTECTED](abcde, 3, 2)}} as input:
+has been given @[EMAIL PROTECTED](`abcde', `3', `2')}} as input:
 
 @example
 define(`x', `substr(ab')
 @result{}
-define(`y', `cde, 3, 2)')
+define(`y', `cde, `3', `2')')
 @result{}
 x`'y
 @result{}de
@@ -824,30 +831,32 @@ x`'y
 
 Unquoted strings on either side of a quoted string are subject to
 being recognized as macro names.  In the following example, quoting the
-empty string allows for the @code{dnl} macro to be recognized as such:
+empty string allows for the second @code{macro} to be recognized as such:
 
[EMAIL PROTECTED] ignore
 @example
-define(`macro', `di$1')
-macro(v)`'dnl
+define(`macro', `m')
[EMAIL PROTECTED]
+macro(`m')macro
[EMAIL PROTECTED]
+macro(`m')`'macro
[EMAIL PROTECTED]
 @end example
 
[EMAIL PROTECTED]
-Without the quotes, this would rather yield the string @samp{divdnl}
-followed by an end of line.
-
 Quoting may prevent recognizing as a macro name the concatenation of a
 macro expansion with the surrounding characters.  In this example:
 
[EMAIL PROTECTED] ignore
 @example
 define(`macro', `di$1')
-macro(v)`ert'
[EMAIL PROTECTED]
+macro(`v')`ert'
[EMAIL PROTECTED]
+macro(`v')ert
[EMAIL PROTECTED]
 @end example
 
 @noindent
-the input will produce the string @samp{divert}.  If the quote was
-removed, the @code{divert} builtin would be called instead.
+the input will produce the string @samp{divert}.  When the quotes were
+removed, the @code{divert} builtin was called instead.
 
 @node Macro Arguments, Quoting Arguments, Inhibiting Invocation, Macros
 @section Macro arguments
@@ -921,9 +930,13 @@ example with the parentheses, the `right
 foo(`() (() (')
 @end example
 
-It is, however, in certain cases necessary to leave out quotes for some
-arguments, and there is nothing wrong in doing it.  It just makes life a
-bit harder, if you are not careful.
+It is, however, in certain cases necessary or convenient to leave out
+quotes for some arguments, and there is nothing wrong in doing it.  It
+just makes life a bit harder, if you are not careful.  For consistency,
+this manual follows the rule of thumb that each layer of parenthesis
+introduces another layer of single quoting, except when showing the
+consequences of quoting rules.  This is done even when the quoted string
+cannot be a macro, such as with integers.
 
 @node Macro expansion,  , Quoting Arguments, Macros
 @section Macro expansion
@@ -1001,6 +1014,20 @@ a part of the macro definition, and it i
 the output.  This can be avoided by use of the macro @code{dnl}.
 @xref{Dnl}, for details.
 
+The first argument to @code{define} should be quoted; otherwise, if the
+macro is already defined, you will be defining a different macro.  This
+example shows the problems with underquoting, since we did not want to
+define @code{one}:
+
[EMAIL PROTECTED]
+define(foo, one)
[EMAIL PROTECTED]
+define(foo, two)
[EMAIL PROTECTED]
+one
[EMAIL PROTECTED]
[EMAIL PROTECTED] example
+
 The macro @code{define} is recognized only with parameters.
 
 @node Arguments, Pseudo Arguments, Define, Definitions
@@ -1010,13 +1037,15 @@ The macro @code{define} is recognized on
 @cindex Arguments to macros
 Macros can have arguments.  The @var{n}th argument is denoted by
 @code{$n} in the expansion text, and is replaced by the @var{n}th actual
-argument, when the macro is expanded.  Here is an example of a macro with
+argument, when the macro is expanded.  Replacement of arguments happens
+before rescanning, regardless of how many nesting levels of quoting
+appear in the expansion.  Here is an example of a macro with
 two arguments.  It simply exchanges the order of the two arguments.
 
 @example
 define(`exch', `$2, $1')
 @result{}
-exch(arg1, arg2)
+exch(`arg1', `arg2')
 @result{}arg2, arg1
 @end example
 
@@ -1084,7 +1113,7 @@ nargs
 @result{}0
 nargs()
 @result{}1
-nargs(arg1, arg2, arg3)
+nargs(`arg1', `arg2', `arg3')
 @result{}3
 @end example
 
@@ -1121,8 +1150,12 @@ define(`foo', `This is macro `foo'.')
 @result{}
 echo1(foo)
 @result{}This is macro This is macro foo..
+echo1(`foo')
[EMAIL PROTECTED] is macro foo.
 echo2(foo)
 @result{}This is macro foo.
+echo2(`foo')
[EMAIL PROTECTED]
 @end example
 
 @noindent
@@ -1233,6 +1266,19 @@ In this way, @code{defn} can be used to 
 definitions of builtin macros.  Even if the original macro is removed,
 the other name can still be used to access the definition.
 
+The fact that macro definitions can be transferred also explains why you
+should use @code{$0}, rather than retyping a macro's name in its
+definition:
+
[EMAIL PROTECTED]
+define(`foo', `This is `$0'')
[EMAIL PROTECTED]
+define(`bar', defn(`foo'))
[EMAIL PROTECTED]
+bar
[EMAIL PROTECTED] is bar
[EMAIL PROTECTED] example
+
 The macro @code{defn} is recognized only with parameters.
 
 @node Pushdef, Indir, Defn, Definitions
@@ -1347,7 +1393,7 @@ The point is, here, that larger macro pa
 defined, that will not be called by accident.  They can @emph{only} be
 called through the builtin @code{indir}.
 
[EMAIL PROTECTED] FIXME: Why indir does not require at least one parameter?
+The macro @code{indir} is recognized only with parameters.
 
 @node Builtin,  , Indir, Definitions
 @section Indirect call of builtins
@@ -1444,16 +1490,35 @@ If called with three or four arguments, 
 for character), otherwise it expands to @var{not-equal}.
 
 @example
-ifelse(foo, bar, `true')
+ifelse(`foo', `bar', `true')
 @result{}
-ifelse(foo, foo, `true')
+ifelse(`foo', `foo', `true')
 @result{}true
-ifelse(foo, bar, `true', `false')
[EMAIL PROTECTED]
-ifelse(foo, foo, `true', `false')
+define(`foo', `bar')
[EMAIL PROTECTED]
+ifelse(foo, `bar', `true', `false')
 @result{}true
+ifelse(foo, `foo', `true', `false')
[EMAIL PROTECTED]
 @end example
 
+Notice how the first argument was used unquoted; it is common to compare
+the expansion of a macro with a string.  With this macro, you can now
+reproduce the behavior of many of the builtins, where the macro is
+recognized only with arguments.
+
[EMAIL PROTECTED]
+define(`foo', `ifelse(`$#', `0', ``$0'', `arguments:$#')')
[EMAIL PROTECTED]
+foo
[EMAIL PROTECTED]
+foo()
[EMAIL PROTECTED]:1
+foo(`a', `b', `c')
[EMAIL PROTECTED]:3
[EMAIL PROTECTED] example
+
+
 @cindex multibranches
 However, @code{ifelse} can take more than four arguments.  If given more
 than four arguments, @code{ifelse} works like a @code{case} or @code{switch}
@@ -1463,7 +1528,7 @@ the procedure is repeated with the first
 calls for an example:
 
 @example
-ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh')
 @result{}seventh
 @end example
 
@@ -1500,9 +1565,9 @@ It takes any number of arguments, and ex
 argument, separated by commas, with each argument quoted.
 
 @example
-shift(bar)
+shift(`bar')
 @result{}
-shift(foo, bar, baz)
+shift(`foo', `bar', `baz')
 @result{}bar,baz
 @end example
 
@@ -1510,14 +1575,14 @@ An example of the use of @code{shift} is
 order of its arguments:
 
 @example
-define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
                          `reverse(shift($@@)), `$1'')')
 @result{}
 reverse
 @result{}
-reverse(foo)
+reverse(`foo')
 @result{}foo
-reverse(foo, bar, gnats, and gnus)
+reverse(`foo', `bar', `gnats', `and gnus')
 @result{}and gnus, gnats, bar, foo
 @end example
 
@@ -1532,7 +1597,7 @@ can, for example, be used for simple cou
 
 @comment ignore
 @example
-forloop(`i', 1, 8, `i ')
+forloop(`i', `1', `8', `i ')
 @result{}1 2 3 4 5 6 7 8
 @end example
 
@@ -1545,7 +1610,7 @@ For-loops can be nested, like
 
 @comment ignore
 @example
-forloop(`i', 1, 4, `forloop(`j', 1, 8, `(i, j) ')
+forloop(`i', `1', `4', `forloop(`j', `1', `8', `(i, j) ')
 ')
 @result{}(1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8)
 @result{}(2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8)
@@ -1589,9 +1654,9 @@ a name.  Correcting these errors are lef
 @node Debugging, Input Control, Conditionals, Top
 @chapter How to debug macros and input
 
-When writing macros for @code{m4}, most of the time they would not
-work as intended (as is the case with most programming languages).
-There is a little support for macro debugging in @code{m4}.
+When writing macros for @code{m4}, they often do not work as intended on
+the first try (as is the case with most programming languages).
+Fortunately, there is support for macro debugging in @code{m4}.
 
 @menu
 * Dumpdef::                     Displaying macro definitions
@@ -1635,7 +1700,6 @@ dumpdef(`define')
 @end example
 
 The last example shows how builtin macros definitions are displayed.
-
 The definition that is dumped corresponds to what would occur if the
 macro were to be called at that point, even if other definitions are
 still live due to redefining a macro during argument collection.
@@ -1647,7 +1711,7 @@ f(popdef(`f')dumpdef(`f'))
 @error{}f:@tabchar{}``$0'1'
 @result{}f2
 f(popdef(`f')dumpdef(`f'))
[EMAIL PROTECTED]:7: m4: Undefined name f
[EMAIL PROTECTED]:7: m4: undefined macro `f'
 @result{}f1
 @end example
 
@@ -1673,7 +1737,7 @@ traceoff(...)
 
 @noindent
 When called without any arguments, @code{traceon} and @code{traceoff}
-will turn tracing on and off, respectively,  for all defined macros.
+will turn tracing on and off, respectively, for all defined macros.
 When called with arguments, only the named macros are affected.
 
 The expansion of @code{traceon} and @code{traceoff} is void.
@@ -1723,7 +1787,7 @@ undefine(`foo')
 ifdef(`foo', `yes', `no')
 @result{}no
 indir(`foo')
[EMAIL PROTECTED]:17: m4: Undefined macro `foo'
[EMAIL PROTECTED]:17: m4: undefined macro `foo'
 @result{}
 define(`foo', `blah')
 @result{}
@@ -1904,6 +1968,14 @@ collection will take place.  @code{dnl} 
 input following the matching close parenthesis up to and including the
 next newline, on whatever line containing it, will still be discarded.
 
[EMAIL PROTECTED]
+dnl(`this is ignored',
+`so is this') and this too
[EMAIL PROTECTED]:3: m4: Warning: excess arguments to builtin `dnl' ignored
+but not this
[EMAIL PROTECTED] not this
[EMAIL PROTECTED] example
+
 @node Changequote, Changecom, Dnl, Input Control
 @section Changing the quote characters
 
@@ -1921,11 +1993,13 @@ changequote(opt @var{start}, opt @var{en
 where @var{start} is the new start-quote delimiter and @var{end} is the
 new end-quote delimiter.  If any of the arguments are missing, the default
 quotes (@code{`} and @code{'}) are used instead of the void arguments.
[EMAIL PROTECTED] FIXME POSIX requires that with one argument, the closing quote
[EMAIL PROTECTED] be set to newline, not '.
 
 The expansion of @code{changequote} is void.
 
 @example
-changequote([, ])
+changequote(`[', `]')
 @result{}
 define([foo], [Macro [foo].])
 @result{}
@@ -1937,7 +2011,7 @@ If no single character is appropriate, @
 of any length.
 
 @example
-changequote([[[, ]]])
+changequote(`[[[', `]]]')
 @result{}
 define([[[foo]]], [[[Macro [[[[[foo]]]]].]]])
 @result{}
@@ -1982,9 +2056,9 @@ changecom(opt @var{start}, opt @var{end}
 @end example
 @noindent
 where @var{start} is the new start-comment delimiter and @var{end} is
-the new end-comment delimiter.  If any of the arguments are void, the
-default comment delimiters (@code{#} and newline) are used instead of
-the void arguments.  The comment delimiters can be of any length.
+the new end-comment delimiter.  If only one argument is provided,
+newline becomes the new end-comment delimiter.  The comment delimiters
+can be of any length.
 
 The expansion of @code{changecom} is void.
 
@@ -2006,8 +2080,8 @@ Note how comments are copied to the outp
 strings.  If you want the text inside a comment expanded, quote the
 start comment delimiter.
 
-Calling @code{changecom} without any arguments disables the commenting
-mechanism completely.
+Calling @code{changecom} without any arguments, or with an empty string
+for the first argument, disables the commenting mechanism completely.
 
 @example
 define(`comment', `COMMENT')
@@ -2051,7 +2125,7 @@ apply translations to a file of numbers:
 @example
 changeword(`[_a-zA-Z0-9]+')
 @result{}
-define(1, 0)1
+define(`1', `0')1
 @result{}0
 @end example
 
@@ -2065,7 +2139,7 @@ define(`_indir', defn(`indir'))
 @result{}
 changeword(`_[_a-zA-Z0-9]*')
 @result{}
-esyscmd(foo)
+esyscmd(`foo')
 @result{}esyscmd(foo)
 _indir(`esyscmd', `echo hi')
 @result{}hi
@@ -2164,7 +2238,7 @@ which stores @var{string} and the rest o
 to be reread when end of input is reached.
 
 @example
-define(`cleanup', `This is the `cleanup' actions.
+define(`cleanup', `This is the `cleanup' action.
 ')
 @result{}
 m4wrap(`cleanup')
@@ -2172,7 +2246,7 @@ m4wrap(`cleanup')
 This is the first and last normal input line.
 @result{}This is the first and last normal input line.
 ^D
[EMAIL PROTECTED] is the cleanup actions.
[EMAIL PROTECTED] is the cleanup action.
 @end example
 
 The saved input is only reread when the end of normal input is seen, and
@@ -2185,7 +2259,9 @@ not if @code{m4exit} is used to exit @co
 It is safe to call @code{m4wrap} from saved text, but then the order in
 which the saved text is reread is undefined.  If @code{m4wrap} is not used
 recursively, the saved pieces of text are reread in the opposite order
-in which they were saved (LIFO---last in, first out).
+in which they were saved (LIFO---last in, first out).  However, this
+behavior is likely to change in a future release, to match
[EMAIL PROTECTED], so you should not depend on this order.
 
 Here is an example of implementing a factorial function using
 @code{m4wrap}:
@@ -2195,7 +2271,7 @@ define(`f', `ifelse(`$1', `0', `Answer: 
 ', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
 ', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
 @result{}
-f(10)
+f(`10')
 @result{}
 ^D
 @result{}Answer: 10*9*8*7*6*5*4*3*2*1=3628800
@@ -2243,7 +2319,7 @@ does not.
 @example
 include(`none')
 @result{}
[EMAIL PROTECTED]:2: m4: Cannot open none: No such file or directory
[EMAIL PROTECTED]:2: m4: cannot open `none': No such file or directory
 sinclude(`none')
 @result{}
 @end example
@@ -2364,7 +2440,7 @@ When all the @code{m4} input will have b
 diversions are automatically undiverted, in numerical order.
 
 @example
-divert(1)
+divert(`1')
 This text is diverted.
 divert
 @result{}
@@ -2397,7 +2473,7 @@ example of unwanted output is the traili
 definitions.  Here is how to avoid them.
 
 @example
-divert(-1)
+divert(`-1')
 define(`foo', `Macro `foo'.')
 define(`bar', `Macro `bar'.')
 divert
@@ -2423,18 +2499,16 @@ which undiverts the diversions given by 
 given.  If no arguments are supplied, all diversions are undiverted, in
 numerical order.
 
[EMAIL PROTECTED] FIXME: Explain what happens when undiverting all to else than 
0.
-
 The expansion of @code{undivert} is void.
 
 @example
-divert(1)
+divert(`1')
 This text is diverted.
 divert
 @result{}
 This text is not diverted.
 @result{}This text is not diverted.
-undivert(1)
+undivert(`1')
 @result{}
 @result{}This text is diverted.
 @result{}
@@ -2452,21 +2526,34 @@ When a diversion has been undiverted, th
 and it is not possible to bring back diverted text more than once.
 
 @example
-divert(1)
+divert(`1')
 This text is diverted first.
-divert(0)undivert(1)dnl
+divert(`0')undivert(`1')dnl
 @result{}
 @result{}This text is diverted first.
-undivert(1)
+undivert(`1')
 @result{}
-divert(1)
+divert(`1')
 This text is also diverted but not appended.
-divert(0)undivert(1)dnl
+divert(`0')undivert(`1')dnl
 @result{}
 @result{}This text is also diverted but not appended.
 @end example
 
-Attempts to undivert the current diversion are silently ignored.
+Attempts to undivert the current diversion are silently ignored.  Thus,
+when the current diversion is not 0, the current diversion does not get
+rearranged among the other diversions.
+
[EMAIL PROTECTED]
+divert(`1')one
+divert(`2')two
+divert(`3')three
+divert(`2')undivert`'dnl
+divert`'undivert`'dnl
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED] example
 
 @cindex GNU extensions
 @cindex file inclusion
@@ -2506,12 +2593,10 @@ expands to the number of the current div
 @example
 Initial divnum
 @result{}Initial 0
-divert(1)
+divert(`1')
 Diversion one: divnum
-divert(2)
+divert(`2')
 Diversion two: divnum
-divert
[EMAIL PROTECTED]
 ^D
 @result{}
 @result{}Diversion one: 1
@@ -2519,9 +2604,6 @@ divert
 @result{}Diversion two: 2
 @end example
 
-The last call of @code{divert} without argument is necessary, since the
-undiverted text would otherwise be diverted itself.
-
 @node Cleardiv,  , Divnum, Diversions
 @section Discarding diverted text
 
@@ -2532,14 +2614,14 @@ text is actually needed.  Since all non-
 on the main output stream when the end of input is seen, a method of
 discarding a diversion is needed.  If all diversions should be
 discarded, the easiest is to end the input to @code{m4} with
[EMAIL PROTECTED](-1)} followed by an explicit @samp{undivert}:
[EMAIL PROTECTED](`-1')} followed by an explicit @samp{undivert}:
 
 @example
-divert(1)
+divert(`1')
 Diversion one: divnum
-divert(2)
+divert(`2')
 Diversion two: divnum
-divert(-1)
+divert(`-1')
 undivert
 ^D
 @end example
@@ -2551,7 +2633,7 @@ Clearing selected diversions can be done
 
 @example
 define(`cleardivert',
-`pushdef(`_n', divnum)divert(-1)undivert($@@)divert(_n)popdef(`_n')')
+`pushdef(`_n', divnum)divert(`-1')undivert($@@)divert(_n)popdef(`_n')')
 @result{}
 @end example
 
@@ -2696,9 +2778,9 @@ which expands to the substring of @var{s
 is always 0.
 
 @example
-substr(`gnus, gnats, and armadillos', 6)
+substr(`gnus, gnats, and armadillos', `6')
 @result{}gnats, and armadillos
-substr(`gnus, gnats, and armadillos', 6, 5)
+substr(`gnus, gnats, and armadillos', `6', `5')
 @result{}gnats
 @end example
 
@@ -2852,7 +2934,7 @@ example shows how @code{format} can be u
 
 @comment ignore
 @example
-forloop(`i', 1, 10, `format(`%6d squared is %10d
+forloop(`i', `1', `10', `format(`%6d squared is %10d
 ', i, eval(i**2))')
 @result{}     1 squared is          1
 @result{}     2 squared is          4
@@ -2874,7 +2956,7 @@ modifiers @samp{+}, @samp{-}, @[EMAIL PROTECTED] 
 @samp{l}.  For more details on the functioning of @code{printf}, see the
 C Library Manual.
 
[EMAIL PROTECTED] FIXME: Why format does not require at least one argument?
+The macro @code{format} is recognized only with parameters.
 
 @node Arithmetic, UNIX commands, Text handling, Top
 @chapter Macros for doing arithmetic
@@ -2911,9 +2993,9 @@ which expand to the numerical value of @
 or decremented, respectively, by one.
 
 @example
-incr(4)
+incr(`4')
 @result{}5
-decr(7)
+decr(`7')
 @result{}6
 @end example
 
@@ -2993,20 +3075,20 @@ relation return @code{0}.
 Here are a few examples of use of @code{eval}.
 
 @example
-eval(-3 * 5)
+eval(`-3 * 5')
 @result{}-15
 eval(index(`Hello world', `llo') >= 0)
 @result{}1
-define(`square', `eval(($1)**2)')
+define(`square', `eval(`('$1`)**2')')
 @result{}
-square(9)
+square(`9')
 @result{}81
-square(square(5)+1)
+square(square(`5')`+1')
 @result{}676
 define(`foo', `666')
 @result{}
-eval(`foo'/6)
[EMAIL PROTECTED]:14: m4: Bad expression in eval: foo/6
+eval(`foo/6')
[EMAIL PROTECTED]:14: m4: bad expression in eval: foo/6
 @result{}
 eval(foo/6)
 @result{}111
@@ -3024,15 +3106,15 @@ output width.  The result is zero-padded
 requested width.
 
 @example
-eval(666, 10)
+eval(`666', `10')
 @result{}666
-eval(666, 11)
+eval(`666', `11')
 @result{}556
-eval(666, 6)
+eval(`666', `6')
 @result{}3030
-eval(666, 6, 10)
+eval(`666', `6', `10')
 @result{}0000003030
-eval(-666, 6, 10)
+eval(`-666', `6', `10')
 @result{}-000003030
 @end example
 
@@ -3109,7 +3191,7 @@ Assume you are positioned into the @file
 @code{m4} distribution, then:
 
 @example
-define(`vice', `esyscmd(grep Vice ../COPYING)')
+define(`vice', `esyscmd(`grep Vice ../COPYING')')
 @result{}
 vice
 @result{}  Ty Coon, President of Vice
@@ -3142,7 +3224,7 @@ which expands to the exit status of the 
 @example
 syscmd(`false')
 @result{}
-ifelse(sysval, 0, zero, non-zero)
+ifelse(sysval, `0', `zero', `non-zero')
 @result{}non-zero
 syscmd(`exit 2')
 @result{}
@@ -3261,9 +3343,9 @@ which expands to the quoted name of the 
 current input line number in that file.
 
 @example
-errprint(`m4:'__file__:__line__: `Input error
+errprint(`m4:'__file__:__line__: `input error
 ')
[EMAIL PROTECTED]:m4.input:2: Input error
[EMAIL PROTECTED]:m4.input:2: input error
 @result{}
 @end example
 
@@ -3286,10 +3368,10 @@ which causes @code{m4} to exit, with exi
 @example
 define(`fatal_error',
        `errprint(`m4: '__file__: __line__`: fatal error: $*
-')m4exit(1)')
+')m4exit(`1')')
 @result{}
-fatal_error(`This is a BAD one, buster')
[EMAIL PROTECTED]: m4.input: 6: fatal error: This is a BAD one, buster
+fatal_error(`this is a BAD one, buster')
[EMAIL PROTECTED]: m4.input: 6: fatal error: this is a BAD one, buster
 @end example
 
 After this macro call, @code{m4} will exit with exit code 1.  This macro
@@ -3390,11 +3472,13 @@ m4 -R file3.m4f file4.m4
 Some care is necessary because not every effort has been made for
 this to work in all cases.  In particular, the trace attribute of
 macros is not handled, nor the current setting of @code{changeword}.
+Currently, @code{m4wrap} and @code{sysval} also have problems.
 Also, interactions for some options of @code{m4} being used in one call
 and not for the next, have not been fully analyzed yet.  On the other
 end, you may be confident that stacks of @code{pushdef}'ed definitions
 are handled correctly, so are @code{undefine}'d or renamed builtins,
-changed strings for quotes or comments.
+changed strings for quotes or comments.  And future releases of GNU M4
+will improve on the utility of frozen files.
 
 When an @code{m4} run is to be frozen, the automatic undiversion
 which takes place at end of execution is inhibited.  Instead, all
@@ -3637,6 +3721,11 @@ file for each invocation of @code{makete
 of the macro is different even if the input is identical.
 
 @item
[EMAIL PROTECTED] requires @code{changequote(@var{arg})}
+(@pxref{Changequote}) to use newline as the close quote, but GNU
[EMAIL PROTECTED] uses @samp{'} as the close quote.
+
[EMAIL PROTECTED]
 Traditional @code{m4} treats @code{traceon} (@pxref{Trace}) without
 arguments as a global variable, independent of named macro tracing.
 Also, once a macro is undefined, named tracing of that macro is lost.
@@ -3647,6 +3736,13 @@ turns tracing off for all definitions re
 also traced by name; and tracing by name, such as with @samp{-tfoo} at
 the command line or @code{traceon(`foo')} in the input, is an attribute
 that is preserved even if the macro is currently undefined.
+
[EMAIL PROTECTED]
+Traditional implementations allow argument collection, but not string
+processing, to span file boundaries.  Thus, if @file{a.m4} contains
[EMAIL PROTECTED](}, and @file{b.m4} contains @samp{abc)}, @kbd{m4 a.m4 b.m4}
+outputs @samp{3} with traditional @code{m4}, but gives an error message
+that the end of file was encountered inside a macro with GNU @code{m4}.
 @end itemize
 
 @node Other Incompatibilities,  , Incompatibilities, Compatibility
_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches

Reply via email to