static PyObject * delete_text(EditLineObject *self, PyObject *pycount) { const LineInfo *linfo; int cur_line_len; int count; pel_note(__FUNCTION__); /* convert the value */ count = PyLong_AsLong(pycount); if (count < 0) Py_RETURN_NONE; /* get the current line itself */ linfo = el_line(self->el); cur_line_len = linfo->lastchar - linfo->buffer; /* value is bogus as it is out of range */ if (count > cur_line_len) Py_RETURN_NONE; /* rub out the data */ el_deletestr(self->el, count); /* done */ Py_RETURN_NONE; }
static void clear_el_buffer(void) { #ifdef HAVE_EDITLINE const LineInfo *lf = el_line(el); int len = (int)(lf->lastchar - lf->buffer); if (global_profile->batch_mode) return; el_deletestr(el, len); memset((char*)lf->buffer, 0, len); #endif }
static unsigned char console_eofkey(EditLine * el, int ch) { LineInfo *line; /* only exit if empty line */ line = (LineInfo *)el_line(el); if (line->buffer == line->lastchar) { printf("/exit\n\n"); running = thread_running = 0; return CC_EOF; } else { if (line->cursor != line->lastchar) { line->cursor++; el_deletestr(el, 1); } return CC_REDISPLAY; } }
/* * Complete the word at or before point, * 'what_to_do' says what to do with the completion. * \t means do standard completion. * `?' means list the possible completions. * `*' means insert all of the possible completions. * `!' means to do standard completion, and list all possible completions if * there is more than one. * * Note: '*' support is not implemented * '!' could never be invoked */ int fn_complete(EditLine *el, char *(*complet_func)(const char *, int), char **(*attempted_completion_function)(const char *, int, int), const Char *word_break, const Char *special_prefixes, const char *(*app_func)(const char *), size_t query_items, int *completion_type, int *over, int *point, int *end) { const TYPE(LineInfo) *li; Char *temp; char **matches; const Char *ctemp; size_t len; int what_to_do = '\t'; int retval = CC_NORM; if (el->el_state.lastcmd == el->el_state.thiscmd) what_to_do = '?'; /* readline's rl_complete() has to be told what we did... */ if (completion_type != NULL) *completion_type = what_to_do; if (!complet_func) complet_func = fn_filename_completion_function; if (!app_func) app_func = append_char_function; /* We now look backwards for the start of a filename/variable word */ li = FUN(el,line)(el); ctemp = li->cursor; while (ctemp > li->buffer && !Strchr(word_break, ctemp[-1]) && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) ) ctemp--; len = (size_t)(li->cursor - ctemp); temp = el_malloc((len + 1) * sizeof(*temp)); (void)Strncpy(temp, ctemp, len); temp[len] = '\0'; /* these can be used by function called in completion_matches() */ /* or (*attempted_completion_function)() */ if (point != NULL) *point = (int)(li->cursor - li->buffer); if (end != NULL) *end = (int)(li->lastchar - li->buffer); if (attempted_completion_function) { int cur_off = (int)(li->cursor - li->buffer); matches = (*attempted_completion_function)( ct_encode_string(temp, &el->el_scratch), cur_off - (int)len, cur_off); } else matches = NULL; if (!attempted_completion_function || (over != NULL && !*over && !matches)) matches = completion_matches( ct_encode_string(temp, &el->el_scratch), complet_func); if (over != NULL) *over = 0; if (matches) { int i; size_t matches_num, maxlen, match_len, match_display=1; retval = CC_REFRESH; /* * Only replace the completed string with common part of * possible matches if there is possible completion. */ if (matches[0][0] != '\0') { el_deletestr(el, (int) len); FUN(el,insertstr)(el, ct_decode_string(matches[0], &el->el_scratch)); } if (what_to_do == '?') goto display_matches; if (matches[2] == NULL && (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) { /* * We found exact match. Add a space after * it, unless we do filename completion and the * object is a directory. */ FUN(el,insertstr)(el, ct_decode_string((*app_func)(matches[0]), &el->el_scratch)); } else if (what_to_do == '!') { display_matches: /* * More than one match and requested to list possible * matches. */ for(i = 1, maxlen = 0; matches[i]; i++) { match_len = strlen(matches[i]); if (match_len > maxlen) maxlen = match_len; } /* matches[1] through matches[i-1] are available */ matches_num = (size_t)(i - 1); /* newline to get on next line from command line */ (void)fprintf(el->el_outfile, "\n"); /* * If there are too many items, ask user for display * confirmation. */ if (matches_num > query_items) { (void)fprintf(el->el_outfile, "Display all %zu possibilities? (y or n) ", matches_num); (void)fflush(el->el_outfile); if (getc(stdin) != 'y') match_display = 0; (void)fprintf(el->el_outfile, "\n"); } if (match_display) { /* * Interface of this function requires the * strings be matches[1..num-1] for compat. * We have matches_num strings not counting * the prefix in matches[0], so we need to * add 1 to matches_num for the call. */ fn_display_match_list(el, matches, matches_num+1, maxlen); } retval = CC_REDISPLAY; } else if (matches[0][0]) { /* * There was some common match, but the name was * not complete enough. Next tab will print possible * completions. */ el_beep(el); } else { /* lcd is not a valid object - further specification */ /* is needed */ el_beep(el); retval = CC_NORM; } /* free elements of array and the array itself */ for (i = 0; matches[i]; i++) el_free(matches[i]); el_free(matches); matches = NULL; } el_free(temp); return retval; }
static char *cli_complete(EditLine *el, int ch) { int len=0; char *ptr; int nb_matches; char **matches; char wipped; char temp_buffer[2]; int retval = CC_ERROR; int maxlen=0, match_len; LineInfo *lf = (LineInfo *)el_line(el); wipped = *(char*)lf->cursor; *(char *)lf->cursor = '\0'; ptr = (char *)lf->cursor; if (ptr) { while (ptr > lf->buffer) { if (isspace(*ptr)) { ptr++; break; } ptr--; } } len = lf->cursor - ptr; matches = acc_cli_completion_matches((char *)lf->buffer, ptr); if (matches) { /* Set edit line to the content at idx=0 */ if (matches[0][0] != '\0') { if(strcmp(matches[0],"debug")) { el_deletestr(el, (int) len); el_insertstr(el, matches[0]); } retval = CC_REFRESH; } /* Count number of items; determine maximum word length */ for (nb_matches=1; matches[nb_matches]; nb_matches++) { match_len = strlen(matches[nb_matches]); if (match_len > maxlen) maxlen = match_len; } /* The entry at idx=0 doesn't count */ nb_matches--; if (nb_matches == 0) { /* Unlikely... */ el_insertstr(el," "); retval = CC_REFRESH; } else if (nb_matches == 1) { /* Found an exact match */ if(lf->cursor != lf->lastchar) { lf->cursor++; el_deletestr(el, 1); snprintf(temp_buffer,2,"%c",wipped); el_insertstr(el,temp_buffer); } else { el_insertstr(el, " "); } retval = CC_REFRESH; } else { if(lf->cursor != lf->lastchar) { lf->cursor++; el_deletestr(el, 1); snprintf(temp_buffer,2,"%c",wipped); el_insertstr(el,temp_buffer); } /* Print possible matches, skipping idx=0 */ fprintf(stdout, "\n"); acc_cli_display_match_list(matches+1, nb_matches, maxlen); retval = CC_REDISPLAY; } for (nb_matches=0; matches[nb_matches]; nb_matches++) { free(matches[nb_matches]); } free(matches); } return (char *)(long)retval; }
/* * Complete the word at or before point, * 'what_to_do' says what to do with the completion. * \t means do standard completion. * `?' means list the possible completions. * `*' means insert all of the possible completions. * `!' means to do standard completion, and list all possible completions if * there is more than one. * * Note: '*' support is not implemented * '!' could never be invoked */ int fn_complete(EditLine *el, char *(*complet_func)(const char *, int), char **(*attempted_completion_function)(const char *, int, int), const char *word_break, const char *special_prefixes, const char *(*app_func)(const char *), size_t query_items, int *completion_type, int *over, int *point, int *end, const char *(*find_word_start_func)(const char *, const char *), char *(*dequoting_func)(const char *), char *(*quoting_func)(const char *)) { const LineInfo *li; char *temp; char *dequoted_temp; char **matches; const char *ctemp; size_t len; int what_to_do = '\t'; int retval = CC_NORM; if (el->el_state.lastcmd == el->el_state.thiscmd) what_to_do = '?'; /* readline's rl_complete() has to be told what we did... */ if (completion_type != NULL) *completion_type = what_to_do; if (!complet_func) complet_func = fn_filename_completion_function; if (!app_func) app_func = append_char_function; /* We now look backwards for the start of a filename/variable word */ li = el_line(el); if (find_word_start_func) ctemp = find_word_start_func(li->buffer, li->cursor); else { ctemp = li->cursor; while (ctemp > li->buffer && !strchr(word_break, ctemp[-1]) && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) ctemp--; } len = li->cursor - ctemp; #if defined(__SSP__) || defined(__SSP_ALL__) temp = malloc(sizeof(*temp) * (len + 1)); if (temp == NULL) return retval; #else temp = alloca(sizeof(*temp) * (len + 1)); #endif (void)strncpy(temp, ctemp, len); temp[len] = '\0'; if (dequoting_func) { dequoted_temp = dequoting_func(temp); if (dequoted_temp == NULL) return retval; } else dequoted_temp = NULL; /* these can be used by function called in completion_matches() */ /* or (*attempted_completion_function)() */ if (point != 0) *point = (int)(li->cursor - li->buffer); if (end != NULL) *end = (int)(li->lastchar - li->buffer); if (attempted_completion_function) { int cur_off = (int)(li->cursor - li->buffer); matches = (*attempted_completion_function) (dequoted_temp ? dequoted_temp : temp, (int)(cur_off - len), cur_off); } else matches = 0; if (!attempted_completion_function || (over != NULL && !*over && !matches)) matches = completion_matches(dequoted_temp ? dequoted_temp : temp, complet_func); if (over != NULL) *over = 0; if (matches) { int i; size_t matches_num, maxlen, match_len, match_display=1; retval = CC_REFRESH; /* * Only replace the completed string with common part of * possible matches if there is possible completion. */ if (matches[0][0] != '\0') { char *quoted_match; if (quoting_func) { quoted_match = quoting_func(matches[0]); if (quoted_match == NULL) goto free_matches; } else quoted_match = NULL; el_deletestr(el, (int) len); el_insertstr(el, quoted_match ? quoted_match : matches[0]); free(quoted_match); } if (what_to_do == '?') goto display_matches; if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) { /* * We found exact match. Add a space after * it, unless we do filename completion and the * object is a directory. */ el_insertstr(el, (*app_func)(matches[0])); } else if (what_to_do == '!') { display_matches: /* * More than one match and requested to list possible * matches. */ for(i = 1, maxlen = 0; matches[i]; i++) { match_len = strlen(matches[i]); if (match_len > maxlen) maxlen = match_len; } matches_num = i - 1; /* newline to get on next line from command line */ (void)fprintf(el->el_outfile, "\n"); /* * If there are too many items, ask user for display * confirmation. */ if (matches_num > query_items) { (void)fprintf(el->el_outfile, "Display all %zu possibilities? (y or n) ", matches_num); (void)fflush(el->el_outfile); if (getc(stdin) != 'y') match_display = 0; (void)fprintf(el->el_outfile, "\n"); } if (match_display) fn_display_match_list(el, matches, matches_num, maxlen); retval = CC_REDISPLAY; } else if (matches[0][0]) { /* * There was some common match, but the name was * not complete enough. Next tab will print possible * completions. */ el_beep(el); } else { /* lcd is not a valid object - further specification */ /* is needed */ el_beep(el); retval = CC_NORM; } free_matches: /* free elements of array and the array itself */ for (i = 0; matches[i]; i++) free(matches[i]); free(matches); matches = NULL; } free(dequoted_temp); #if defined(__SSP__) || defined(__SSP_ALL__) free(temp); #endif return retval; }
int main(int argc, char *argv[]) { esl_handle_t handle = {{0}}; int count = 0; const char *line = NULL; char cmd_str[1024] = ""; esl_config_t cfg; cli_profile_t *profile = NULL; int rv = 0; #ifndef WIN32 char hfile[512] = "/etc/fs_cli_history"; char cfile[512] = "/etc/fs_cli.conf"; char dft_cfile[512] = "/etc/fs_cli.conf"; #else char hfile[512] = "fs_cli_history"; char cfile[512] = "fs_cli.conf"; char dft_cfile[512] = "fs_cli.conf"; #endif char *home = getenv("HOME"); /* Vars for optargs */ int opt; static struct option options[] = { {"help", 0, 0, 'h'}, {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"user", 1, 0, 'u'}, {"password", 1, 0, 'p'}, {"debug", 1, 0, 'd'}, {"execute", 1, 0, 'x'}, {"loglevel", 1, 0, 'l'}, {"quiet", 0, 0, 'q'}, {0, 0, 0, 0} }; char temp_host[128]; int argv_host = 0; char temp_user[256]; char temp_pass[128]; int argv_pass = 0 ; int argv_user = 0 ; int temp_port = 0; int argv_port = 0; int temp_log = -1; int argv_error = 0; int argv_exec = 0; char argv_command[256] = ""; char argv_loglevel[128] = ""; int argv_quiet = 0; strncpy(internal_profile.host, "127.0.0.1", sizeof(internal_profile.host)); strncpy(internal_profile.pass, "ClueCon", sizeof(internal_profile.pass)); strncpy(internal_profile.name, "internal", sizeof(internal_profile.name)); internal_profile.port = 8021; set_fn_keys(&internal_profile); if (home) { snprintf(hfile, sizeof(hfile), "%s/.fs_cli_history", home); snprintf(cfile, sizeof(cfile), "%s/.fs_cli_conf", home); } signal(SIGINT, handle_SIGINT); #ifdef SIGQUIT signal(SIGQUIT, handle_SIGQUIT); #endif esl_global_set_default_logger(6); /* default debug level to 6 (info) */ for(;;) { int option_index = 0; opt = getopt_long(argc, argv, "H:U:P:S:u:p:d:x:l:qh?", options, &option_index); if (opt == -1) break; switch (opt) { case 'H': esl_set_string(temp_host, optarg); argv_host = 1; break; case 'P': temp_port= atoi(optarg); if (temp_port > 0 && temp_port < 65536){ argv_port = 1; } else { printf("ERROR: Port must be in range 1 - 65535\n"); argv_error = 1; } break; case 'u': esl_set_string(temp_user, optarg); argv_user = 1; break; case 'p': esl_set_string(temp_pass, optarg); argv_pass = 1; break; case 'd': temp_log=atoi(optarg); if (temp_log < 0 || temp_log > 7){ printf("ERROR: Debug level should be 0 - 7.\n"); argv_error = 1; } else { esl_global_set_default_logger(temp_log); } break; case 'x': argv_exec = 1; esl_set_string(argv_command, optarg); break; case 'l': esl_set_string(argv_loglevel, optarg); break; case 'q': argv_quiet = 1; break; case 'h': case '?': print_banner(stdout); usage(argv[0]); return 0; default: opt = 0; } } if (argv_error){ printf("\n"); return usage(argv[0]); } if (!(rv = esl_config_open_file(&cfg, cfile))) { rv = esl_config_open_file(&cfg, dft_cfile); } if (rv) { char *var, *val; char cur_cat[128] = ""; while (esl_config_next_pair(&cfg, &var, &val)) { if (strcmp(cur_cat, cfg.category)) { esl_set_string(cur_cat, cfg.category); esl_set_string(profiles[pcount].name, cur_cat); esl_set_string(profiles[pcount].host, "localhost"); esl_set_string(profiles[pcount].pass, "ClueCon"); profiles[pcount].port = 8021; set_fn_keys(&profiles[pcount]); esl_log(ESL_LOG_DEBUG, "Found Profile [%s]\n", profiles[pcount].name); pcount++; } if (!strcasecmp(var, "host")) { esl_set_string(profiles[pcount-1].host, val); } else if (!strcasecmp(var, "user")) { esl_set_string(profiles[pcount-1].user, val); } else if (!strcasecmp(var, "password")) { esl_set_string(profiles[pcount-1].pass, val); } else if (!strcasecmp(var, "port")) { int pt = atoi(val); if (pt > 0) { profiles[pcount-1].port = (esl_port_t)pt; } } else if (!strcasecmp(var, "debug")) { int dt = atoi(val); if (dt > -1 && dt < 8){ profiles[pcount-1].debug = dt; } } else if(!strcasecmp(var, "loglevel")) { esl_set_string(profiles[pcount-1].loglevel, val); } else if(!strcasecmp(var, "quiet")) { profiles[pcount-1].quiet = esl_true(val); } else if (!strncasecmp(var, "key_F", 5)) { char *key = var + 5; if (key) { int i = atoi(key); if (i > 0 && i < 13) { profiles[pcount-1].console_fnkeys[i - 1] = strdup(val); } } } } esl_config_close_file(&cfg); } if (optind < argc) { get_profile(argv[optind], &profile); } if (!profile) { if (get_profile("default", &profile)) { esl_log(ESL_LOG_DEBUG, "profile default does not exist using builtin profile\n"); profile = &internal_profile; } } if (temp_log < 0 ) { esl_global_set_default_logger(profile->debug); } if (argv_host) { esl_set_string(profile->host, temp_host); } if (argv_port) { profile->port = (esl_port_t)temp_port; } if (argv_user) { esl_set_string(profile->user, temp_user); } if (argv_pass) { esl_set_string(profile->pass, temp_pass); } if (*argv_loglevel) { esl_set_string(profile->loglevel, argv_loglevel); profile->quiet = 0; } esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host); if (argv_host) { if (argv_port && profile->port != 8021) { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s:%u@%s> ", profile->host, profile->port, profile->name); } else { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s@%s> ", profile->host, profile->name); } } else { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", profile->name); } if (esl_connect(&handle, profile->host, profile->port, profile->user, profile->pass)) { esl_global_set_default_logger(7); esl_log(ESL_LOG_ERROR, "Error Connecting [%s]\n", handle.err); if (!argv_exec) usage(argv[0]); return -1; } if (argv_exec){ const char *err = NULL; snprintf(cmd_str, sizeof(cmd_str), "api %s\n\n", argv_command); esl_send_recv(&handle, cmd_str); if (handle.last_sr_event) { if (handle.last_sr_event->body) { printf("%s\n", handle.last_sr_event->body); } else if ((err = esl_event_get_header(handle.last_sr_event, "reply-text")) && !strncasecmp(err, "-err", 3)) { printf("Error: %s!\n", err + 4); } } esl_disconnect(&handle); return 0; } global_handle = &handle; global_profile = profile; esl_thread_create_detached(msg_thread_run, &handle); #ifdef HAVE_EDITLINE el = el_init(__FILE__, stdout, stdout, stdout); el_set(el, EL_PROMPT, &prompt); el_set(el, EL_EDITOR, "emacs"); myhistory = history_init(); el_set(el, EL_ADDFN, "f1-key", "F1 KEY PRESS", console_f1key); el_set(el, EL_ADDFN, "f2-key", "F2 KEY PRESS", console_f2key); el_set(el, EL_ADDFN, "f3-key", "F3 KEY PRESS", console_f3key); el_set(el, EL_ADDFN, "f4-key", "F4 KEY PRESS", console_f4key); el_set(el, EL_ADDFN, "f5-key", "F5 KEY PRESS", console_f5key); el_set(el, EL_ADDFN, "f6-key", "F6 KEY PRESS", console_f6key); el_set(el, EL_ADDFN, "f7-key", "F7 KEY PRESS", console_f7key); el_set(el, EL_ADDFN, "f8-key", "F8 KEY PRESS", console_f8key); el_set(el, EL_ADDFN, "f9-key", "F9 KEY PRESS", console_f9key); el_set(el, EL_ADDFN, "f10-key", "F10 KEY PRESS", console_f10key); el_set(el, EL_ADDFN, "f11-key", "F11 KEY PRESS", console_f11key); el_set(el, EL_ADDFN, "f12-key", "F12 KEY PRESS", console_f12key); el_set(el, EL_ADDFN, "EOF-key", "EOF (^D) KEY PRESS", console_eofkey); el_set(el, EL_BIND, "\033OP", "f1-key", NULL); el_set(el, EL_BIND, "\033OQ", "f2-key", NULL); el_set(el, EL_BIND, "\033OR", "f3-key", NULL); el_set(el, EL_BIND, "\033OS", "f4-key", NULL); el_set(el, EL_BIND, "\033[11~", "f1-key", NULL); el_set(el, EL_BIND, "\033[12~", "f2-key", NULL); el_set(el, EL_BIND, "\033[13~", "f3-key", NULL); el_set(el, EL_BIND, "\033[14~", "f4-key", NULL); el_set(el, EL_BIND, "\033[15~", "f5-key", NULL); el_set(el, EL_BIND, "\033[17~", "f6-key", NULL); el_set(el, EL_BIND, "\033[18~", "f7-key", NULL); el_set(el, EL_BIND, "\033[19~", "f8-key", NULL); el_set(el, EL_BIND, "\033[20~", "f9-key", NULL); el_set(el, EL_BIND, "\033[21~", "f10-key", NULL); el_set(el, EL_BIND, "\033[23~", "f11-key", NULL); el_set(el, EL_BIND, "\033[24~", "f12-key", NULL); el_set(el, EL_BIND, "\004", "EOF-key", NULL); el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); el_set(el, EL_BIND, "^I", "ed-complete", NULL); if (myhistory == 0) { esl_log(ESL_LOG_ERROR, "history could not be initialized\n"); goto done; } history(myhistory, &ev, H_SETSIZE, 800); el_set(el, EL_HIST, history, myhistory); history(myhistory, &ev, H_LOAD, hfile); el_source(el, NULL); #endif #ifdef WIN32 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { wOldColorAttrs = csbiInfo.wAttributes; } #endif if (!argv_quiet && !profile->quiet) { snprintf(cmd_str, sizeof(cmd_str), "log %s\n\n", profile->loglevel); esl_send_recv(&handle, cmd_str); } print_banner(stdout); esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n"); printf("%s\n", handle.last_sr_reply); while (running) { #ifdef HAVE_EDITLINE line = el_gets(el, &count); #else line = basic_gets(&count); #endif if (count > 1) { if (!esl_strlen_zero(line)) { char *cmd = strdup(line); char *p; #ifdef HAVE_EDITLINE const LineInfo *lf = el_line(el); char *foo = (char *) lf->buffer; #endif if ((p = strrchr(cmd, '\r')) || (p = strrchr(cmd, '\n'))) { *p = '\0'; } assert(cmd != NULL); #ifdef HAVE_EDITLINE history(myhistory, &ev, H_ENTER, line); #endif if (process_command(&handle, cmd)) { running = 0; } #ifdef HAVE_EDITLINE el_deletestr(el, strlen(foo) + 1); memset(foo, 0, strlen(foo)); #endif free(cmd); } } usleep(1000); } #ifdef HAVE_EDITLINE done: history(myhistory, &ev, H_SAVE, hfile); /* Clean up our memory */ history_end(myhistory); el_end(el); #endif esl_disconnect(&handle); thread_running = 0; return 0; }
static unsigned char esl_console_complete(const char *buffer, const char *cursor) { char cmd_str[2048] = ""; unsigned char ret = CC_REDISPLAY; char *dup = strdup(buffer); char *buf = dup; int pos = 0, sc = 0; char *p; if (!esl_strlen_zero(cursor) && !esl_strlen_zero(buffer)) { pos = (int)(cursor - buffer); } if (pos > 0) { *(buf + pos) = '\0'; } if ((p = strchr(buf, '\r')) || (p = strchr(buf, '\n'))) { *p = '\0'; } while (*buf == ' ') { buf++; sc++; } #ifdef HAVE_EDITLINE if (!*buf && sc) { el_deletestr(el, sc); } #endif sc = 0; p = end_of_p(buf); while(p >= buf && *p == ' ') { sc++; p--; } #ifdef HAVE_EDITLINE if (sc > 1) { el_deletestr(el, sc - 1); *(p + 2) = '\0'; } #endif if (*cursor) { snprintf(cmd_str, sizeof(cmd_str), "api console_complete c=%ld;%s\n\n", (long)pos, buf); } else { snprintf(cmd_str, sizeof(cmd_str), "api console_complete %s\n\n", buf); } esl_send_recv(global_handle, cmd_str); if (global_handle->last_sr_event && global_handle->last_sr_event->body) { char *r = global_handle->last_sr_event->body; char *w, *p1; if (r) { if ((w = strstr(r, "\n\nwrite="))) { int len = 0; *w = '\0'; w += 8; len = atoi(w); if ((p1= strchr(w, ':'))) { w = p1+ 1; } printf("%s\n\n\n", r); #ifdef HAVE_EDITLINE el_deletestr(el, len); el_insertstr(el, w); #else #ifdef _MSC_VER console_bufferInput(0, len, (char*)buffer, DELETE_REFRESH_OP); console_bufferInput(w, (int)strlen(w), (char*)buffer, 0); #endif #endif } else { printf("%s\n", r); #ifdef _MSC_VER console_bufferInput(0, 0, (char*)buffer, DELETE_REFRESH_OP); #endif } } fflush(stdout); } esl_safe_free(dup); return ret; }