[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] @quote-args for multiple arguments
From: |
Sergey Poznyakoff |
Subject: |
Re: [PATCH] @quote-args for multiple arguments |
Date: |
Tue, 04 Jul 2006 12:38:25 +0300 |
Karl Berry <address@hidden> wrote:
> So, would you have time to rework your patch to (1) make
> @allow-recursion give a warning, and (2) make @quote-args the default?
Here it goes:
2006-07-04 Sergey Poznyakoff <address@hidden>
* makeinfo/macro.c (add_macro): Initialize def->argcount
(get_brace_args): Change argument type to enum quote_type.
(All callers updated.) Implement default argument quoting.
(expand_macro): Use def->argcount to control the number of passed
arguments.
(define_macro): Issue a warning if @allow-recursion or @quote-arg
is used.
* makeinfo/macro.h (MACRO_DEF): New member argcount
(enum quote_type): New data type.
(get_brace_args): Change argument type to enum quote_type
(ME_QUOTE_ARG): Remove the macro
* makeinfo/makeinfo.c (cm_ifeq): Update call to get_brace_args
* makeinfo/tests/Makefile.am (TESTS): New test quote-args
(EXTRA_DIST): New file quote-args.txi
* makeinfo/tests/quote-args: New test
* makeinfo/tests/quote-args.txi: New file
* doc/texinfo.txi: Document automatic argument quoting
Index: doc/texinfo.txi
===================================================================
RCS file: /cvsroot/texinfo/texinfo/doc/texinfo.txi,v
retrieving revision 1.166
diff -p -u -r1.166 texinfo.txi
--- doc/texinfo.txi 24 Jun 2006 22:02:28 -0000 1.166
+++ doc/texinfo.txi 4 Jul 2006 09:27:39 -0000
@@ -13768,16 +13768,69 @@ No arguments here.
@end display
@cindex Comma, in macro arguments
+Passing strings, containig commas, as macro arguments requires special
+care, since they should be properly @dfn{quoted} to prevent
address@hidden from confusing them with argument separators.
+To manually quote a comma, prepend it with a backslash character,
+like this: @code{\,}. To facilitate use of macros, @command{makeinfo}
+implements a set of rules called @dfn{automatic quoting}:
+
address@hidden 1
address@hidden If a macro takes only one argument, all commas in its invocation
+are quoted by default. For example:
+
address@hidden
address@hidden
+@@macro address@hidden@}
+@@address@hidden: address@hidden
+@@end macro
+
+@@address@hidden nice feature, though it can be address@hidden
address@hidden group
address@hidden example
+
address@hidden
+will produce the following output
+
address@hidden
address@hidden: A nice feature, though it can be dangerous.}
address@hidden example
+
+And indeed, it can. Namely, @command{makeinfo}
+does not control number of arguments passed to one-argument
+macros, so be careful when you invoke them.
+
address@hidden If a macro calls another macros (possibly itself), any commas in
+the nested macro invocations are quoted by default. Thus, the
+following example:
+
address@hidden
address@hidden
+@@rmacro address@hidden,address@hidden
+\a\\b\
+@@end rmacro
+
+@@address@hidden@@address@hidden, address@hidden, address@hidden
address@hidden group
address@hidden example
+
address@hidden
+will produce the string @samp{foobarbaz}.
+
address@hidden Otherwise, a comma should be explicitely quoted to be taken as
+a part of an argument.
address@hidden enumerate
+
@cindex Braces, in macro arguments
-To insert a comma, brace, or backslash in an argument, prepend a
-backslash, as in
+Other character that need to be quoted in macro arguments are
+curly braces and backslash. For example
@example
@@@var{macname} @address@hidden@}\,@}
@end example
@noindent
-which will pass the (almost certainly error-producing) argument
+will pass the (almost certainly error-producing) argument
@address@hidden@},} to @var{macname}. However, commas in parameters, even
if escaped by a backslash, might cause trouble in @TeX{}.
Index: makeinfo/macro.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/macro.c,v
retrieving revision 1.8
diff -p -u -r1.8 macro.c
--- makeinfo/macro.c 15 May 2005 00:00:07 -0000 1.8
+++ makeinfo/macro.c 4 Jul 2006 09:27:39 -0000
@@ -151,13 +151,14 @@ add_macro (char *name, char **arglist, c
def->source_lineno = source_lineno;
def->body = body;
def->arglist = arglist;
+ def->argcount = array_len (arglist);
def->inhibited = 0;
def->flags = flags;
}
char **
-get_brace_args (int quote_single)
+get_brace_args (enum quote_type quote)
{
char **arglist, *word;
int arglist_index, arglist_size;
@@ -187,8 +188,10 @@ get_brace_args (int quote_single)
depth++;
input_text_offset++;
}
- else if ((character == ',' && !quote_single) ||
- ((character == '}') && depth == 1))
+ else if ((character == ','
+ && !(quote == quote_single
+ || (quote == quote_many && depth > 1)))
+ || ((character == '}') && depth == 1))
{
int len = input_text_offset - start;
@@ -285,7 +288,7 @@ get_macro_args (MACRO_DEF *def)
}
}
}
- return get_brace_args (def->flags & ME_QUOTE_ARG);
+ return get_brace_args (def->argcount == 1 ? quote_single : quote_many);
}
/* Substitute actual parameters for named parameters in body.
@@ -386,17 +389,13 @@ char *
expand_macro (MACRO_DEF *def)
{
char **arglist;
- int num_args;
char *execution_string = NULL;
int start_line = line_number;
- /* Find out how many arguments this macro definition takes. */
- num_args = array_len (def->arglist);
-
/* Gather the arguments present on the line if there are any. */
arglist = get_macro_args (def);
- if (num_args < array_len (arglist))
+ if (def->argcount < array_len (arglist))
{
free_array (arglist);
line_error (_("Macro `%s' called on line %d with too many args"),
@@ -567,12 +566,6 @@ define_macro (char *mactype, int recursi
}
}
}
-
- /* If we have exactly one argument, do @quote-arg implicitly. Not
- only does this match TeX's behavior (which can't feasibly be
- changed), but it's a good idea. */
- if (arglist_index == 1)
- flags |= ME_QUOTE_ARG;
}
/* Read the text carefully until we find an "@end macro" which
@@ -595,6 +588,7 @@ define_macro (char *mactype, int recursi
(strncmp (line + 1, "allow-recursion", 15) == 0) &&
(line[16] == 0 || whitespace (line[16])))
{
+ warning (_("@allow-recursion is deprecated; please use @rmacro
instead"));
for (i = 16; whitespace (line[i]); i++);
strcpy (line, line + i);
flags |= ME_RECURSE;
@@ -609,20 +603,14 @@ define_macro (char *mactype, int recursi
(strncmp (line + 1, "quote-arg", 9) == 0) &&
(line[10] == 0 || whitespace (line[10])))
{
+ warning (_("@quote-arg is deprecated; arguments are quoted by
default"));
for (i = 10; whitespace (line[i]); i++);
strcpy (line, line + i);
-
- if (arglist && arglist[0] && !arglist[1])
- {
- flags |= ME_QUOTE_ARG;
- if (!*line)
- {
- free (line);
- continue;
- }
- }
- else
- line_error (_("@quote-arg only useful for single-argument macros"));
+ if (!*line)
+ {
+ free (line);
+ continue;
+ }
}
if (*line == COMMAND_PREFIX
Index: makeinfo/macro.h
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/macro.h,v
retrieving revision 1.3
diff -p -u -r1.3 macro.h
--- makeinfo/macro.h 15 May 2005 00:00:07 -0000 1.3
+++ makeinfo/macro.h 4 Jul 2006 09:27:39 -0000
@@ -37,16 +37,16 @@ typedef struct {
typedef struct {
char *name; /* Name of the macro. */
char **arglist; /* Args to replace when executing. */
+ int argcount; /* Number of args in arglist */
char *body; /* Macro body. */
char *source_file; /* File where this macro is defined. */
int source_lineno; /* Line number within FILENAME. */
int inhibited; /* Nonzero means make find_macro () fail. */
- int flags; /* ME_RECURSE, ME_QUOTE_ARG, etc. */
+ int flags; /* ME_RECURSE, etc. */
} MACRO_DEF;
/* flags for MACRO_DEF */
#define ME_RECURSE 0x01
-#define ME_QUOTE_ARG 0x02
extern void execute_macro (MACRO_DEF *def);
extern MACRO_DEF *find_macro (char *name);
@@ -72,6 +72,8 @@ extern void cm_alias (void), cm_definfoe
extern int array_len (char **array);
extern void free_array (char **array);
-extern char **get_brace_args (int quote_single);
+
+enum quote_type { quote_none, quote_single, quote_many };
+extern char **get_brace_args (enum quote_type type);
#endif /* not MACRO_H */
Index: makeinfo/makeinfo.c
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/makeinfo.c,v
retrieving revision 1.87
diff -p -u -r1.87 makeinfo.c
--- makeinfo/makeinfo.c 19 Jun 2006 23:08:57 -0000 1.87
+++ makeinfo/makeinfo.c 4 Jul 2006 09:27:42 -0000
@@ -3640,7 +3640,7 @@ cm_ifeq (void)
{
char **arglist;
- arglist = get_brace_args (0);
+ arglist = get_brace_args (quote_none);
if (arglist)
{
Index: makeinfo/tests/Makefile.am
===================================================================
RCS file: /cvsroot/texinfo/texinfo/makeinfo/tests/Makefile.am,v
retrieving revision 1.5
diff -p -u -r1.5 Makefile.am
--- makeinfo/tests/Makefile.am 11 Apr 2004 17:56:47 -0000 1.5
+++ makeinfo/tests/Makefile.am 4 Jul 2006 09:27:42 -0000
@@ -19,6 +19,7 @@ TESTS = accent accentenc \
macro-at menu-whitespace \
no-headers \
node-expand node-value node-whitespace \
+ quote-args \
top \
twofiles
@@ -33,4 +34,5 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
include-value.txi incl-incl.txi \
macro-at.txi menu-whitespace.txi \
node-expand.txi node-value.txi node-whitespace.txi \
+ quote-args.txi \
top.txi # top2.txi
Index: makeinfo/tests/quote-args
--- /dev/null 1994-07-18 02:46:18.000000000 +0300
+++ makeinfo/tests/quote-args 2006-07-04 11:48:04.000000000 +0300
@@ -0,0 +1,19 @@
+#!/bin/sh
+# Test @quote-args facility
+
+: ${srcdir=.}
+
+unset TEXINFO_OUTPUT
+TMP=quote-args.out
+
+cat > quote-args.samp <<EOT
+*FIXME: Many arguments, separated by commas, are processed here*
+natopocotuototam
+
+EOT
+
+../makeinfo --plaintex quote-args.txi | diff - quote-args.samp
+exit_code=$?
+
+rm quote-args.samp
+exit $exit_code
Index: makeinfo/tests/quote-args.txi
--- /dev/null 1994-07-18 02:46:18.000000000 +0300
+++ makeinfo/tests/quote-args.txi 2006-07-04 11:58:03.000000000 +0300
@@ -0,0 +1,20 @@
+\input texinfo
address@hidden
address@hidden quote-args.info
address@hidden Quote-args facility in macros
+
address@hidden cat{a,b}
+\a\\b\
address@hidden rmacro
+
address@hidden FIXME{a}
address@hidden: \a\}
address@hidden macro
+
address@hidden Top, , (dir), (dir)
+
address@hidden
address@hidden arguments, separated by commas, are processed here}
address@hidden@address@hidden@address@hidden@cat{na, to}, po}, co}, tu},
oto},tam}
address@hidden
+
Regards,
Sergey