]> git.ipfire.org Git - thirdparty/bash.git/blame - bracecomp.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / bracecomp.c
CommitLineData
726f6388
JA
1/* bracecomp.c -- Complete a filename with the possible completions enclosed
2 in csh-style braces such that the list of completions is available to the
3 shell. */
4
5/* Original version by tromey@cns.caltech.edu, Fri Feb 7 1992. */
6
3185942a 7/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
726f6388
JA
8
9 This file is part of GNU Bash, the Bourne Again SHell.
10
3185942a
JA
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
726f6388 15
3185942a
JA
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
726f6388 20
3185942a
JA
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23*/
726f6388 24
ccc6cda3 25#include "config.h"
3185942a 26
ccc6cda3
JA
27#if defined (BRACE_EXPANSION) && defined (READLINE)
28
726f6388
JA
29#include <stdio.h>
30
ccc6cda3 31#if defined (HAVE_UNISTD_H)
cce855bc
JA
32# ifdef _MINIX
33# include <sys/types.h>
34# endif
ccc6cda3
JA
35# include <unistd.h>
36#endif
37
d166f048 38#include "bashansi.h"
3185942a 39#include "shmbutil.h"
726f6388
JA
40
41#include "shell.h"
42#include <readline/readline.h>
43
3185942a
JA
44static int _strcompare __P((char **, char **));
45
726f6388
JA
46/* Find greatest common prefix of two strings. */
47static int
48string_gcd (s1, s2)
49 char *s1, *s2;
50{
51 register int i;
52
53 if (s1 == NULL || s2 == NULL)
54 return (0);
55
56 for (i = 0; *s1 && *s2; ++s1, ++s2, ++i)
57 {
58 if (*s1 != *s2)
59 break;
60 }
61
62 return (i);
63}
64
65static char *
66really_munge_braces (array, real_start, real_end, gcd_zero)
67 char **array;
68 int real_start, real_end, gcd_zero;
69{
70 int start, end, gcd;
e8ce775d
JA
71 char *result, *subterm, *x;
72 int result_size, flag, tlen;
726f6388
JA
73
74 flag = 0;
75
76 if (real_start == real_end)
77 {
ac50fbac
CR
78 x = array[real_start] ? sh_backslash_quote (array[real_start] + gcd_zero, 0, 0)
79 : sh_backslash_quote (array[0], 0, 0);
e8ce775d 80 return x;
726f6388
JA
81 }
82
f73dda09 83 result = (char *)xmalloc (result_size = 16);
726f6388
JA
84 *result = '\0';
85
86 for (start = real_start; start < real_end; start = end + 1)
87 {
88 gcd = strlen (array[start]);
89 for (end = start + 1; end < real_end; end++)
90 {
91 int temp;
92
93 temp = string_gcd (array[start], array[end]);
94
95 if (temp <= gcd_zero)
96 break;
97
98 gcd = temp;
99 }
100 end--;
101
102 if (gcd_zero == 0 && start == real_start && end != (real_end - 1))
103 {
104 /* In this case, add in a leading '{', because we are at
105 top level, and there isn't a consistent prefix. */
106 result_size += 1;
f73dda09 107 result = (char *)xrealloc (result, result_size);
d166f048 108 result[0] = '{'; result[1] = '\0';
726f6388
JA
109 flag++;
110 }
111
e8ce775d
JA
112 /* Make sure we backslash quote every substring we insert into the
113 resultant brace expression. This is so the default filename
114 quoting function won't inappropriately quote the braces. */
726f6388 115 if (start == end)
e8ce775d
JA
116 {
117 x = savestring (array[start] + gcd_zero);
ac50fbac 118 subterm = sh_backslash_quote (x, 0, 0);
e8ce775d
JA
119 free (x);
120 }
726f6388
JA
121 else
122 {
123 /* If there is more than one element in the subarray,
e8ce775d
JA
124 insert the (quoted) prefix and an opening brace. */
125 tlen = gcd - gcd_zero;
f73dda09 126 x = (char *)xmalloc (tlen + 1);
e8ce775d
JA
127 strncpy (x, array[start] + gcd_zero, tlen);
128 x[tlen] = '\0';
ac50fbac 129 subterm = sh_backslash_quote (x, 0, 0);
e8ce775d
JA
130 free (x);
131 result_size += strlen (subterm) + 1;
f73dda09 132 result = (char *)xrealloc (result, result_size);
e8ce775d
JA
133 strcat (result, subterm);
134 free (subterm);
726f6388
JA
135 strcat (result, "{");
136 subterm = really_munge_braces (array, start, end + 1, gcd);
137 subterm[strlen (subterm) - 1] = '}';
138 }
139
140 result_size += strlen (subterm) + 1;
f73dda09 141 result = (char *)xrealloc (result, result_size);
726f6388
JA
142 strcat (result, subterm);
143 strcat (result, ",");
144 free (subterm);
145 }
146
147 if (gcd_zero == 0)
148 result[strlen (result) - 1] = flag ? '}' : '\0';
149 return (result);
150}
151
3185942a
JA
152static int
153_strcompare (s1, s2)
154 char **s1, **s2;
155{
156 int result;
157
158 result = **s1 - **s2;
159 if (result == 0)
160 result = strcmp (*s1, *s2);
161
162 return result;
163}
164
28ef6c31 165static int
726f6388
JA
166hack_braces_completion (names)
167 char **names;
168{
169 register int i;
170 char *temp;
171
3185942a
JA
172 i = strvec_len (names);
173 if (MB_CUR_MAX > 1 && i > 2)
174 qsort (names+1, i-1, sizeof (char *), (QSFUNC *)_strcompare);
175
176 temp = really_munge_braces (names, 1, i, 0);
726f6388
JA
177
178 for (i = 0; names[i]; ++i)
179 {
180 free (names[i]);
181 names[i] = NULL;
182 }
183 names[0] = temp;
28ef6c31 184 return 0;
726f6388
JA
185}
186
e8ce775d
JA
187/* We handle quoting ourselves within hack_braces_completion, so we turn off
188 rl_filename_quoting_desired and rl_filename_quoting_function. */
28ef6c31
JA
189int
190bash_brace_completion (count, ignore)
191 int count, ignore;
726f6388 192{
28ef6c31
JA
193 rl_compignore_func_t *orig_ignore_func;
194 rl_compentry_func_t *orig_entry_func;
195 rl_quote_func_t *orig_quoting_func;
196 rl_completion_func_t *orig_attempt_func;
197 int orig_quoting_desired, r;
726f6388
JA
198
199 orig_ignore_func = rl_ignore_some_completions_function;
200 orig_attempt_func = rl_attempted_completion_function;
201 orig_entry_func = rl_completion_entry_function;
e8ce775d
JA
202 orig_quoting_func = rl_filename_quoting_function;
203 orig_quoting_desired = rl_filename_quoting_desired;
726f6388 204
28ef6c31
JA
205 rl_completion_entry_function = rl_filename_completion_function;
206 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
207 rl_ignore_some_completions_function = hack_braces_completion;
208 rl_filename_quoting_function = (rl_quote_func_t *)NULL;
e8ce775d 209 rl_filename_quoting_desired = 0;
726f6388 210
28ef6c31 211 r = rl_complete_internal (TAB);
726f6388
JA
212
213 rl_ignore_some_completions_function = orig_ignore_func;
214 rl_attempted_completion_function = orig_attempt_func;
215 rl_completion_entry_function = orig_entry_func;
e8ce775d
JA
216 rl_filename_quoting_function = orig_quoting_func;
217 rl_filename_quoting_desired = orig_quoting_desired;
28ef6c31
JA
218
219 return r;
726f6388 220}
ccc6cda3 221#endif /* BRACE_EXPANSION && READLINE */