summaryrefslogtreecommitdiffabout
path: root/README
blob: 40782d89570c74e8e9a33baadfeb3f8acb1f838c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
M4KWARGS - keyword argument support for m4 macros
=================================================

M4kwargs is a macro package that implements keyword arguments for
m4 macros. It relies on the patsubst builtin, which is available at
least in GNU m4 and in FreeBSD m4. This package has been tested with
these two implementations.

Installation
============

After unpacking the tarball, run "make check". If all tests pass, proceed to
installation. Otherwise, feel free to send a report to the author. See below
for the contact information.

To install the package, run "make install". The name of the installation
target directory is described in Makefile terms as

  $(DESTDIR)$(PREFIX)/share/$(M4DIR)

Default values for these variables are:

  $(DESTDIR)   (empty)
  $(PREFIX)    /usr/local
  $(M4DIR)     m4kwargs

To change the installation directory, override any or all of these in the
make command line. E.g. to install to /usr/share/m4, do

  make install PREFIX=/usr M4DIR=m4

Another noteworthy installation variable is BRACKETQUOTES. By default, m4kwargs
assumes standard m4 quotes (`'). You can change them to [] when installing the
package by declaring BRACKETQUOTES=1:

  make install BRACKETQUOTES=1

Usage
=====

It is supposed that the pathname of the installation directory is added to the
m4 search path using the -I command line option, if your version of m4 supports
it. If not, run m4 from the installation directory.

Include the file kwargs.m4 at the top of your source file:

  include(kwargs.m4)

This will do the following:

1. Check if m4 provides the patsubst builtin. If not, an error message will
be printed and m4 will terminate with exit status 1.
2. Check if patsubst takes a basic or extended regular expression as its
second argument.
3. Prefix all built-in m4 identifiers with m4_. Note to GNU m4 users:
don't use the -P (--prefix-builtins) option, as it will interfere with
this step.
4. Load the package macros.

All these steps are performed in a diversion, so that they add nothing to the
output.

The basic way of declaring keyword arguments is by using the KWARGS_ASGN
macro. This macro takes as its arguments a comma-delimited list of
keyword=value assignments. Its expansion is empty.

Suppose you want to write a macro INCR, that takes a single numeric argument
and expands to its value incremented by one. If a keyword argument `delta' is
supplied, the macro will expand to its argument incremented by that value, so
that

  INCR(4) => 5
  INCR(4,delta=2)  => 6

Here is how to declare such macro:

  m4_define(`INCR',
    `KWARGS_ASGN(m4_shift($@))m4_eval($1 + KWARG_VALUE(`delta',1))')

The KWARG_VALUE macro expands to the value of the keyword argument named by
its first parameter, if it is defined, and to its second parameter otherwise.

This definition has a drawback that keywords assigned by KWARGS_ASGN will
remain in effect after the macro has been expanded. To avoid this, use the
KWARGS_PUSH/KWARGS_POP pair, as shown below:

  m4_define(`INCR',
    `KWARGS_PUSH(m4_shift($@))m4_eval($1 + KWARG_VALUE(`delta',1))KWARGS_POP')

The package provides a special macro KW_DEFINE, for defining macros that
make use of keyword arguments. The basic usage is the same as for m4_define:

  KW_DEFINE(NAME, TEXT)

The KW_DEFINE macro takes care to wrap the expansion of TEXT in KWARGS_PUSH
and KWARGS_POP. There is one special thing about it: TEXT should refer to
positional arguments using the notation KW_ARGV(N), instead of the familiar
$N. Here is how to define INCR using KW_DEFINE:

  KW_DEFINE(`INCR',
    `m4_eval(KW_ARGV(1) + KWARG_VALUE(`delta',1))')

Macros
======

This section describes the macros provided by this package. They are ordered
by category.

Debugging
---------

KWARGS_DUMP([DELIM],[EXP])
  For each defined keyword argument, produce the following expansion:
  
    EXP(`KW=VAL')DELIM
    
  DELIM defaults to newline, EXP - to m4_quote, 

Keyword arguments access macros
-------------------------------

KWARG_IFSET(NAME,IF-SET,IF-NOT-SET)
  If the argument NAME is set, expands to IF-SET, otherwise expands
  to IF-NOT-SET.

KWARGS_SWITCH(NAME1,IF-SET1,NAME2,IF-SET2,...,IF-NOT-SET)
  If NAME1 is set, expands to IF-SET1. Otherwise, if NAME2 is set,
  expands to IF-SET2. The process continues for all name-if-set pairs within
  `...'.  If none of the names is set, expands to IF-NOT-SET.

KWARGS_SWITCH_VALUE(NAME, VAL1, CASE1, VAL2, CASE2,..., OTHERWISE)
  If keyword argument NAME has value VAL1, expands to CASE1.
  Otherwise, if NAME has value VAL2, expands to CASE2, etc.
  If no matching value is listed, expands to OTHERWISE.

KWARG_VALUE(NAME [,DEFAULT])
  Expands to the value of argument NAME, if it is defined, or to DEFAULT
  otherwise.

KWARGS_FOREACH(ITERATOR, TEXT)
  Takes the name in ITERATOR, which must be a valid identifier, and
  successively assigns it each keyword name. For each assignment to ITERATOR,
  TEXT is appended to the expansion of KWARGS_FOREACH. TEXT may refer to
  ITERATOR. Any definition of ITERATOR prior to this invocation is restored.

KWARGS_LIST()
  Expand to a comma-delimited list of quoted keyword arguments, suitable for
  use as argument list to a macro.

Expansion in keyword argument context
-------------------------------------

KWARGS_APPLY(MACRO,[ARGS...])
  Split ARGS into positional and keyword arguments and expand to
  MACRO(PARGS), where PARGS are positional arguments. MACRO can
  refer to keyword arguments using the macros discussed above.
  
KWARGS_WITH(TEXT,ARGS...)
  Split ARGS into positional and keyword arguments and expand to
  TEXT.
  To refer to the positional arguments from TEXT, use the following notation:

     KW_ARGV(1)     instead of $1
     KW_ARGV(2)     instead of $*
     ...
     KW_ARGV        instead of $*        
     KW_ARGQ        instead of $@
     KW_ARGC        instead of $#        

KWARGS_DEFINE(NAME,TEXT)
  Defines NAME to expand to TEXT. Upon expansion, the argument list
  is split into positional arguments and keyword arguments as in KWARGS_WITH.
  TEXT should refer to positional arguments using the macros described above.

Keyword argument manipulation
-----------------------------

KWARGS_ASGN(ARGS...)
  Assign arguments.
  ARGS is a comma-separated list of keyword[=value] pairs.

KWARGS_UNASGN(ARGS...])
  Unassign keywords. ARGS is the same as for KWARGS_ASGN.

KWARGS_PUSH([ARGS...])
  Push current keyword arguments on stack, clear the keyword argument table
  and reset keyword arguments using KWARGS_ASGN(ARGS).

KWARGS_POP()
  Pop keyword argument definitions from stack.

KWARGS_DUP()
  Push current keyword arguments on stack and retain their definitions.
  This can be used to augment or override keyword arguments. To
  restore previous arguments, use KWARGS_POP. The normal usage pattern is:
  
    KWARGS_PUSH()
    KWARGS_ASGN($@)
    ...
    KWARGS_POP

Low-level interface
-------------------

KWARGS_PARSE(ARGS...)
  Split ARGS in positional and keyword arguments. Define the latter, expand
  to the former.

KWARG_SET(NAME [, VALUE])
  Sets argument NAME to VALUE

KWARG_CLR(NAME)
  Clears the keyword argument NAME.

KWARG_ASGN(NAME[=VAL])
  Assigns VAL to NAME. If VAL is absent, equivalent to KWARG_SET(NAME).

KWARG_UNASGN(NAME[=VAL])
  Unassign argument. Optional VAL is ignored.

Bug-reporting
=============

Please send your bug reports and suggestions to
Sergey Poznyakoff <gray@gnu.org>.


Return to:

Send suggestions and report system problems to the System administrator.