Merge of Fredrik Hultin command_line
[people/xl0/gpxe.git] / src / core / cmdlinelib.c
1 #include "cmdlinelib.h"
2 #include <console.h>
3 #include <malloc.h>
4 #include <string.h>
5 #include <stdarg.h>
6
7 int cmdl_getexit(cmd_line* cmd)
8 {
9         if(cmdl_check(cmd) && !cmd->exit){
10                 return 0;
11         }else{
12                 return 1;
13         }
14
15 }
16
17 void cmdl_setexit(cmd_line* cmd, int exit)
18 {
19         if(cmdl_check(cmd)){
20                 cmd->exit = exit;
21         }
22 }
23
24 int cmdl_printf(cmd_line* cmd, const char *format, ...)
25 {
26         int ret;
27         char string[CMDL_OUTPUT_SIZE];
28         va_list ap;
29
30         va_start(ap, format);
31         ret = vsprintf(string, format, ap);
32         cmdl_addoutput_str(cmd, string);
33         va_end(ap);
34         return ret;
35 }
36
37
38 void cmdl_addoutput_str(cmd_line* cmd, char output[CMDL_OUTPUT_SIZE])
39 {
40         if(cmdl_check(cmd) && output != NULL){
41                 if(!cmd->has_output){
42                         cmdl_clearoutput(cmd);
43                 }
44                 strncat(cmd->output, output, CMDL_OUTPUT_SIZE);
45                 cmd->has_output = 1;
46         }
47 }
48
49 char* cmdl_getoutput(cmd_line* cmd)
50 {
51         if(cmdl_check(cmd) && cmd->has_output){
52                 cmd->has_output = 0;
53                 return cmd->output;
54         }else{
55                 return "";
56         }
57 }
58
59 void cmdl_setpropmt(cmd_line* cmd, char prompt[CMDL_PROMPT_SIZE])
60 {
61         if(cmdl_check(cmd) && prompt != NULL){
62                 strncat(cmd->prompt, prompt, CMDL_PROMPT_SIZE);
63         }
64 }
65
66 char *cmdl_getprompt(cmd_line* cmd)
67 {
68         if(cmdl_check(cmd)){
69                 return cmd->prompt;
70         }else{
71                 return "";
72         }
73 }
74
75 char* cmdl_getbuffer(cmd_line* cmd){
76         if(cmdl_check(cmd)){
77                 return cmd->buffer;
78         }else{
79                 return "";
80         }
81 }
82
83 void cmdl_addchar(cmd_line* cmd, char in)
84 {
85         if(in >= 32){
86                 if(cmdl_check(cmd)){
87                         cmd->buffer[cmd->cursor] = in;
88                         cmdl_movecursor(cmd, CMDL_RIGHT);
89                 }
90         }else{
91                 switch(in){
92                         case 0x08: /* Backspace */
93
94                                 cmdl_delat(cmd, cmd->cursor);
95                                 cmdl_movecursor(cmd, CMDL_LEFT);
96                                 break;
97                         case 0x0a:
98                         case 0x0d: /* Enter */
99                                 cmdl_exec(cmd);
100                                 break;
101                 }
102         }
103 }
104
105 void cmdl_exec(cmd_line* cmd)
106 {
107         char* command;
108         cmdl_printf(cmd, "%s %s\n", cmd->prompt, cmd->buffer);
109
110         command = cmdl_parse_getcmd(cmd);
111         if(strlen(command) != 0){
112                 if(strcmp(command, "exit") == 0 || strcmp(command, "quit") == 0){
113                         cmdl_setexit(cmd, 1);
114                 }else if(strcmp(command, "help") == 0){
115                         cmdl_printf(cmd, "Don't panic\n");
116                 }else{
117                         cmdl_printf(cmd, "%s: unknown command\n", command);
118                 }
119         }
120         free(command);
121         
122         cmdl_clearbuffer(cmd);
123 }
124
125 char* cmdl_parse_getcmd(cmd_line* cmd){
126         int i;
127         char* ret;
128         ret = (char*)malloc(1);
129         ret[0] = 0;
130
131         for(i=0; i < CMDL_BUFFER_SIZE - 1; i++){
132                 if(cmd->buffer[i + 1] == ' ' || cmd->buffer[i + 1] == '\0'){
133                         free(ret);
134                         ret = (char*)malloc(i+1);
135                         strncat(ret, cmd->buffer, i+1);
136                         break;
137                 }
138         }
139         return ret;
140 }
141
142 void cmdl_clearbuffer(cmd_line* cmd)
143 {
144         if(cmdl_check(cmd)){
145                 int i;
146                 cmd->cursor = 0;
147                 for(i=0; i < CMDL_BUFFER_SIZE; i++){
148                         cmd->buffer[i] = 0;
149                 }
150         }
151 }
152
153 void cmdl_clearoutput(cmd_line* cmd)
154 {
155         if(cmdl_check(cmd)){
156                 int i;
157                 for(i=0; i < CMDL_OUTPUT_SIZE; i++){
158                         cmd->output[i] = 0;
159                 }
160         }
161 }
162
163 void cmdl_movecursor(cmd_line* cmd, int direction)
164 {
165         if(cmdl_check(cmd)){
166                 switch(direction){
167                         case CMDL_LEFT:
168                                 if(cmd->cursor > 0){
169                                         cmd->cursor--;
170                                 }
171                                 break;
172                         case CMDL_RIGHT:
173                                 if(cmd->cursor < CMDL_BUFFER_SIZE - 1){
174                                         cmd->cursor++;
175                                 }
176                                 break;
177                 }
178         }
179 }
180
181 void cmdl_delat(cmd_line* cmd, int at)
182 {
183         if(cmdl_check(cmd) && at < CMDL_BUFFER_SIZE - 1 && at >= 0){
184                 int i;
185                 for(i = at; i < CMDL_BUFFER_SIZE - 1; i++){
186                         cmd->buffer[i] = cmd->buffer[i + 1];
187                 }
188         }
189 }
190
191
192 int cmdl_check(cmd_line* cmd)
193 {
194         if(
195                 cmd != NULL && 
196                 cmd->buffer != NULL &&
197                 cmd->prompt != NULL &&
198                 cmd->cursor >= 0 && 
199                 cmd->cursor < CMDL_BUFFER_SIZE - 1 &&
200                 cmd->buffer[CMDL_BUFFER_SIZE - 1] == 0 &&
201                 cmd->prompt[CMDL_PROMPT_SIZE - 1] == 0
202         ){
203                 return 1;
204         }else{
205                 return 0;
206         }
207 }
208
209 cmd_line* cmdl_create()
210 {
211         cmd_line* this;
212         int i;
213         
214         // Initiate the command line
215         
216         this = (cmd_line*)malloc(sizeof(cmd_line));
217         
218         if(this == NULL){
219                 return NULL;
220         }
221         
222
223         /* Allocate output buffer */
224         
225         this->output = (char*)malloc(CMDL_OUTPUT_SIZE);
226         if(this->output == NULL){
227                 free(this);
228                 return NULL;
229         }
230         
231         for(i = 0; i < CMDL_OUTPUT_SIZE; i++){
232                 this->output[i] = 0;
233         }
234
235         /* Allocate command line buffer */
236         
237         this->buffer = (char*)malloc(CMDL_BUFFER_SIZE);
238         if(this->buffer == NULL){
239                 free(this);
240                 return NULL;
241         }
242         
243         for(i = 0; i < CMDL_BUFFER_SIZE; i++){
244                 this->buffer[i] = 0;
245         }
246         
247         /* Allocate prompt buffer */
248         
249         this->prompt = (char*)malloc(CMDL_PROMPT_SIZE);
250         if(this->prompt == NULL){
251                 free(this);
252                 return NULL;
253         }
254         
255         for(i = 0; i < CMDL_PROMPT_SIZE; i++){
256                 this->prompt[i] = 0;
257         }
258         
259         /* Initiate cursor position */
260         
261         this->cursor = 0;
262         this->has_output = 0;
263         this->exit = 0;
264         
265         return this;
266 }
267
268 void cmdl_free(cmd_line* cmd)
269 {
270         free(cmd);
271 }
272