📄 mal_readline.c
字号:
#line 77 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"#include "mal_config.h"#include "mal.h"#undef PATHLENGTH#include "mal_client.h"#include "mal_scenario.h"/* #define _MAL_READLINE_DEBUG */#ifdef HAVE_LIBREADLINE#include <readline/readline.h>#include <readline/history.h>#include "mal_readline.h"#include "mal_debugger.h"void init_readline(void);void deinit_readline(void);rl_completion_func_t *suspend_completion(void);void continue_completion(rl_completion_func_t * func);#ifdef HAVE_STRINGS_H#include <strings.h> /* for strncasecmp */#endifstatic const char *mal_commands[] = { "address", "atom", "barrier", "catch", "command", "comment", "exit", "end", "function", "factory", "leave", "pattern", "module", "raise", "redo", 0};const char *mdb_commands[] = { "atoms", "break", "breakpoints", "call", "continue", "delete", "down", "exit", "finish", "help", "info", "io", "list", "List", "next", "module", "modules", "optimizer", "print", "quit", "run", "step", "trace", "timer", "up", "var", "where", 0};static int malcommandlimit = 15;static void mal_help_display(char **msg, int a, int b){ int i; (void) msg; (void) a; (void) b; for(i=0;i<a; i++) stream_printf(GDKout,"%s\n",msg[i]); stream_printf(GDKout,"%s",rl_line_buffer);}static int mal_help(int a, int b){ char **msg,*c; int i; (void) a; (void) b; c= rl_line_buffer+strlen(rl_line_buffer)-1; while( c > rl_line_buffer && isspace(*c)) c--; while( c > rl_line_buffer && !isspace(*c)) c--; msg= getHelp(MCgetClient()->nspace,c,0); stream_printf(GDKout,"\n"); for(i=0; msg[i]; i++){ stream_printf(GDKout,"%s\n",msg[i]); GDKfree(msg[i]); } GDKfree(msg); return 0;}#line 188 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"static char *mal_command_generator(const char *text, int state){ static int index, len, last; static char **msg =0; const char *name; char buf[BUFSIZ]; int i; /* we pick our own portion of the linebuffer */ text= rl_line_buffer+strlen(rl_line_buffer)-1; while( text > rl_line_buffer && ! isspace((int) *text)) text--; if( strlen(text)< BUFSIZ){ strcpy(buf,text); text= buf; }#ifdef _MAL_READLINE_DEBUG printf("expand:%d [%d] %s \n",state,(int)strlen(text),text);#endif if (!state) { index = 0; last = 0; len = strlen(text); if( msg){ for(i=0; msg[i]; i++) GDKfree(msg[i]); GDKfree(msg); } msg = 0; } if( mdbSession() ){ while ( (name = mdb_commands[index++]) ){ if( #line 182 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"#ifdef HAVE_STRNCASECMP (strncasecmp(name, text, len) == 0)#else (strncmp(name, text, len) == 0)#endif#line 224 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx" ) return strdup(name); } return NULL; } while (index < malcommandlimit && (name = mal_commands[index++])) { if( #line 182 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"#ifdef HAVE_STRNCASECMP (strncasecmp(name, text, len) == 0)#else (strncmp(name, text, len) == 0)#endif#line 230 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx" ) return strdup(name); } if( msg == 0){ msg= getHelp(MCgetClient()->nspace,(str)(text),1); last =0; } if( msg[last]){ last++; mal_unquote(msg[last-1]); return strdup(msg[last-1]); } return NULL;}static char **mal_completion(const char *text, int start, int end){ (void) start; (void) end; /* FIXME: Nice, context-sensitive completion strategy should go here */ return rl_completion_matches(text, mal_command_generator);}rl_completion_func_t *suspend_completion(void){ rl_completion_func_t *func = rl_attempted_completion_function; rl_attempted_completion_function = NULL; return func;}voidcontinue_completion(rl_completion_func_t * func){ rl_attempted_completion_function = func;}voidinit_readline(void){ str history = MCgetClient()->history; /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "MonetDB"; /* recognize the help function, should react to <FCN-2> */ rl_bind_key('\033',mal_help); /* Tell the completer that we want to try our own completion before std completion (filename) kicks in. */ rl_attempted_completion_function = mal_completion; rl_completion_display_matches_hook= mal_help_display; rl_completion_append_character=0; read_history(history);}voiddeinit_readline(void){ str history = MCgetClient()->history; if (history) { write_history(history); }}#endif /* HAVE_LIBREADLINE */#line 299 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"#ifndef S_ISCHR#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)#endif#ifdef HAVE_TERMIOS_H#include <termios.h>#endifstatic voidshowCommands(void){ printf("?\t - show this message\n");#ifdef HAVE_LIBREADLINE printf("!\t - show the history\n");#endif printf("<file\t - read input from file\n"); printf(">file\t - save response in file\n"); printf(">\t - response to terminal\n"); printf("cd\t - change directory\n"); printf("\\q\t- terminate session\n");}#ifdef HAVE_LIBREADLINEstatic int initReadline;#endifchar *getConsoleInput(const char *prompt, int linemode, int exit_on_error){ char *line = NULL; char *buf = NULL; size_t length; Client c; (void) exit_on_error; (void) linemode; do {#ifdef HAVE_LIBREADLINE if (prompt) { /* rl_completion_func_t *func = NULL;*/ if (buf) free(buf); buf = readline(prompt); /* add a newline to the end since that makes further processing easier */ if (buf) { add_history(buf); length = strlen(buf); buf = realloc(buf, length + 2); buf[length++] = '\n'; buf[length] = 0; } line = buf; } else#endif {#ifndef HAVE_LIBREADLINE if (prompt) { fputs(prompt, stdout); fflush(stdout); }#endif if (buf == NULL) buf= malloc(BUFSIZ); line = fgets(buf, BUFSIZ, stdin); } if (line == NULL) { /* end of file */ if (buf) free(buf); return 0; } else length = strlen(line); if (length > 0 ) { /* test for special commands */ while (length > 0 && (*line & ~0x7F) == 0 && isspace((int) *line)) { line++; length--; } /* in the switch, use continue if the line was processed, use break to send to parser */ switch (*line) { case '\0': /* empty line */ break; case '\\': switch (line[1]) { case 'q': free(buf); return 0; default: break; } line= NULL; break; case '<': /* read commands from file */ if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; /* doFile(mid, line + 1, 0);*/ line= NULL; continue; case '>': /* redirect output to file */ line++; length--; if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; c = MCgetClient(); if (c->fdout && c->fdout != GDKout && c->fdout != GDKerr){ close_stream(c->fdout); c->fdout= 0; } if (length == 0 || strcmp(line, "stdout") == 0) c->fdout = GDKout; else if (strcmp(line, "stderr") == 0) c->fdout = GDKerr; else if ((c->fdout = open_wastream(line)) == NULL) { c->fdout = GDKout; stream_printf(GDKerr, "Cannot open %s\n", line); } line = NULL; continue; case 'c': /* cd command? */ if (line[1] == 'd' && (line[2] & ~0x7F) == 0 && isspace((int) line[2])) { if (line[length - 1] == '\n') line[--length] = 0; if (line[length - 1] == '\r') line[--length] = 0; if (chdir(line + 3) < 0) perror(line); line = NULL; continue; } break;#ifdef HAVE_LIBREADLINE case '!': { char *nl; Client c= MCgetClient(); int i; if(line[1]=='\n') { for(i=0; i< history_length; i++){ nl= history_get(i)? history_get(i)->line:0; if( nl) stream_printf(c->fdout, "%d %s\n", i, nl); } line = NULL; } else if( history_expand(line,&nl) ==1 ) { stream_printf(c->fdout,"#%s",nl); line= nl; } else line= NULL; } continue;#endif case '?': if( !isspace( (int) line[1]) ) showHelp( MCgetClient()->nspace,line+1, MCgetClient()->fdout); else showCommands(); line= NULL; continue; } } } while (line == NULL); return line;}int readConsole(Client cntxt){ /* execute from stdin */ struct stat statb; char *buf; if( cntxt->promptlength == 0) return -1; if( cntxt->fdin->s == cntxt->console->s){ if ( !(fstat(fileno(stdin), &statb) == 0 && S_ISCHR(statb.st_mode)) ) return -1; } /* read lines and move string to client buffer. */#ifdef HAVE_LIBREADLINE if( initReadline ==0){ init_readline(); using_history(); stifle_history(1000); initReadline =1 ; }#endif buf= getConsoleInput(cntxt->prompt, 0, 1); if( buf) { int len= strlen(buf); if( len >= (int) cntxt->fdin->size) { /* extremly dirty inplace buffer overwriting */ cntxt->fdin->buf= realloc(cntxt->fdin->buf, len+1); cntxt->fdin->len = len; cntxt->fdin->size = len; } strcpy(cntxt->fdin->buf, buf); cntxt->fdin->pos = 0; return 1; } else { cntxt->fdin->eof = 1;#ifdef HAVE_LIBREADLINE if( initReadline ){ deinit_readline(); initReadline= 0; }#endif } return -1;}#line 524 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_readline.mx"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -