Name
	alx-0003r3 - Add directives #def and #enddef

Category
	New directives.

Author
	Alejandro Colomar <alx@kernel.org>

	Cc: Martin Uecker <uecker@tugraz.at>
	Cc: Joseph Myers <josmyers@redhat.com>
	Cc: Javier Múgica <javier@aerotri.es>
	Cc: Ori Bernstein <ori@eigenstate.org>
	Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>

History
	<https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0003.git/>

	r0 (2025-03-10):
	-  Pick stuff from n1410.

	r1 (2025-03-11):
	-  Fix typos.
	-  Only allow conditional (and null) preprocessing directives
	   within a replacement body.
	-  Update wording regarding nesting with if sections.
	-  Update wording that refers to replacement lists.
	Thanks to Joseph for the feedback that led to r1.

	r2 (2025-03-14):
	-  Disallow all preprocessing directives within a replacement
	   group.  Make it equivalent to #define except for not needing
	   the escape characters to use multiple source lines.  This is
	   the minimal feature, which makes sure we don't add an
	   underdeveloped feature, but rather a scoped one.

	r3 (2025-03-19):
	-  Define replacement-group directly in terms of pp-tokens, not
	   in terms of replacement-list.

Description
	One thing that gets in the way when writing and sharing macros
	is writing (and updating) the trailing \ at the end of each
	line.  Multi-line macros could be defined with an end delimiter
	instead.  That would also make syntax highlighting nicer.

	Here's the proposed syntax:

		#def foo(x)
		do {
			bar(x);
			baz(x);
		while (0)
		#enddef

Proposed wording
	Based on N3467.

    6.10.1  Preprocessing directives :: General
	@@ Syntax, p1
	 group-part:
	 	if-section
	+	def-section
	 	control-line
	 	text-line
	 	# non-directive
	@@ p1, after endif-line
	+def-section:
	+	def-line replacement-group(opt) enddef-line
	+
	+def-line:
	+	# def identifier new-line
	+	# def identifier lparen identifier-list(opt) ) new-line
	+	# def identifier lparen ... ) new-line
	+	# def identifier lparen identifier-list , ... ) new-line
	+
	+replacement-group:
	+	pp-tokens(opt) new-line
	+	replacement-group pp-tokens(opt) new-line
	+
	+enddef-line:
	+	# enddef new-line

    6.10.2  Conditional inclusion
	@@ Constraints, p4
	 (that is,
	 if it is predefined
	 or if it has been the subject of
	-a #define
	+a #define or #def
	 preprocessing directive
	 without an intervening #undef directive
	 with the same subject identifier),

    6.10.3  Source file inclusion
	s/replacement list/& or group/g

    6.10.4  Binary resource inclusion
	s/replacement list/& or group/g

    6.10.5.1  Macro replacement :: General
	@@ Constraints, p1
	-Two replacement lists
	+Two replacement lists or groups
	 are identical

	@@ p2
	 shall not be redefined
	-by another #define preprocessing directive
	+by another #define or #def preprocessing directive
	 unless the second definition is
	 an object-like macro definition
	-and the two replacement lists
	+and the two replacement lists or groups
	 are identical.
	...
	 shall not be redefined
	-by another #define preprocessing directive
	+by another #define or #def preprocessing directive
	 unless the second definition is
	 a function-like macro definition
	 that has the same number and spelling of parameters,
	-and the two replacement lists
	+and the two replacement lists or groups
	 are identical.

	@@ p5
	 The identifiers __VA_ARGS__ and __VA_OPT__
	 shall occur only in
	-the replacement-list
	+the replacement list or group
	 of a function-like macro

	@@ Semantics, p7
	 The identifier immediately following the
	-define
	+define or def
	 is called the macro name.
	...
	 Any white-space characters preceding or following
	-the replacement list
	+the replacement list or group
	 of preprocessing tokens
	 are not considered part of the replacement list or group
	 for either form of macro.

	@@ p9
	 A preprocessing directive of the form
		# define identifier replacement-list new-line
	+	# def identifier new-line
	...
	 to be replaced by
	-the replacement list
	+the replacement list or group
	 of preprocessing tokens
	 that constitute the remainder of the directive.
	-The replacement list
	+The replacement list or group
	 is then rescanned for more macro names
	 as specified later in this subclause.

	@@ p10
	 A preprocessing directive of the form
		# define identifier lparen identifier-list(opt) ) replacement-list new-line
		# define identifier lparen ... ) replacement-list new-line
		# define identifier lparen identifier-list , ... ) replacement-list new-line
	+	# def identifier lparen identifier-list(opt) ) new-line
	+	# def identifier lparen ... ) new-line
	+	# def identifier lparen identifier-list , ... ) new-line
	...
	 until the new-line character
	-that terminates the #define preprocessing directive.
	+that terminates the #define preprocessing directive,
	+or until the enddef line
	+that terminates the #def preprocessing directive.
	 Each subsequent instance of the function-like macro name
	 followed by a ( as the next preprocessing token
	 introduces the sequence of preprocessing tokens
	 that is replaced by
	-the replacement list
	+the replacement list or group
	 in the definition
	 (an invocation of the macro).

    6.10.5.2  Macro replacement :: Argument substitution
	s/replacement list/& or group/g

    6.10.5.3  Macro replacement :: The # operator
	@@ Constraints, p1
	 Each # preprocessing token
	-in the replacement list
	+in the replacement list or group
	 for a function-like macro
	 shall be followed by a parameter
	 as the next preprocessing token in the replacement list.

	@@ Semantics, p2
	 If,
	-in the replacement list,
	+in the replacement list or group,
	 a parameter is immediately preceded
	 by a # preprocessing token,

    6.10.5.4  Macro replacement :: The ## operator
	s/replacement list/& or group/g

    6.10.5.5  Macro replacement :: Rescanning and further replacement
	s/replacement list/& or group/g

    6.10.6  Line control
	s/replacement list/& or group/g

    6.10.10.1  Predefined macro names :: General
	@@ p2
	 shall be the subject of
	-a #define or a #undef
	+a #define, #def, or #undef
	 preprocessing directive.

    7.28  Type-generic math <tgmath.h>
	@@ p14 (NOTE)
	-	#define cbrt(X)                  \
	-	_Generic((X),                    \
	-	  long double: _Roundwise_cbrtl, \
	-	  default:     _Roundwise_cbrt,  \
	-	  float:       _Roundwise_cbrtf  \
	-	)(X)
	+	#def cbrt(X)
	+	_Generic((X),
	+	  long double: _Roundwise_cbrtl,
	+	  default:     _Roundwise_cbrt,
	+	  float:       _Roundwise_cbrtf
	+	)(X)
	+	#enddef

    J.1  Unspecified behavior
	s/replacement list/& or group/g