nand_base: We have to ignore the -EUCLEAN error
[barebox-mini2440.git] / common / complete.c
blobc499e097c08de9099a37916c7646b0ffa3ae4c79
1 /*
2 * complete.c - functions for TAB completion
4 * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <common.h>
21 #include <complete.h>
22 #include <xfuncs.h>
23 #include <list.h>
24 #include <malloc.h>
25 #include <fs.h>
26 #include <linux/stat.h>
27 #include <libgen.h>
28 #include <command.h>
29 #include <stringlist.h>
31 static int file_complete(struct string_list *sl, char *instr)
33 char *path = strdup(instr);
34 struct stat s;
35 DIR *dir;
36 struct dirent *d;
37 char tmp[PATH_MAX];
38 char *base, *dirn;
40 base = basename(instr);
41 dirn = dirname(path);
43 dir = opendir(dirn);
44 if (!dir)
45 goto out;
47 while ((d = readdir(dir))) {
48 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
49 continue;
51 if (!strncmp(base, d->d_name, strlen(base))) {
52 strcpy(tmp, instr);
53 strcat(tmp, d->d_name + strlen(base));
54 if (!stat(tmp, &s) && S_ISDIR(s.st_mode))
55 strcat(tmp, "/");
56 else
57 strcat(tmp, " ");
58 string_list_add(sl, tmp);
62 closedir(dir);
64 out:
65 free(path);
67 return 0;
70 static int command_complete(struct string_list *sl, char *instr)
72 cmd_tbl_t *cmdtp;
73 char cmd[128];
75 for_each_command(cmdtp) {
76 if (!strncmp(instr, cmdtp->name, strlen(instr))) {
77 strcpy(cmd, cmdtp->name);
78 cmd[strlen(cmdtp->name)] = ' ';
79 cmd[strlen(cmdtp->name) + 1] = 0;
80 string_list_add(sl, cmd);
84 return 0;
87 static int tab_pressed = 0;
89 void complete_reset(void)
91 tab_pressed = 0;
94 int complete(char *instr, char **outstr)
96 struct string_list sl, *entry, *first_entry;
97 int pos;
98 char ch;
99 int changed;
100 static char out[256];
101 int outpos = 0;
102 int reprint = 0;
103 char *t;
105 string_list_init(&sl);
107 /* advance to the last command */
108 t = strrchr(instr, ';');
109 if (!t)
110 t = instr;
111 else
112 t++;
114 while (*t == ' ')
115 t++;
117 instr = t;
119 /* get the completion possibilities */
120 if ((t = strrchr(t, ' '))) {
121 t++;
122 file_complete(&sl, t);
123 instr = t;
124 } else
125 command_complete(&sl, instr);
127 pos = strlen(instr);
129 *outstr = "";
130 if (list_empty(&sl.list))
131 return reprint;
133 out[0] = 0;
135 first_entry = list_first_entry(&sl.list, struct string_list, list);
137 while (1) {
138 entry = first_entry;
139 ch = entry->str[pos];
140 if (!ch)
141 break;
143 changed = 0;
144 list_for_each_entry(entry, &sl.list, list) {
145 if (!entry->str[pos])
146 break;
147 if (ch != entry->str[pos]) {
148 changed = 1;
149 break;
153 if (changed)
154 break;
155 out[outpos++] = ch;
156 pos++;
159 if (!list_is_last(&first_entry->list, &sl.list) && !outpos && tab_pressed) {
160 printf("\n");
161 string_list_print_by_column(&sl);
162 reprint = 1;
165 out[outpos++] = 0;
166 *outstr = out;
168 if (*out == 0)
169 tab_pressed = 1;
170 else
171 tab_pressed = 0;
173 string_list_free(&sl);
175 return reprint;