* LEVAI Daniel <l...@ecentrum.hu> [110510 14:33]:
> On Tue, May 10, 2011 at 12:28:06 +0200, LEVAI Daniel wrote:
> > On Tue, May 10, 2011 at 08:41:48 +0200, LEVAI Daniel wrote:
> > > On Mon, May 09, 2011 at 23:48:46 +0400, Alexander Polakov wrote:
> > > > * Alexander Polakov <polac...@gmail.com> [110502 18:19]:
> > > > > Do you mean something like this or I got it all wrong again and we
> > > > > have to wait another 15 years for someone to dig into this?
> > > > 
> > > > That diff was wrong, this one is likely less wrong.
> > > This is working fine for me.
> > 
> > I've just found a usecase where it fails to complete a filename:
> > 
> > $ touch 'aaa: bbb ccc'
> > $ touch 'aaa: bbc ddd'
> > $ ls -la a<TAB>
> > $ ls -la aaa:\ bb<TAB>
> > aaa: bbb ccc   aaa: bbc ddd
> > $ ls -la aaa:\ bbc<TAB>
> >   ^^^ nothing happens
> Apperantly, adding ':' to ESCAPEDCHARS solves the problem. Do you think
> there is any sideeffect to this?

No, I don't think so. Let's just add it and find out in practice.

Index: bin/ksh/edit.c
===================================================================
RCS file: /cvs/src/bin/ksh/edit.c,v
retrieving revision 1.34
diff -u -r1.34 edit.c
--- bin/ksh/edit.c      20 May 2010 01:13:07 -0000      1.34
+++ bin/ksh/edit.c      10 May 2011 10:48:26 -0000
@@ -357,20 +357,6 @@
 
        toglob = add_glob(str, slen);
 
-       /* remove all escaping backward slashes */
-       escaping = 0;
-       for (i = 0, idx = 0; toglob[i]; i++) {
-               if (toglob[i] == '\\' && !escaping) {
-                       escaping = 1;
-                       continue;
-               }
-
-               toglob[idx] = toglob[i];
-               idx++;
-               if (escaping) escaping = 0;
-       }
-       toglob[idx] = '\0';
-
        /*
         * Convert "foo*" (toglob) to an array of strings (words)
         */
@@ -378,7 +364,7 @@
        s = pushs(SWSTR, ATEMP);
        s->start = s->str = toglob;
        source = s;
-       if (yylex(ONEWORD) != LWORD) {
+       if (yylex(ONEWORD|RMBKSLSH) != LWORD) {
                source = sold;
                internal_errorf(0, "fileglob: substitute error");
                return 0;
@@ -394,6 +380,20 @@
        if (nwords == 1) {
                struct stat statb;
 
+               /* remove all escaping backward slashes (see below) */
+               escaping = 0;
+               for (i = 0, idx = 0; toglob[i]; i++) {
+                       if (toglob[i] == '\\' && !escaping) {
+                               escaping = 1;
+                               continue;
+                       }
+
+                       toglob[idx] = toglob[i];
+                       idx++;
+                       if (escaping) escaping = 0;
+               }
+               toglob[idx] = '\0';
+
                /* Check if globbing failed (returned glob pattern),
                 * but be careful (E.g. toglob == "ab*" when the file
                 * "ab*" exists is not an error).
@@ -821,7 +821,7 @@
        int rval = 0;
 
        for (add = 0, wlen = len; wlen - add > 0; add++) {
-               if (strchr("\"#$&'()*;<=>?[\\]`{|}", s[add]) ||
+               if (strchr(ESCAPEDCHARS, s[add]) ||
                    strchr(ifs, s[add])) {
                        if (putbuf_func(s, add) != 0) {
                                rval = -1;
Index: bin/ksh/lex.c
===================================================================
RCS file: /cvs/src/bin/ksh/lex.c,v
retrieving revision 1.45
diff -u -r1.45 lex.c
--- bin/ksh/lex.c       9 Mar 2011 09:30:39 -0000       1.45
+++ bin/ksh/lex.c       10 May 2011 10:48:26 -0000
@@ -299,6 +299,10 @@
                                        }
                                        /* FALLTHROUGH */
                                default:
+                                       if ((cf & RMBKSLSH) && strchr(" " 
ESCAPEDCHARS, c)) {
+                                               *wp++ = QCHAR, *wp++ = c;
+                                               break;
+                                       }
                                        Xcheck(ws, wp);
                                        if (c) { /* trailing \ is lost */
                                                *wp++ = CHAR, *wp++ = '\\';
Index: bin/ksh/lex.h
===================================================================
RCS file: /cvs/src/bin/ksh/lex.h,v
retrieving revision 1.11
diff -u -r1.11 lex.h
--- bin/ksh/lex.h       29 May 2006 18:22:24 -0000      1.11
+++ bin/ksh/lex.h       10 May 2011 10:48:26 -0000
@@ -113,6 +113,7 @@
 #define CMDWORD BIT(8)         /* parsing simple command (alias related) */
 #define HEREDELIM BIT(9)       /* parsing <<,<<- delimiter */
 #define HEREDOC BIT(10)                /* parsing heredoc */
+#define RMBKSLSH BIT(11)       /* remove backslashes */
 
 #define        HERES   10              /* max << in line */
 
Index: bin/ksh/sh.h
===================================================================
RCS file: /cvs/src/bin/ksh/sh.h,v
retrieving revision 1.30
diff -u -r1.30 sh.h
--- bin/ksh/sh.h        4 Jan 2010 18:07:11 -0000       1.30
+++ bin/ksh/sh.h        10 May 2011 10:48:26 -0000
@@ -398,6 +398,9 @@
 #define OBRACE '{'
 #define CBRACE '}'
 
+/* Characters to be escaped */
+#define ESCAPEDCHARS "\"#$&'()*:;<=>?[\\]`{|}"
+
 /* Determine the location of the system (common) profile */
 #define KSH_SYSTEM_PROFILE "/etc/profile"
 

-- 
Alexander Polakov | plhk.ru

Reply via email to