A NOTE has been added to this issue. 
====================================================================== 
http://austingroupbugs.net/view.php?id=1072 
====================================================================== 
Reported By:                quinngrier
Assigned To:                
====================================================================== 
Project:                    1003.1(2013)/Issue7+TC1
Issue ID:                   1072
Category:                   Shell and Utilities
Type:                       Clarification Requested
Severity:                   Comment
Priority:                   normal
Status:                     New
Name:                       Quinn Grier 
Organization:                
User Reference:              
Section:                    m4 (utility) 
Page Number:                2899, 2901 
Line Number:                95625, 95733 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2016-08-27 01:18 UTC
Last Modified:              2018-02-09 14:47 UTC
====================================================================== 
Summary:                    m4 ifelse argument expansion clarification
====================================================================== 

---------------------------------------------------------------------- 
 (0003919) eblake (manager) - 2018-02-09 14:47
 http://austingroupbugs.net/view.php?id=1072#c3919 
---------------------------------------------------------------------- 
Interpretation response
------------------------

The standard is unclear on this issue, and no conformance distinction can
be made between alternative implementations based on this. This is being
referred to the sponsor.

Rationale:
-------------
All known m4 implementations perform macro expansion and argument
collection in the same manner; but the wording used in the standard was did
not give enough details on how this occurs.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------
All page and line numbers are for the 2016 edition.

On page 2934 lines 97081-97090 change:
<blockquote>The <i>m4</i> utility shall compare each token from the input
against the set of built-in and user-defined macros. If the token matches
the name of a macro, then the token shall be replaced by the macro’s
defining text, if any, and rescanned for matching macro names. Once no
portion of the token matches the name of a macro, it shall be written to
standard output. Macros may have arguments, in which case the arguments
shall be substituted into the defining text before it is rescanned.

Macro calls have the form:

<i>name</i>(<i>arg1, arg2, ..., argn</i>)

Macro names shall consist of letters, digits, and underscores, where the
first character is not a digit. Tokens not of this form shall not be
treated as macros.</blockquote>to:
<blockquote>The <i>m4</i> utility shall compare each token from the input
against the set of built-in and user-defined macros. If the token matches
the name of a macro, then the token shall be replaced by the macro’s
defining text, if any, then scanning for tokens shall resume at the start
of the macro's defining text concatenated with the subsequent input.  If a
token does not match the name of a macro, it shall be written to standard
output.  Macros may have arguments, in which case the arguments shall be
substituted into the defining text before it is rescanned.

No special meaning shall be given to characters enclosed between matching
left and right quoting strings, other than identifying nested quoting while
finding the matching right quoting string, but the outermost quoting
strings shall themselves be discarded. By default, the left quoting string
consists of a grave accent (backquote) and the right quoting string
consists of an acute accent (single-quote); see also the <b>changequote</b>
macro.

Comments are written but not scanned for matching macro names; by default,
the begin-comment string consists of the <number-sign> character and the
end-comment string consists of a <newline>. See also the <b>changecom</b>
and <b>dnl</b> macros.

Name tokens shall consist of the longest possible sequence of letters,
digits, and underscores, where the first character is not a digit. Tokens
not of this form shall not be treated as name tokens.  A macro call is a
name token that matches the name of a built-in or user-defined macro. 
Macro calls can have either of the following forms, which shall be
distinguished by whether or not the macro name is immediately followed by a
<left-parenthesis>:

    <i>name</i>

    <i>name</i>(<i>arg1, arg2, ..., argn</i>)</blockquote>

On page 2934 lines 97094-97106 change:
<blockquote>If a macro name is followed by a <left-parenthesis>, its
arguments are the <comma>-separated tokens between the <left-parenthesis>
and the matching <right-parenthesis>. Unquoted white-space characters
preceding each argument shall be ignored. All other characters, including
trailing white-space characters, are retained. <comma> characters enclosed
between <left-parenthesis> and <right-parenthesis> characters do not
delimit arguments.

