#include "ihe.h" #include "__cpp.h" #include "core.h" /* Global variables */ cmd_mng_t cmd_mng; static int cmd_loop = 1; extern cmd_table_t tab[]; #define CMK_KEYMAP1(KEY) (in_buf[0]==(KEY)&&(ret_read==1)) #define CMK_KEYMAP4(KEY1,KEY2,KEY3,KEY4) ((in_buf[3]==(KEY1))&&(in_buf[2]==(KEY2))&&(in_buf[1]==(KEY3))&&(in_buf[0]==(KEY4))&&(ret_read==4)) #define CMD_IN_BUF_SIZE 32 typedef struct cmd_in_buf_t { char buf[CMD_IN_BUF_SIZE+2];//enought space to put "'\n',NULL" int cur_sz; } cmd_in_buf_t; int cmd_buf_clean( cmd_in_buf_t *buf ); /* type == 1, usual printable chars type == 2, print in hex */ int cmd_buf_print( cmd_in_buf_t *buf, int type ); int cmd_buf_add( cmd_in_buf_t *buf, char *ch, int size ); int cmd_buf_rem1( cmd_in_buf_t *buf ); int cmd_buf_full( cmd_in_buf_t *buf ); int cmd_buf_clean( cmd_in_buf_t *buf ) { memset( buf, 0, sizeof(cmd_in_buf_t)); return 0; } int cmd_buf_print( cmd_in_buf_t *buf, int type ) { int i; //printf("sz:%d\n",buf->cur_sz); for (i=0;(icur_sz ) { if (type == 1) { if (isprint(buf->buf[i])) { printf("%c",(char)(buf->buf[i]&0xff)); } else { printf("."); } } else if (type == 2) { printf("%02x ", (unsigned char)(buf->buf[i]&0xff) ); } } else { printf(" "); } } fflush(stdout); return 0; } int term_set_std_mode( term_screen *ts ) { int ret = 0; if ( tcgetattr( ts->ifd, &ts->orig_i ) == -1 ) { ERROR("Cannot get input terminal attributes\n"); goto exit_error; } ts->raw_i = ts->orig_i; /* modify the original mode */ /* input modes: no break, no CR to NL, no parity check, no strip char, * no start/stop output control. */ //ts->raw_i.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); ts->raw_i.c_iflag = IUTF8|ICRNL; /* output modes - disable post raw */ //ts->raw_i.c_oflag &= ~(OPOST); ts->raw_i.c_oflag = OPOST|ONLCR; /* control modes - set 8 bit chars */ //ts->raw_i.c_cflag |= (CS8); ts->raw_i.c_cflag = CS8|CREAD; /* local modes - choing off, canonical off, no extended functions, * no signal chars (^Z,^C) */ //ts->raw_i.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); //if ICANNON ignore ESC char //ts->raw_i.c_lflag = ISIG|ECHO; ts->raw_i.c_lflag = ISIG; /* control chars - set return condition: min number of bytes and timer. * We want read to return every single byte, without timeout. */ ts->raw_i.c_cc[VMIN] = 1; ts->raw_i.c_cc[VTIME] = 0; /* 1 byte, no timer */ /* put terminal in raw mode after flushing */ if (tcsetattr( ts->ifd, TCSAFLUSH, &ts->raw_i) < 0) { ERROR("Cannot set new terminal input attribures\n"); goto exit_error; } return ret; exit_error: errno = ENOTTY; return -1; } int custom_term_echo( char *keybuf ) { if (isprint(keybuf[0])) { write(1,keybuf,1); } if (keybuf[0]=='\n') { write(1,"\r\n",2); } return 0; } int cmd_tab_autocomplete( char *in_buf ) { cmd_arg_t *args; cmd_tok_t tl, *ptr = &tl, *iter = NULL; struct cmd_acq_t *iter_sugg = NULL; memset( &tl, 0, sizeof( cmd_tok_t )); int i; //printf("[%s]\n", in_buf); #warning "Fix this" /* if ( parse_cmd( ptr, in_buf) == -1) { printf("Cmd problems\n"); return -1; } */ iter = ptr->next; args = cmd_arg_create( iter ); for (i=0; iargc; i++) { printf("ARG:%d TYPE:%d %s\n", i, args->type[i], args->argv[i]); } //printf("Unkn command\n"); //if command not found offer auto complete options if (args->argc > 0) { //printf("asd\n"); struct cmd_acq_head_t *ac = cmd_acq(tab,args->argv[0]); if (ac != NULL) { printf("\n>"); //printf("Did you mean "); SLIST_FOREACH(iter_sugg,ac,next_sugg) { printf("%s ", iter_sugg->suggestion); } printf("\n"); } cmd_acq_free( ac ); } cmd_tok_destroy( ptr->next ); ptr->next = NULL; cmd_arg_destroy( args ); return 0; } int cmd_buf_add( cmd_in_buf_t *buf, char *ch, int size ) { int i,j; /* for (i=0;icur_sz; for ( j=0; jbuf[i+j] = ch[j]; buf->cur_sz = i+j+1; //printf("%d\n", buf->cur_sz ); //printf("\n"); } } return 0; } int cmd_buf_rem1( cmd_in_buf_t *buf ) { int ret = -1; if ( buf->cur_sz > 0 ) { buf->cur_sz -= 1; ret = 0; } return ret; } int cmd_buf_full( cmd_in_buf_t *buf ) { int ret = 0; if ( buf->cur_sz == (CMD_IN_BUF_SIZE-1) ) { return 1; } return ret; } /* GLOBAL VARIABLES */ file_t *g_file = NULL; //buf_t *g_buf = NULL; Buf *g_buf = NULL; int g_flags = FD_RW; int c_version( cmd_arg_t *arg ) { int argc = arg->argc; if ( argc != 0 ) { printf("Command should not have arguments mister\n"); return -1; } printf("Version 0.0.2\n"); return 0; } int c_arg( cmd_arg_t *arg ) { int i; int argc = arg->argc; char **argv = arg->argv; for (i=0;iargc; int th = -1; if ( argc > 0 ) { printf("No arguments needed\n"); return -1; } th = term_cur_get_r(); if (th == -1) { printf("Cannot get current term height\n"); return -1; } printf("%d\n",th); */ return 0; } int c_tw( cmd_arg_t *arg ) { /* int argc = arg->argc; int tw = -1; if ( argc > 0 ) { printf("No arguments needed\n"); return -1; } tw = term_cur_get_c(); if (tw == -1) { printf("Cannot get current term width\n"); return -1; } printf("%d\n",tw); */ return 0; } /* CMD COMMANDS */ cmd_table_t tab[] = { {"version", c_version , NULL, NULL, NULL}, {"arg", c_arg , NULL, NULL, NULL}, //{"quit", c_quit}, {"help", c_help, NULL, NULL, NULL}, {"?", c_help, NULL, NULL, NULL}, {"open", c_open, h_open, NULL, NULL}, {"close", c_close, h_close, NULL, NULL}, {"info", c_info, h_info, NULL, NULL}, {"seek", c_seek, h_seek, NULL, NULL}, {"pos", c_pos, h_pos, NULL, NULL}, {"size", c_size, h_size, NULL, NULL}, {"blk", c_blk, h_blk, NULL, NULL}, {"read", c_read, h_read, NULL, NULL}, {"dump", c_dump, h_dump, NULL, NULL}, {"dumpx", c_dumpx, h_dumpx, NULL, NULL}, {"dumps", c_dumps, h_dumps, NULL, NULL}, {"write", c_write, h_write, NULL, NULL}, {"writes", c_writes, h_writes, NULL, NULL}, {"resize", c_resize, h_resize, NULL, NULL}, {"flags", c_flags, h_flags, NULL, NULL}, {"manifesto", c_manifesto, NULL, NULL, NULL}, {"ls", c_ls, h_ls, NULL, NULL}, {"pwd", c_pwd, h_pwd, NULL, NULL}, {"cd", c_cd, h_cd, NULL, NULL}, {"pageup", c_pageup, h_pageup, NULL, NULL}, {"pagedown", c_pagedown, h_pagedown, NULL, NULL}, //{"bwrite", c_bwrite, h_bwrite, NULL, NULL}, //{"bread", c_bread, h_bread, NULL, NULL}, //{"create", c_create, h_create, NULL, NULL}, //{"th", c_th. h_th, NULL, NULL}, //{"tw", c_tw, h_tw, NULL, NULL}, //{"tfit", c_tfit, h_tfit, NULL, NULL}, {NULL, NULL , NULL, NULL, NULL}, }; int main( int argc, char **argv ) { const int sz_buf = 1024; int err; uint8_t in_buf[sz_buf]; int ret_read; int new_c=0, new_r=0, old_r=0, old_c=0; cmd_arg_t *args; cmd_tok_t tl, *ptr = &tl, *iter = NULL; memset( &tl, 0, sizeof( cmd_tok_t )); //preapre global stuff g_file = file_init(); //init basic buffer g_buf = new Buf(DEFAULT_BLK_SIZE); struct term_screen ts; memset( &ts, 0, sizeof(ts) ); cmd_in_buf_t cmd_in; cmd_buf_clean( &cmd_in ); //clean cmd manager structure that is global memset(&cmd_mng, 0, sizeof(cmd_mng)); //register command table cmd_mng.table = tab; cmd_mng.flag_history = 0; cmd_mng.flag_autocomplete = 1; if ( term_init( &ts ) == -1 ) printf("Some err when init\n"); //term_set_raw_mode( &ts ); term_set_std_mode( &ts ); term_clr_scr( &ts ); new_c = term_get_maxcol( &ts ); new_r = term_get_maxrow( &ts ); old_r = new_r; old_c = new_c; term_cur_set_c( &ts, 0); term_cur_set_r( &ts, old_r); write(1,"$",1); while ( cmd_loop ) { //write(1,"$",1); ret_read = read(2, in_buf, sz_buf ); if (ret_read < 0) { printf("Cannot read\n"); continue; } in_buf[ret_read] = 0; //printf("ret_read=%02x %02x %02x %02x\n",in_buf[0],in_buf[1],in_buf[2],in_buf[3]); //custom echoing service to ignore some special chars like TAB custom_term_echo( (char *)in_buf ); //printf("(%d)%s\n",ret_read,in_buf); if ( (isprint(in_buf[0])) && (in_buf[0]!='?') && (in_buf[0]!='\t')) { //printf("asd %d\n", ret_read); cmd_buf_add( &cmd_in, (char *)in_buf, ret_read ); } //auto complete advice if (CMK_KEYMAP1(9)) { if ( cmd_in.cur_sz == 0 ) { continue; } //cmd_buf_print( &cmd_in, 2 ); cmd_in.buf[cmd_in.cur_sz] = '\n'; cmd_in.buf[cmd_in.cur_sz+1] = 0; #warning "Auto complete" cmd_tab_autocomplete( cmd_in.buf ); //cmd_buf_print( &cmd_in, 2 ); write(1,"$",1); cmd_buf_print( &cmd_in, 1 ); term_cur_set_c( &ts, cmd_in.cur_sz+2 ); continue; } /* if (CMK_KEYMAP1('?')) { cmd_buf_print( &cmd_in, 1 ); } */ if (CMK_KEYMAP1(8) || CMK_KEYMAP1(127)) { cmd_buf_rem1( &cmd_in ); term_cur_set_c( &ts, 0); write(1,"$",1); cmd_buf_print( &cmd_in, 1 ); term_cur_set_c( &ts, cmd_in.cur_sz+2 ); continue; } if (CMK_KEYMAP1(27)) { cmd_buf_print( &cmd_in, 1 ); break; } //exec cmd if (CMK_KEYMAP1('\n')) { int i; cmd_in.buf[cmd_in.cur_sz] = '\n'; cmd_in.buf[cmd_in.cur_sz+1] = 0; #warning "Fix this" /* if ( parse_cmd( ptr, cmd_in.buf) == -1) { continue; } */ /* iter = ptr->next; args = cmd_arg_create( iter ); cmd_tok_destroy( ptr->next ); ptr->next = NULL; */ /* for (i=0; iargc; i++) { printf("ARG:%d TYPE:%d %s\n", i, args->type[i], args->argv[i]); } */ /* if (cmd_exec(tab, args) != 0) { printf("!Unknown command\n"); }*/ err = cmd_mng_exec( &cmd_mng, cmd_in.buf, cmd_in.cur_sz ); if (err!=CMD_EOK) { printf("Unknow command\n"); } //cmd_arg_destroy( args ); cmd_buf_clean( &cmd_in ); write(1,"$",1); } //if (CMK_KEYMAP1(0x7e365b1b)) //pagedown if (CMK_KEYMAP4(0x7e,0x36,0x5b,0x1b)) { char local_cmd[] = "pagedown"; write(1,"\n",1); cmd_buf_clean(&cmd_in); cmd_buf_add(&cmd_in, local_cmd, strlen(local_cmd)); err = cmd_mng_exec( &cmd_mng, cmd_in.buf, cmd_in.cur_sz ); if (err!=CMD_EOK) { printf("Unknow command\n"); } cmd_buf_clean( &cmd_in ); write(1,"$",1); } //pageup if (CMK_KEYMAP4(0x7e,0x35,0x5b,0x1b)) { char local_cmd[] = "pageup\n"; write(1,"\n",1); cmd_buf_clean(&cmd_in); cmd_buf_add(&cmd_in, local_cmd, strlen(local_cmd)); err = cmd_mng_exec( &cmd_mng, cmd_in.buf, cmd_in.cur_sz ); if (err!=CMD_EOK) { printf("Unknow command\n"); } cmd_buf_clean( &cmd_in ); write(1,"$",1); } } cmd_mng_free( &cmd_mng ); term_clr_scr( &ts ); term_set_orig_mode( &ts ); return 0; }