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
26 #include <linux/stat.h>
29 #include <stringlist.h>
31 static int file_complete(struct string_list
*sl
, char *instr
)
33 char *path
= strdup(instr
);
40 base
= basename(instr
);
47 while ((d
= readdir(dir
))) {
48 if (!strcmp(d
->d_name
, ".") || !strcmp(d
->d_name
, ".."))
51 if (!strncmp(base
, d
->d_name
, strlen(base
))) {
53 strcat(tmp
, d
->d_name
+ strlen(base
));
54 if (!stat(tmp
, &s
) && S_ISDIR(s
.st_mode
))
58 string_list_add(sl
, tmp
);
70 static int command_complete(struct string_list
*sl
, char *instr
)
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
);
87 static int tab_pressed
= 0;
89 void complete_reset(void)
94 int complete(char *instr
, char **outstr
)
96 struct string_list sl
, *entry
, *first_entry
;
100 static char out
[256];
105 string_list_init(&sl
);
107 /* advance to the last command */
108 t
= strrchr(instr
, ';');
119 /* get the completion possibilities */
120 if ((t
= strrchr(t
, ' '))) {
122 file_complete(&sl
, t
);
125 command_complete(&sl
, instr
);
130 if (list_empty(&sl
.list
))
135 first_entry
= list_first_entry(&sl
.list
, struct string_list
, list
);
139 ch
= entry
->str
[pos
];
144 list_for_each_entry(entry
, &sl
.list
, list
) {
145 if (!entry
->str
[pos
])
147 if (ch
!= entry
->str
[pos
]) {
159 if (!list_is_last(&first_entry
->list
, &sl
.list
) && !outpos
&& tab_pressed
) {
161 string_list_print_by_column(&sl
);
173 string_list_free(&sl
);