Fix some issues with quoted output and shorten it in some cases.

Output quoted suitable for re-input to the shell occurs in
various cases such as 'set', 'trap'.

Bugfix: *, ? and [ must be quoted (except sole [)
Bugfix: ~ and # must be quoted (really only sometimes, but keep it simple)
Bugfix: space, tab and newline must always be quoted
Shortening: other IFS characters do not need quoting
Bugfix: send to correct output file, not hard-coded stdout
Shortening: avoid unnecessary '' with \'

Approved by:	ed (mentor)
This commit is contained in:
Jilles Tjoelker 2009-06-19 22:09:55 +00:00
parent 5b204a113c
commit e68165a6bb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194516

View File

@ -133,32 +133,38 @@ void
outqstr(const char *p, struct output *file)
{
char ch;
int inquotes;
if (p[0] == '\0') {
outstr("''", file);
return;
}
if (p[strcspn(p, "|&;<>()$`\\\"'")] == '\0' && (!ifsset() ||
p[strcspn(p, ifsval())] == '\0')) {
/* Caller will handle '=' if necessary */
if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#")] == '\0' ||
strcmp(p, "[") == 0) {
outstr(p, file);
return;
}
out1c('\'');
inquotes = 0;
while ((ch = *p++) != '\0') {
switch (ch) {
case '\'':
/*
* Can't quote single quotes inside single quotes;
* close them, write escaped single quote, open again.
*/
outstr("'\\''", file);
/* Can't quote single quotes inside single quotes. */
if (inquotes)
outc('\'', file);
inquotes = 0;
outstr("\\'", file);
break;
default:
if (!inquotes)
outc('\'', file);
inquotes = 1;
outc(ch, file);
}
}
out1c('\'');
if (inquotes)
outc('\'', file);
}
STATIC char out_junk[16];