Support quoting of macro arguments (#222)
Single or double quotes can be used in macro arguments as expected - they denote the begin and the end of the argument. Example with 2-nd and 3-rd argument in double quotes: ./rpm --define "%foo() 1:%1 2:%2 3:%3" \ --eval '%foo Next_argument_will_be_empty "" "Last argument"' 1:Next_argument_will_be_empty 2: 3:Last argument Example with all arguments in single quotes, without spaces between arguments: ./rpm --define "%foo() 1:%1 2:%2 3:%3" \ --eval "%foo 'Next argument will be empty''''Last argument'" 1:Next argument will be empty 2: 3:Last argument
This commit is contained in:
parent
9a9eefc40e
commit
47f0a899ef
|
@ -649,6 +649,61 @@ freeArgs(MacroBuf mb, int delete)
|
|||
mb->level--;
|
||||
}
|
||||
|
||||
/* XXX: belongs to argv.c but figure a sensible API before making public */
|
||||
static ARGV_t argvSplitShell(const char * str, const char * seps)
|
||||
{
|
||||
char *dest = NULL;
|
||||
ARGV_t argv;
|
||||
int argc = 1;
|
||||
const char * s;
|
||||
char * t;
|
||||
int c;
|
||||
int quote;
|
||||
|
||||
if (str == NULL || seps == NULL)
|
||||
return NULL;
|
||||
|
||||
dest = xmalloc(strlen(str) + 1);
|
||||
t = dest;
|
||||
s = str;
|
||||
argc = 1;
|
||||
|
||||
while ((c = *s)) {
|
||||
if (strchr(seps, c)) {
|
||||
s++;
|
||||
} else {
|
||||
if (!strchr("\"\'",c)) {
|
||||
/* read argument not in "" or ''*/
|
||||
for (; (c = *s); s++, t++) {
|
||||
if (strchr(seps, c) || strchr("\"\'",c))
|
||||
break;
|
||||
*t = c;
|
||||
}
|
||||
} else {
|
||||
/* read argument in "" or '' */
|
||||
quote = *s;
|
||||
s++;
|
||||
for (; (c = *s) && (c != quote); t++,s++)
|
||||
*t = c;
|
||||
s++;
|
||||
}
|
||||
*t = '\0';
|
||||
t++;
|
||||
argc++;
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
argv = xmalloc((argc + 1) * sizeof(*argv));
|
||||
for (c = 0, s = dest; s < t; s+= strlen(s) + 1) {
|
||||
argv[c] = xstrdup(s);
|
||||
c++;
|
||||
}
|
||||
argv[c] = NULL;
|
||||
free(dest);
|
||||
return argv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse arguments (to next new line) for parameterized macro.
|
||||
* @todo Use popt rather than getopt to parse args.
|
||||
|
@ -685,7 +740,7 @@ grabArgs(MacroBuf mb, const rpmMacroEntry me, const char * se,
|
|||
expandThis(mb, se, lastc-se, &s);
|
||||
mb->escape = oescape;
|
||||
|
||||
argvSplit(&av, s, " \t");
|
||||
av = argvSplitShell(s, " \t");
|
||||
argvAppend(&argv, av);
|
||||
argvFree(av);
|
||||
free(s);
|
||||
|
|
|
@ -267,3 +267,66 @@ runroot rpm \
|
|||
[error: lua script failed: [[string "<lua>"]]:1: exit not permitted in this context]
|
||||
)
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([macro arguments in double quotes])
|
||||
AT_KEYWORDS([macros arguments])
|
||||
AT_CHECK([
|
||||
runroot rpm --define "%foo() 1:%1 2:%2" --eval '%foo "argument 1" argument_2'
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval '%foo "argument 1" argument_2 """"""'
|
||||
|
||||
runroot rpm \
|
||||
--define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval '%foo "arg. number 1""arg. number 2" "arg number 3" "" normal'
|
||||
|
||||
runroot rpm \
|
||||
--define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval '%foo "arg. number 1"normal"arg. number 2" '
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval '%foo """jjj"""aa"" '
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" --eval '%foo xx"yy""zz""""bb" '
|
||||
],
|
||||
[0],
|
||||
[1:argument 1 2:argument_2
|
||||
1:argument 1 2:argument_2 3: 4: 5:
|
||||
1:arg. number 1 2:arg. number 2 3:arg number 3 4: 5:normal
|
||||
1:arg. number 1 2:normal 3:arg. number 2 4:%4 5:%5
|
||||
1: 2:jjj 3: 4:aa 5:
|
||||
1:xx 2:yy 3:zz 4: 5:bb
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([macro arguments in single + double quotes])
|
||||
AT_KEYWORDS([macros arguments])
|
||||
AT_CHECK([
|
||||
|
||||
runroot rpm \
|
||||
--define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval "%foo 'arg. number 1''arg. number 2' 'arg number 3' '' normal"
|
||||
|
||||
runroot rpm \
|
||||
--define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval "%foo 'arg. number 1'normal'arg. number 2'''normal "
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval "%foo '''jjj'''aa'' "
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" \
|
||||
--eval "%foo ''\"jjj\"''aa\"\" "
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" --eval "%foo xx'yy''zz''''bb' "
|
||||
|
||||
runroot rpm --define "%foo() 1:%1 2:%2 3:%3 4:%4 5:%5" --eval "%foo xx'yy'\"zz\"\"\"'bb' "
|
||||
],
|
||||
[0],
|
||||
[1:arg. number 1 2:arg. number 2 3:arg number 3 4: 5:normal
|
||||
1:arg. number 1 2:normal 3:arg. number 2 4: 5:normal
|
||||
1: 2:jjj 3: 4:aa 5:
|
||||
1: 2:jjj 3: 4:aa 5:
|
||||
1:xx 2:yy 3:zz 4: 5:bb
|
||||
1:xx 2:yy 3:zz 4: 5:bb
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
|
Loading…
Reference in New Issue