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