#include "cmdlinelib.h" #include #include #include #include int cmdl_getexit(cmd_line* cmd) { if(cmdl_check(cmd) && !cmd->exit){ return 0; }else{ return 1; } } void cmdl_setexit(cmd_line* cmd, int exit) { if(cmdl_check(cmd)){ cmd->exit = exit; } } int cmdl_printf(cmd_line* cmd, const char *format, ...) { int ret; char string[CMDL_OUTPUT_SIZE]; va_list ap; va_start(ap, format); ret = vsprintf(string, format, ap); cmdl_addoutput_str(cmd, string); va_end(ap); return ret; } void cmdl_addoutput_str(cmd_line* cmd, char output[CMDL_OUTPUT_SIZE]) { if(cmdl_check(cmd) && output != NULL){ if(!cmd->has_output){ cmdl_clearoutput(cmd); } strncat(cmd->output, output, CMDL_OUTPUT_SIZE); cmd->has_output = 1; } } char* cmdl_getoutput(cmd_line* cmd) { if(cmdl_check(cmd) && cmd->has_output){ cmd->has_output = 0; return cmd->output; }else{ return ""; } } void cmdl_setpropmt(cmd_line* cmd, char prompt[CMDL_PROMPT_SIZE]) { if(cmdl_check(cmd) && prompt != NULL){ strncat(cmd->prompt, prompt, CMDL_PROMPT_SIZE); } } char *cmdl_getprompt(cmd_line* cmd) { if(cmdl_check(cmd)){ return cmd->prompt; }else{ return ""; } } char* cmdl_getbuffer(cmd_line* cmd){ if(cmdl_check(cmd)){ return cmd->buffer; }else{ return ""; } } void cmdl_addchar(cmd_line* cmd, char in) { if(in >= 32){ if(cmdl_check(cmd)){ cmd->buffer[cmd->cursor] = in; cmdl_movecursor(cmd, CMDL_RIGHT); } }else{ switch(in){ case 0x08: /* Backspace */ cmdl_delat(cmd, cmd->cursor); cmdl_movecursor(cmd, CMDL_LEFT); break; case 0x0a: case 0x0d: /* Enter */ cmdl_exec(cmd); break; } } } void cmdl_exec(cmd_line* cmd) { char* command; cmdl_printf(cmd, "%s %s\n", cmd->prompt, cmd->buffer); command = cmdl_parse_getcmd(cmd); if(strlen(command) != 0){ if(strcmp(command, "exit") == 0 || strcmp(command, "quit") == 0){ cmdl_setexit(cmd, 1); }else if(strcmp(command, "help") == 0){ cmdl_printf(cmd, "Don't panic\n"); }else{ cmdl_printf(cmd, "%s: unknown command\n", command); } } free(command); cmdl_clearbuffer(cmd); } char* cmdl_parse_getcmd(cmd_line* cmd){ int i; char* ret; ret = (char*)malloc(1); ret[0] = 0; for(i=0; i < CMDL_BUFFER_SIZE - 1; i++){ if(cmd->buffer[i + 1] == ' ' || cmd->buffer[i + 1] == '\0'){ free(ret); ret = (char*)malloc(i+1); strncat(ret, cmd->buffer, i+1); break; } } return ret; } void cmdl_clearbuffer(cmd_line* cmd) { if(cmdl_check(cmd)){ int i; cmd->cursor = 0; for(i=0; i < CMDL_BUFFER_SIZE; i++){ cmd->buffer[i] = 0; } } } void cmdl_clearoutput(cmd_line* cmd) { if(cmdl_check(cmd)){ int i; for(i=0; i < CMDL_OUTPUT_SIZE; i++){ cmd->output[i] = 0; } } } void cmdl_movecursor(cmd_line* cmd, int direction) { if(cmdl_check(cmd)){ switch(direction){ case CMDL_LEFT: if(cmd->cursor > 0){ cmd->cursor--; } break; case CMDL_RIGHT: if(cmd->cursor < CMDL_BUFFER_SIZE - 1){ cmd->cursor++; } break; } } } void cmdl_delat(cmd_line* cmd, int at) { if(cmdl_check(cmd) && at < CMDL_BUFFER_SIZE - 1 && at >= 0){ int i; for(i = at; i < CMDL_BUFFER_SIZE - 1; i++){ cmd->buffer[i] = cmd->buffer[i + 1]; } } } int cmdl_check(cmd_line* cmd) { if( cmd != NULL && cmd->buffer != NULL && cmd->prompt != NULL && cmd->cursor >= 0 && cmd->cursor < CMDL_BUFFER_SIZE - 1 && cmd->buffer[CMDL_BUFFER_SIZE - 1] == 0 && cmd->prompt[CMDL_PROMPT_SIZE - 1] == 0 ){ return 1; }else{ return 0; } } cmd_line* cmdl_create() { cmd_line* this; int i; // Initiate the command line this = (cmd_line*)malloc(sizeof(cmd_line)); if(this == NULL){ return NULL; } /* Allocate output buffer */ this->output = (char*)malloc(CMDL_OUTPUT_SIZE); if(this->output == NULL){ free(this); return NULL; } for(i = 0; i < CMDL_OUTPUT_SIZE; i++){ this->output[i] = 0; } /* Allocate command line buffer */ this->buffer = (char*)malloc(CMDL_BUFFER_SIZE); if(this->buffer == NULL){ free(this); return NULL; } for(i = 0; i < CMDL_BUFFER_SIZE; i++){ this->buffer[i] = 0; } /* Allocate prompt buffer */ this->prompt = (char*)malloc(CMDL_PROMPT_SIZE); if(this->prompt == NULL){ free(this); return NULL; } for(i = 0; i < CMDL_PROMPT_SIZE; i++){ this->prompt[i] = 0; } /* Initiate cursor position */ this->cursor = 0; this->has_output = 0; this->exit = 0; return this; } void cmdl_free(cmd_line* cmd) { free(cmd); }