##
##  rpm-4.0.2.patch.bugfix -- Annotated patch file
##  Copyright (c) 2000-2001 Cable & Wireless Deutschland GmbH
##  Copyright (c) 2000-2001 Ralf S. Engelschall <rse.com>
##
##  This file assembles changes to existing RPM source files between
##  the original RedHat RPM and the OpenPKG RPM variant. It can be
##  automatically applied to a vanilla RedHat RPM source tree with the
##  'patch' tool to upgrade those files. Each patch snippet is annotated
##  with a short description.
##
##  Created on: 23-Sep-2001
##

+---------------------------------------------------------------------------
| First, remove incorrectly introduced buffer assignment. Second, fix
| second and subsequent "%{foo -x}" constructs. Without resetting
| the option index only the first construct works. Third, bugfix
| the handling of macros inside macro arguments as in "%{foo
| bar%{quux}baz}". RPM correctly determined the pointer to the
| terminating second(1) closing brace, but instead of passing
| this pointer to the subroutine which handles the macro argument
| construction, it passed the underlying character. This in turn
| obviously leaded to an incorrect determination of the argument end
| (it then though the first closing brace is the end). We fix this by
| passing the pointer and not the underlying character.
+---------------------------------------------------------------------------
Index: rpmio/macro.c
--- rpmio/macro.c	2001/01/19 01:47:25	1.1.1.2
+++ rpmio/macro.c	2001/09/20 09:58:20	1.6
@@ -746,7 +746,7 @@
  * @return		address to continue parsing
  */
 /*@dependent@*/ static const char *
-grabArgs(MacroBuf *mb, const MacroEntry *me, const char *se, char lastc)
+grabArgs(MacroBuf *mb, const MacroEntry *me, const char *se, char *lastc)
 {
     char buf[BUFSIZ], *b, *be;
     char aname[16];
@@ -764,7 +764,7 @@
 
     /* Copy args into buf until lastc */
     *be++ = ' ';
-    while ((c = *se++) != '\0' && c != lastc) {
+    while ((c = *se++) != '\0' && (se-1) != lastc) {
 	if (!isblank(c)) {
 	    *be++ = c;
 	    continue;
@@ -801,7 +801,7 @@
     /* Build argv array */
     argv = (const char **) alloca((argc + 1) * sizeof(char *));
     be[-1] = ' ';	/*  be - 1 == b + strlen(b) == buf + strlen(buf)  */
-    buf[0] = '\0';
+    be[0] = '\0';
     b = buf;
     for (c = 0; c < argc; c++) {
 	argv[c] = b;
@@ -814,6 +814,15 @@
     opts = me->opts;
 
     /* Define option macros. */
+#ifdef __GLIBC__
+    /* set to value of 0 instead of 1, because internally GNU libc
+       increases it to 1 implicitly, but additionally performs the
+       necessary full initialization. Without this the option parsing
+       will horribly break under Linux and various circumstances. */
+    optind = 0;
+#else
+    optind = 1;
+#endif
     while((c = getopt(argc, (char **)argv, opts)) != -1) {
 	if (c == '?' || (o = strchr(opts, c)) == NULL) {
 	    rpmError(RPMERR_BADSPEC, _("Unknown option %c in %s(%s)\n"),
@@ -991,7 +1000,7 @@
     int c;
     int rc = 0;
     int negate;
-    char grab;
+    char *grab;
     int chkexist;
 
     if (++mb->depth > max_macro_depth) {
@@ -1024,7 +1033,7 @@
 	if (mb->depth > 1)	/* XXX full expansion for outermost level */
 		t = mb->t;	/* save expansion pointer for printExpand */
 	negate = 0;
-	grab = '\0';
+	grab = NULL;
 	chkexist = 0;
 	switch ((c = *s)) {
 	default:		/* %name substitution */
@@ -1058,7 +1067,8 @@
 		fe = se;
 		/* For "%name " macros ... */
 		if ((c = *fe) && isblank(c))
-			grab = '\n';
+                        if ((grab = strchr(fe, '\n')) == NULL)
+                            grab = strchr(fe, '\0');
 		break;
 	case '(':		/* %(...) shell escape */
 		if ((se = matchchar(s, c, ')')) == NULL) {
@@ -1104,7 +1114,7 @@
 			ge = se - 1;
 			break;
 		case ' ':
-			grab = se[-1];
+			grab = se-1;
 			break;
 		default:
 			break;
