1 /*
2  * ui_cli.c -- the glue that binds various modules into the interpreter
3  *
4  * Copyright (C) 2001-2003 �yvind Kol�s <pippin@users.sourceforge.net>
5  *
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2, or (at your option) any later
9  * version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc., 59
18  * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #if HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "tree.h"
30 #include "file.h"
31 #include "path.h"
32 #include "prefs.h"
33 #include "cli.h"
34 #include "ui_cli.h"
35 
36 
37 /* strips the ending node off a path */
path_strip(char * path)38 static char *path_strip (char *path)
39 {								/* FIXME add double // escaping when node2path gets it */
40 
41 	int j = strlen (path);
42 
43 	while (j > 0) {
44 		if (path[j - 1] == '/') {
45 			path[j] = 0;
46 			return path;
47 		}
48 		j--;
49 	}
50 	return path;
51 }
52 
add(int argc,char ** argv,void * data)53 static uint64_t add (int argc,char **argv, void *data)
54 {
55 	Node *pos = (Node *) data;
56 	Node *tnode;
57 
58 	if(argc==1){
59 		cli_outfunf("usage: %s <new entry>",argv[0]);
60 		return 0;
61 	}
62 
63 	if (argc==2) {
64 		cli_outfun ("empty node added\n");
65 	}
66 
67 	tnode = node_insert_down (node_bottom (pos));
68 	node_set (tnode, TEXT, argv[1]);
69 	return PTR_TO_UINT64(pos);
70 }
71 
addc(int argc,char ** argv,void * data)72 static uint64_t addc (int argc,char **argv, void *data)
73 {
74 	Node *pos = (Node *) data;
75 	Node *tnode;
76 
77 	if(argc==1){
78 		cli_outfunf("usage: %s <entry> [new subentry]",argv[0]);
79 		return 0;
80 	}
81 
82 	tnode = node_exact_match (argv[1], pos);
83 	if (!tnode) {
84 		cli_outfun ("specified parent not found");
85 		return PTR_TO_UINT64(pos);
86 	}
87 
88 	if (node_right (tnode)) {
89 		tnode=node_bottom(tnode);
90 	} else {
91 		tnode=node_insert_right(tnode);
92 	}
93 
94 	if(argc==2)
95 		node_set (tnode, TEXT, "");
96 	else
97 		node_set (tnode, TEXT, argv[2]);
98 
99 	return PTR_TO_UINT64(pos);
100 }
101 
pwd(int argc,char ** argv,void * data)102 static uint64_t pwd (int argc,char **argv, void *data)
103 {
104 	Node *pos = (Node *) data;
105 
106 	cli_outfun (path_strip (node2path (pos)));
107 	cli_outfun ("\n");
108 	return PTR_TO_UINT64(pos);
109 }
110 
cd(int argc,char ** argv,void * data)111 static uint64_t cd (int argc, char **argv, void *data)
112 {
113 	Node *pos = (Node *) data;
114 	Node *tnode = pos;
115 
116 	if(argc==1){
117 		return PTR_TO_UINT64(node_root(pos));
118 	}
119 
120 	if (!strcmp (argv[1], "..")){
121 		if (node_left (tnode) != 0)
122 			return PTR_TO_UINT64((node_left (tnode)));
123 	}
124 
125 
126 	tnode = path2node (argv[1], pos);
127 	if (tnode) {
128 		tnode = node_right (tnode);
129 	}
130 	if (!tnode) {
131 		cli_outfun ("no such node\n");
132 		return PTR_TO_UINT64(pos);
133 	}
134 	return PTR_TO_UINT64(tnode);
135 
136 	return PTR_TO_UINT64(pos);
137 }
138 
139 #include <ctype.h>
140 
pre_command(char * commandline)141 static void pre_command (char *commandline)
142 {
143 	char *c = commandline;
144 
145 	if (commandline) {
146 		while (isspace ((unsigned char)*c))
147 			c++;
148 		if (*c == '#')
149 			commandline[0] = '\0';
150 		if (*c == '\0')
151 			commandline[0] = '\0';
152 	}
153 }
154 
ls(int argc,char ** argv,void * data)155 static uint64_t ls (int argc, char **argv, void *data)
156 {
157 	Node *pos = (Node *) data;
158 
159 	Node *tnode;
160 	int recurse = 0;
161 	int indicate_sub = 1;
162 	int startlevel;
163 
164 	tnode = node_top (pos);
165 
166 	startlevel = nodes_left (tnode);
167 	while (tnode) {
168 
169 		if (recurse) {
170 			int j;
171 
172 			for (j = nodes_left (tnode); j > startlevel; j--) {
173 				printf ("\t");
174 			}
175 		}
176 
177 		cli_outfunf( "%s %s %s",fixnullstring(node_get (tnode, TEXT)),
178 		indicate_sub?
179 		node_right(tnode)?"(..)":""
180 		:"", tnode==pos?"<":""
181 
182 		);
183 
184 		if (recurse) {
185 			tnode = node_recurse (tnode);
186 			if (nodes_left (tnode) < startlevel)
187 				tnode = 0;
188 		} else {
189 			tnode = node_down (tnode);
190 		}
191 	}
192 	return PTR_TO_UINT64(pos);
193 }
194 
195 /*
196 !init_ui_cli();
197 */
init_ui_cli(void)198 void init_ui_cli (void)
199 {
200 	static int inited = 0;
201 
202 	if (!inited) {
203 		inited = 1;
204 		cli_precmd = pre_command;
205 		cli_add_command ("add", add, "<string>");
206 		cli_add_command ("ls", ls, "");
207 
208 		cli_add_help("add","inserts an new entry at the current position");
209 		cli_add_command ("addc", addc, "<parent> <string>");
210 		cli_add_help("addc","inserts a new entry under the node named parent, with the text og string");
211 		cli_add_command ("cd", cd, "<path>");
212 		cli_add_command ("pwd", pwd, "");
213 		cli_add_help ("pwd", "echoes the current path");
214 	}
215 }
216 
217 
docmd(Node * pos,const char * commandline)218 Node *docmd (Node *pos, const char *commandline)
219 {
220 	Node * ret;
221 	char *cmdline = strdup (commandline);
222 
223 	ret = (Node *)cli_docmd (cmdline, pos);
224 	free (cmdline);
225 
226 	return (Node *) ret;
227 }
228 
docmdf(Node * pos,char * format,...)229 Node *docmdf (Node *pos,char *format, ...){
230 	va_list arglist;
231 	char buf[128];
232 
233 	va_start( arglist, format );
234 	vsnprintf(buf,127,format,arglist);
235 	va_end(arglist);
236 
237 	buf[127]=0;
238 	return docmd(pos,buf);
239 }
240 
241 
242 extern int quit_hnb; /* from evilloop. */
243 
cli(Node * pos)244 Node *cli (Node *pos)
245 {
246 	char commandline[4096];
247 
248 	fprintf (stderr,
249 			 "Welcome to %s %s\ntype ? or help for more information\n",
250 			 PACKAGE, VERSION);
251 
252 	do {
253 		fflush (stdout);
254 		fprintf (stdout, "%s>", path_strip (node2path (pos)));
255 		fflush (stdout);
256 		fgets (commandline, 4096, stdin);
257 		commandline[strlen (commandline) - 1] = 0;
258 		pos = (Node *) cli_docmd (commandline, pos);
259 	} while (!quit_hnb);
260 	return pos;
261 }
262