]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/input.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / db / input.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include <signal.h>
35 #include "command.h"
36 #include "input.h"
37 #include "output.h"
38 #include "sig.h"
39 #include "malloc.h"
40 #include "init.h"
41
42 #ifdef ENABLE_READLINE
43 # include <readline/history.h>
44 # include <readline/readline.h>
45 #endif
46
47 int inputstacksize;
48 FILE **inputstack;
49 FILE *curinput;
50
51 static void popfile(void);
52 static int source_f(int argc, char **argv);
53
54 static const cmdinfo_t source_cmd =
55 { "source", NULL, source_f, 1, 1, 0, "source-file",
56 "get commands from source-file", NULL };
57
58 /* our homegrown strtok that understands strings */
59
60 static char *
61 tokenize(
62 char *inp)
63 {
64 static char *last_place = NULL;
65 char *start;
66 char *walk;
67 int in_string = 0;
68 int in_escape = 0;
69
70 if (inp) {
71 start = inp;
72 } else {
73 if (last_place == NULL)
74 return NULL;
75
76 /* we're done */
77 if (*last_place != '\0')
78 return NULL;
79
80 start = last_place + 1;
81 }
82 last_place = NULL;
83
84 /* eat whitespace */
85 while (*start == ' ' || *start == '\t')
86 start++;
87
88 walk = start;
89 for (;*walk != '\0'; walk++) {
90 if (in_escape) {
91 in_escape = 0;
92 continue;
93 }
94 if (*walk == '\\')
95 in_escape = 1;
96 else if (*walk == '\"')
97 in_string ^= 1;
98
99 if (!in_string && !in_escape &&
100 (*walk == ' ' || *walk == '\t')) {
101 last_place = walk;
102 *last_place = '\0';
103 break;
104 }
105 }
106 if (walk == start)
107 return NULL;
108
109 return start;
110 }
111
112 char **
113 breakline(
114 char *input,
115 int *count)
116 {
117 int c;
118 char *inp;
119 char *p;
120 char **rval;
121
122 c = 0;
123 inp = input;
124 rval = xcalloc(sizeof(char *), 1);
125 for (;;) {
126
127 p = tokenize(inp);
128
129 if (p == NULL)
130 break;
131 inp = NULL;
132 c++;
133 rval = xrealloc(rval, sizeof(*rval) * (c + 1));
134 rval[c - 1] = p;
135 rval[c] = NULL;
136 }
137 *count = c;
138 return rval;
139 }
140
141 void
142 doneline(
143 char *input,
144 char **vec)
145 {
146 xfree(input);
147 xfree(vec);
148 }
149
150 static char *
151 fetchline_internal(void)
152 {
153 char buf[1024];
154 int iscont;
155 size_t len;
156 size_t rlen;
157 char *rval;
158
159 rval = NULL;
160 for (rlen = iscont = 0; ; ) {
161 if (inputstacksize == 1) {
162 if (iscont)
163 dbprintf("... ");
164 else
165 dbprintf("%s> ", progname);
166 fflush(stdin);
167 }
168 if (seenint() ||
169 (!fgets(buf, sizeof(buf), curinput) &&
170 ferror(curinput) && seenint())) {
171 clearint();
172 dbprintf("^C\n");
173 clearerr(curinput);
174 if (iscont) {
175 iscont = 0;
176 rlen = 0;
177 if (rval) {
178 xfree(rval);
179 rval = NULL;
180 }
181 }
182 continue;
183 }
184 if (ferror(curinput) || feof(curinput) ||
185 (len = strlen(buf)) == 0) {
186 popfile();
187 if (curinput == NULL) {
188 dbprintf("\n");
189 return NULL;
190 }
191 iscont = 0;
192 rlen = 0;
193 if (rval) {
194 xfree(rval);
195 rval = NULL;
196 }
197 continue;
198 }
199 if (inputstacksize == 1)
200 logprintf("%s", buf);
201 rval = xrealloc(rval, rlen + len + 1);
202 if (rlen == 0)
203 rval[0] = '\0';
204 rlen += len;
205 strcat(rval, buf);
206 if (buf[len - 1] == '\n') {
207 if (len > 1 && buf[len - 2] == '\\') {
208 rval[rlen - 2] = ' ';
209 rval[rlen - 1] = '\0';
210 rlen--;
211 iscont = 1;
212 } else {
213 rval[rlen - 1] = '\0';
214 rlen--;
215 break;
216 }
217 }
218 }
219 return rval;
220 }
221
222 #ifdef ENABLE_READLINE
223 char *
224 fetchline(void)
225 {
226 static char prompt[FILENAME_MAX + 1];
227 char *line;
228
229 if (!prompt[0])
230 snprintf(prompt, sizeof(prompt), "%s> ", progname);
231
232 if (inputstacksize == 1) {
233 line = readline(prompt);
234 if (line && *line)
235 add_history(line);
236 else
237 logprintf("%s", line);
238 } else {
239 line = fetchline_internal();
240 }
241 return line;
242 }
243 #else
244 char *
245 fetchline(void)
246 {
247 return fetchline_internal();
248 }
249 #endif
250
251 static void
252 popfile(void)
253 {
254 if (inputstacksize == 0) {
255 curinput = NULL;
256 return;
257 }
258 if (curinput != stdin)
259 fclose(curinput);
260
261 inputstacksize--;
262 if (inputstacksize) {
263 inputstack =
264 xrealloc(inputstack, inputstacksize * sizeof(*inputstack));
265 curinput = inputstack[inputstacksize - 1];
266 } else {
267 free(inputstack);
268 curinput = NULL;
269 inputstack = NULL;
270 }
271 }
272
273 void
274 pushfile(
275 FILE *file)
276 {
277 inputstack =
278 xrealloc(inputstack,
279 (inputstacksize + 1) * sizeof(*inputstack));
280 inputstacksize++;
281 curinput = inputstack[inputstacksize - 1] = file;
282 }
283
284 /* ARGSUSED */
285 static int
286 source_f(
287 int argc,
288 char **argv)
289 {
290 FILE *f;
291
292 f = fopen(argv[1], "r");
293 if (f == NULL)
294 dbprintf("can't open %s\n", argv[0]);
295 else
296 pushfile(f);
297 return 0;
298 }
299
300 void
301 input_init(void)
302 {
303 add_command(&source_cmd);
304 }