• R/O
  • SSH
  • HTTPS

yash: Commit


Commit MetaInfo

Revision3820 (tree)
Time2018-01-13 17:52:44
Authormagicant

Log Message

Don't quote printed words too redundantly

This commit replaces the quote_sq' function with the new
quote_as_word function, which does not quote if the argument is a
portable filename. It would render a better quoting results when used
for xtrace.

Change Summary

Incremental Difference

--- yash/trunk/lineedit/keymap.c (revision 3819)
+++ yash/trunk/lineedit/keymap.c (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* keymap.c: mappings from keys to functions */
3-/* (C) 2007-2012 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -546,7 +546,7 @@
546546 format = "bindkey -%c -- %ls %s\n";
547547 else
548548 format = "bindkey -%c %ls %s\n";
549- keyseqquote = quote_sq(keyseq);
549+ keyseqquote = quote_as_word(keyseq);
550550 commandname = get_command_name(cmd);
551551 xprintf(format, modechar, keyseqquote, commandname);
552552 free(keyseqquote);
--- yash/trunk/sig.c (revision 3819)
+++ yash/trunk/sig.c (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* sig.c: signal handling */
3-/* (C) 2007-2017 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -1249,7 +1249,7 @@
12491249 if (command == NULL)
12501250 return true;
12511251
1252- wchar_t *q = quote_sq(command);
1252+ wchar_t *q = quote_as_word(command);
12531253 bool ok = xprintf("trap -- %ls %ls\n", q, signame);
12541254 free(q);
12551255 return ok;
--- yash/trunk/expand.c (revision 3819)
+++ yash/trunk/expand.c (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* expand.c: word expansion */
3-/* (C) 2007-2017 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -1659,22 +1659,59 @@
16591659 }
16601660 }
16611661
1662-/* Quotes the specified string by single quotes.
1663- * If the string contains single quotes, they are backslashed. */
1664-wchar_t *quote_sq(const wchar_t *s)
1662+/* Quotes the specified string using backslashes and single-quotes. The result
1663+ * is suitable for re-parsing as a shell command word that would expand to the
1664+ * original string. The result is a newly malloced string. */
1665+wchar_t *quote_as_word(const wchar_t *s)
16651666 {
16661667 xwcsbuf_T buf;
16671668 wb_init(&buf);
1668- wb_wccat(&buf, L'\'');
1669- for (size_t i = 0; s[i] != L'\0'; i++) {
1670- if (s[i] != L'\'') {
1671- wb_wccat(&buf, s[i]);
1672- } else {
1673- wb_ncat_force(&buf, L"'\\''", 4);
1669+ wb_quote_as_word(&buf, s);
1670+ return wb_towcs(&buf);
1671+}
1672+
1673+/* Quotes string `s' using backslashes and single-quotes. The result
1674+ * is suitable for re-parsing as a shell command word that would expand to the
1675+ * original string. The result is appended to the given buffer, which must
1676+ * have been initialized before calling this function. */
1677+xwcsbuf_T *wb_quote_as_word(xwcsbuf_T *restrict buf, const wchar_t *restrict s)
1678+{
1679+ if (*s == L'\0') {
1680+ wb_wccat(buf, L'\'');
1681+ wb_wccat(buf, L'\'');
1682+ return buf;
1683+ }
1684+
1685+ while (*s != L'\0') {
1686+ if (*s == L'\'') {
1687+ wb_wccat(buf, L'\\');
1688+ wb_wccat(buf, L'\'');
1689+ s++;
1690+ continue;
16741691 }
1692+
1693+ const wchar_t *end = s;
1694+ while (*end == L'.' || *end == L'-' || *end == L'_' || *end == L'/' ||
1695+ iswalnum(*end))
1696+ end++;
1697+ if (*end == L'\0' || *end == L'\'') {
1698+ /* No characters have to be quoted until `*end'. */
1699+ wb_ncat_force(buf, s, end - s);
1700+ s = end;
1701+ continue;
1702+ }
1703+
1704+ /* Quote characters until the next single-quote or end-of-string. */
1705+ wb_ensuremax(buf, buf->length + (end - s) + 2);
1706+ wb_wccat(buf, L'\'');
1707+ while (*s != L'\0' && *s != L'\'') {
1708+ wb_wccat(buf, *s);
1709+ s++;
1710+ }
1711+ wb_wccat(buf, L'\'');
16751712 }
1676- wb_wccat(&buf, L'\'');
1677- return wb_towcs(&buf);
1713+
1714+ return buf;
16781715 }
16791716
16801717 /* Removes quotes (', ", \). The result is a newly malloced string. */
--- yash/trunk/expand.h (revision 3819)
+++ yash/trunk/expand.h (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* expand.h: word expansion */
3-/* (C) 2007-2016 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -56,6 +56,7 @@
5656 struct plist_T *restrict dest)
5757 __attribute__((nonnull));
5858
59+struct xwcsbuf_T;
5960 extern wchar_t *escape(const wchar_t *restrict s, const wchar_t *restrict t)
6061 __attribute__((nonnull(1),malloc,warn_unused_result));
6162 extern wchar_t *escapefree(
@@ -65,8 +66,11 @@
6566 __attribute__((nonnull,malloc,warn_unused_result));
6667 extern wchar_t *unescapefree(wchar_t *s)
6768 __attribute__((nonnull,malloc,warn_unused_result));
68-extern wchar_t *quote_sq(const wchar_t *s)
69+extern wchar_t *quote_as_word(const wchar_t *s)
6970 __attribute__((nonnull,malloc,warn_unused_result));
71+extern struct xwcsbuf_T *wb_quote_as_word(
72+ struct xwcsbuf_T *restrict buf, const wchar_t *restrict s)
73+ __attribute__((nonnull));
7074 extern wchar_t *unquote(const wchar_t *s)
7175 __attribute__((nonnull,malloc,warn_unused_result));
7276
--- yash/trunk/variable.c (revision 3819)
+++ yash/trunk/variable.c (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* variable.c: deals with shell variables and parameters */
3-/* (C) 2007-2017 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -1775,7 +1775,7 @@
17751775 return;
17761776
17771777 if (!is_name(name))
1778- name = qname = quote_sq(name);
1778+ name = qname = quote_as_word(name);
17791779
17801780 switch (var->v_type & VF_MASK) {
17811781 case VF_SCALAR:
@@ -1802,7 +1802,7 @@
18021802 xstrbuf_T opts;
18031803
18041804 if (var->v_value != NULL)
1805- quotedvalue = quote_sq(var->v_value);
1805+ quotedvalue = quote_as_word(var->v_value);
18061806 else
18071807 quotedvalue = NULL;
18081808 switch (argv0[0]) {
@@ -1848,7 +1848,7 @@
18481848 return;
18491849 if (var->v_valc > 0) {
18501850 for (size_t i = 0; ; ) {
1851- wchar_t *qvalue = quote_sq(var->v_vals[i]);
1851+ wchar_t *qvalue = quote_as_word(var->v_vals[i]);
18521852 bool ok = xprintf("%ls", qvalue);
18531853 free(qvalue);
18541854 if (!ok)
@@ -1905,7 +1905,7 @@
19051905
19061906 wchar_t *qname = NULL;
19071907 if (!is_name(name))
1908- name = qname = quote_sq(name);
1908+ name = qname = quote_as_word(name);
19091909
19101910 wchar_t *value = command_to_wcs(func->f_body, true);
19111911 const char *format = (qname == NULL) ? "%ls()\n%ls" : "function %ls()\n%ls";
--- yash/trunk/alias.c (revision 3819)
+++ yash/trunk/alias.c (revision 3820)
@@ -1,6 +1,6 @@
11 /* Yash: yet another shell */
22 /* alias.c: alias substitution */
3-/* (C) 2007-2017 magicant */
3+/* (C) 2007-2018 magicant */
44
55 /* This program is free software: you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
@@ -362,7 +362,7 @@
362362 * Returns true iff successful. */
363363 bool print_alias(const wchar_t *name, const alias_T *alias, bool prefix)
364364 {
365- wchar_t *qvalue = quote_sq(alias->value);
365+ wchar_t *qvalue = quote_as_word(alias->value);
366366 const char *format;
367367 bool success;
368368
--- yash/trunk/NEWS (revision 3819)
+++ yash/trunk/NEWS (revision 3820)
@@ -8,6 +8,12 @@
88 x: new bug
99
1010 ----------------------------------------------------------------------
11+Yash 2.47
12+
13+ = When the shell prints aliases, variables, key bindings, etc. they
14+ are now printed with less quotes.
15+
16+----------------------------------------------------------------------
1117 Yash 2.46
1218
1319 = Global aliases are now substituted in all locations, including
Show on old repository browser