Arguments are positionally defined and referenced. The string "<tt>$1</tt>"
in the defining text shall be replaced by the first argument. Systems shall
support at least nine arguments; only the first nine can be referenced,
using the strings "<tt>$1</tt>" to "<tt>$9</tt>", inclusive. The string
"<tt>$0</tt>" is replaced with the name of the macro. The string
"<tt>$#</tt>" is replaced by the number of arguments as a string. The
string "<tt>$*</tt>" is replaced by a list of all of the arguments,
separated by <comma> characters. The string "<tt>$@</tt>" is replaced by a
list of all of the arguments separated by <comma> characters, and each
argument is quoted using the current left and right quoting strings. The
string "<tt>${</tt>" produces unspecified behavior.</blockquote> to:
<blockquote>If a macro name is followed by a <left-parenthesis>, the
subsequent text shall be tokenized and expanded until a token is
encountered that is not a quoted string and whose expansion includes a
matching unquoted <right-parenthesis>.  The expanded text between the
<left-parenthesis> and the matching unquoted <right-parenthesis> is the
macro's argument text.  An unquoted <comma> character within the macro's
argument text shall mark the end of one argument and the beginning of the
next argument unless the unquoted <comma> is enclosed within a nested
unquoted <left-parenthesis>, <right-parenthesis> pair.  The unquoted
<comma> characters that separate the arguments, and any unquoted whitespace
characters at the beginning of each argument, shall be discarded.  All
other characters in the macro's argument text, including any whitespace
characters at the end of an argument and any nested parenthesized text,
shall be retained.  The input text containing the macro name, the following
<left-parenthesis>, and all tokens up to and including the token whose
expansion contained the matching unquoted <right-parenthesis> shall be
replaced, and tokenization shall resume on the result of performing
argument substition on the macro's defining text followed by any expanded
text that followed the matching unquoted <right-parenthesis>.  Otherwise,
the macro name was not followed by a <left-parenthesis>, and tokenization
shall resume on the result of performing argument substitution with zero
arguments on the macro's defining text.

