1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
From 458d69d8f10d582fd7a546eabc1b555bb7337627 Mon Sep 17 00:00:00 2001
From: Alexander Polakov <polachok@gmail.com>
Date: Sun, 29 May 2011 16:05:58 +0400
Subject: [PATCH 6/8] ksh: remove backslashes in filenames using lex.
* this also removes the check for matching pattern and
returned filename. if it returns 1 name, then it must
be the filename of an existing file, right? i think
so.
* change stat() to lstat() to complete broken links
(from LEVAI Daniel).
Why:
* less ugly code
* working completion for special characters like [], () and so
* suggested by martynas
---
edit.c | 31 +++++++------------------------
lex.c | 4 ++++
lex.h | 1 +
3 files changed, 12 insertions(+), 24 deletions(-)
diff --git edit.c edit.c
index 9cdcc6d..01c2fe6 100644
--- edit.c
+++ edit.c
@@ -351,7 +351,7 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp)
{
char *toglob;
char **words;
- int nwords, i, idx, escaping;
+ int nwords;
XPtrV w;
struct source *s, *sold;
@@ -360,20 +360,6 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp)
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)
*/
@@ -381,7 +367,7 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp)
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;
@@ -397,15 +383,12 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp)
if (nwords == 1) {
struct stat statb;
- /* Check if globbing failed (returned glob pattern),
- * but be careful (E.g. toglob == "ab*" when the file
- * "ab*" exists is not an error).
- * Also, check for empty result - happens if we tried
- * to glob something which evaluated to an empty
- * string (e.g., "$FOO" when there is no FOO, etc).
+ /* Check if file exists, also, check for empty
+ * result - happens if we tried to glob something
+ * which evaluated to an empty string (e.g.,
+ * "$FOO" when there is no FOO, etc).
*/
- if ((strcmp(words[0], toglob) == 0 &&
- stat(words[0], &statb) < 0) ||
+ if((lstat(words[0], &statb) < 0) ||
words[0][0] == '\0') {
x_free_words(nwords, words);
words = NULL;
diff --git lex.c lex.c
index ef741c6..fe3d91d 100644
--- lex.c
+++ lex.c
@@ -299,6 +299,10 @@ yylex(int cf)
}
/* FALLTHROUGH */
default:
+ if (cf & RMBKSLSH) {
+ *wp++ = QCHAR, *wp++ = c;
+ break;
+ }
Xcheck(ws, wp);
if (c) { /* trailing \ is lost */
*wp++ = CHAR, *wp++ = '\\';
diff --git lex.h lex.h
index 0904fbd..6a0dbf9 100644
--- lex.h
+++ lex.h
@@ -113,6 +113,7 @@ typedef union {
#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 */
--
1.7.5
|