During argument substitution, arguments shall be positionally defined and
referenced. The string "<tt>$1</tt>" in the defining text shall be replaced
by the first argument. Systems shall support at least nine arguments; only
the first nine can be referenced, using the strings "<tt>$1</tt>" to
"<tt>$9</tt>", inclusive. The string "<tt>$0</tt>" shall be replaced with
the name of the macro. The string "<tt>$#</tt>" shall be replaced by the
number of arguments as a minimal string of decimal digits ('0' if the macro
was invoked without being followed by a <left-parenthesis>, otherwise 1
more than the number of unquoted <comma> characters that divided arguments
in the macro's argument text). The string "<tt>$*</tt>" shall be replaced
by a list of all of the arguments, separated by <comma> characters. The
string "<tt>$@</tt>" shall be replaced by a list of all of the arguments
separated by <comma> characters, and each argument shall be quoted using
the current left and right quoting strings. The string "<tt>${</tt>"
produces unspecified behavior.</blockquote>

On page 2934, delete lines 97110-97116:
<blockquote>No special meaning is given to any characters enclosed between
matching left and right quoting strings, but the quoting strings are
themselves discarded. By default, the left quoting string consists of a
grave accent (backquote) and the right quoting string consists of an acute
accent (single-quote); see also the <b>changequote</b> macro.

Comments are written but not scanned for matching macro names; by default,
the begin-comment string consists of the <number-sign> character and the
end-comment string consists of a <newline>. See also the <b>changecom</b>
and <b>dnl</b> macros.</changequote>
(as these lines were moved and reworded in an earlier change)

On page 2935 line 97129 (changecom), change:
<blockquote>The behavior is unspecified if either argument is provided but
null.</blockquote> to:
<blockquote>The behavior is unspecified if either argument is provided but
null, or if either argument includes letters, digits, underscore, or
<left-parenthesis>.</blockquote>

On page 2935 line 97133 (changequote), change:
<blockquote>The behavior is unspecified if there is a single argument or
either argument is null.</blockquote> to:
<blockquote>The behavior is unspecified if there is a single argument, or
if either argument is null or includes letters, digits, underscore, or
<left-parenthesis>.</blockquote>

On page 2936 line 97206 (ifelse), remove the following parenthetical
remark:
<blockquote>(after macro expansion of both arguments)</blockquote>

On page 2940, in the EXAMPLES section, after line 97369, add the following
(note to editor: feel free to use bullets or other list identifiers instead
of numbers, if that is better):
<blockquote>In the following six examples, an additional line is evaluated
after this prologue of three definitions:

 <pre>define(`macro', `argument 2 is :`$2':, called with $# arguments')dnl
 define(`argumentsa', `Arguments')dnl
 define(`a', `.')dnl</pre>

1. The additional line:
 <pre>macro`'a</pre>
produces:
 <pre>argument 2 is ::, called with 0 arguments.</pre>
Explanation:  <i>macro</i> is called with 0 arguments (as shown by the $#
substitution), the substitution of $2 is the empty string, and the empty
quoted string after the expansion text prevents concatenation with the
subsequent "a", which in turn lets macro <i>a</i> expand to the final
<tt>.</tt>.

2. The additional line:
 <pre>macro()a</pre>
produces:
 <pre>argument 2 is ::, called with 1 Arguments</pre>
Explanation:  <i>macro</i> is called with one (empty string) argument; then
the defining text ending in "arguments" is concatenated with the subsequent
"a" to form the next macro name <i>argumentsa</i> which is expanded into
<tt>Arguments</tt> before the final output.

3. The additional line:
 <pre>macro(  1, (,2,) ,  `3')</pre>
produces:
 <pre>argument 2 is :(,2,) :, called with 3 arguments</pre>
Explanation: Leading (but not trailing) space is removed before the
argument substituted for $2, and the unquoted commas embedded in
parentheses do not delineate arguments.

4. The additional line:
 <pre>macro(  `1', `mac2(,`2',)', `3')</pre>
produces:
 <pre>argument 2 is :mac2(,`2',):, called with 3 arguments</pre>
Explanation: Regardless of whether <i>mac2</i> is a defined macro, quoting
in the macro call prevents interpretation of "mac2" during argument
collection, and the quoting in the defining text of <i>macro</i> prevents
interpretation of "mac2" in the substitution of $2 during rescan of the
output of <i>macro</i>.

5. The additional line:
 <pre>undefine(`mac2')macro(  1, mac2(,2,), 3)</pre>
produces:
 <pre>argument 2 is :mac2(,2,):, called with 3 arguments</pre>
Explanation: <i>mac2</i> is not a macro name when scanned during argument
collection, so it and the subsequent parenthesized text is used literally.

6. The additional line:
 <pre>define(`mac2', `hi$@')macro(  1, mac2(,2,), 3)</pre>
produces:
 <pre>argument 2 is :hi:, called with 4 arguments</pre>
Explanation: <i>mac2</i> is a macro name, so collecting the arguments to
<i>macro</i> requires scanning the output of <i>mac2(,2,)</i> (the text
<tt>`hi',`2',`'</tt> after substitution of $@); this output contains
unquoted commas causing additional arguments to be visible to
<i>macro</i>.</blockquote> 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2016-08-27 01:18 quinngrier     New Issue                                    
2016-08-27 01:18 quinngrier     Name                      => Quinn Grier     
2016-08-27 01:18 quinngrier     Section                   => m4 (utility)    
2016-08-27 01:18 quinngrier     Page Number               => 2899, 2901      
2016-08-27 01:18 quinngrier     Line Number               => 95625, 95733    
2016-08-29 03:01 quinngrier     Note Added: 0003366                          
2016-08-29 03:28 Don Cragun     Interp Status             => ---             
2016-08-29 03:28 Don Cragun     Note Added: 0003367                          
2016-08-29 03:28 Don Cragun     Description Updated                          
2016-08-29 03:29 Don Cragun     Description Updated                          
2018-02-09 14:47 eblake         Note Added: 0003919                          
======================================================================


Reply via email to