/* * Print a formatted colour message at the bottom of the screen, wait a while */ void wait_message( unsigned int sdelay, const char *fmt, ...) { va_list ap; va_start(ap, fmt); clear_message(); #ifdef HAVE_COLOR fcol(tinrc.col_message); #endif /* HAVE_COLOR */ vsnprintf(mesg, sizeof(mesg), fmt, ap); my_fputs(mesg, stdout); #ifdef HAVE_COLOR fcol(tinrc.col_normal); #endif /* HAVE_COLOR */ cursoron(); my_flush(); (void) sleep(sdelay); /* clear_message(); would be nice, but tin doesn't expect this yet */ va_end(ap); }
size_t my_fwrite(const void *ptr, size_t size, size_t count, t_fle *file) { size_t i; size_t j; const char *tab; if (ptr == NULL || file == NULL || (size * count) > FILE_SZ_MAX || (!(file->fmode & O_WRONLY) && !(file->fmode & O_RDWR))) return (-1); i = 0; j = 0; tab = ptr; while (j < (count * size)) { while (((i + file->csr) < BUFF_SZ) && j < (count * size)) file->buff[i++ + file->csr] = tab[j++]; file->csr += i; file->state = NOT_FLUSHED; if (file->csr >= BUFF_SZ) { my_flush(file); i = 0; } } return ((size_t)j); }
int vrpn_Tracker_Dyna::get_status() { int bytesRead; unsigned char statusBuffer[256]; my_flush(); /* send request for status record */ vrpn_write_characters(serial_fd,(const unsigned char *) "\021", 1); vrpn_drain_output_buffer(serial_fd); vrpn_SleepMsecs(1000.0*2); /* do non-blocking read of status record */ bytesRead = vrpn_read_available_characters(serial_fd, statusBuffer, 8); // T_PDYN_STATUS_RECORD_LENGTH =8; if ( bytesRead == 8 ) { /* we have correct length- check a few chars to make sure this is a valid * record */ if ( ((statusBuffer[0] & lOOO_OOOO) != lOOO_OOOO) || ((statusBuffer[1] & lOOO_OOOO) != lOOO_OOOO) ) return(T_ERROR); /* otherwise, all is well */ return(T_OK); } /* if we get here, we either got too much data or not enough */ /* no data means it's probably disconnected or not turned on */ if ( bytesRead == 0 ) { // fprintf(stderr, "No data\n"); return(T_PDYN_NO_DATA); } /* if we got too much data, chances are that it's in continuous mode */ if ( bytesRead > 8) { fprintf(stderr, "3\n"); return(T_PDYN_SPEW_MODE); } /* if we get here, i have no idea what's going on- could be garbage on the * serial line, wrong baud rate, or that the Dynasight is flaking out. */ return(T_ERROR); } /* t_pdyn_get_status */
/* * Read .newsrc into my_group[]. my_group[] ints point to active[] entries. * If allgroups is set, then my_group[] is completely overwritten, * otherwise, groups are appended. Any bogus groups will be handled * accordingly. Bogus groups will _not_ be subscribed to as a design * principle. * * Returns the numer of lines read(useful for a check newsrc >= oldnewsrc) * < 0 error * >=0 number of lines read */ signed long int read_newsrc( char *newsrc_file, t_bool allgroups) { FILE *fp; char *grp, *seq; int sub, i; signed long line_count = 0; struct stat statbuf; if (allgroups) selmenu.max = skip_newgroups(); /* * make a .newsrc if one doesn't exist & auto subscribe to set groups */ if (stat(newsrc_file, &statbuf) == -1) { if (!create_newsrc(newsrc_file)) return -1L; /* ouch */ auto_subscribe_groups(newsrc_file); } else newsrc_mode = statbuf.st_mode; if ((fp = fopen(newsrc_file, "r")) != NULL) { if (!batch_mode || verbose) wait_message(0, _(txt_reading_newsrc)); while ((grp = tin_fgets(fp, FALSE)) != NULL) { seq = parse_newsrc_line(grp, &sub); line_count++; if (sub == SUBSCRIBED) { if ((i = my_group_add(grp)) >= 0) { if (!active[my_group[i]].bogus) { active[my_group[i]].subscribed = SUB_BOOL(sub); parse_bitmap_seq(&active[my_group[i]], seq); } } else process_bogus(grp); } } fclose(fp); /* If you aborted with 'q', then you get what you get. */ if (cmd_line) { my_fputc('\n', stdout); my_flush(); } } return line_count; }
void clear_message( void) { if (!cmd_line) { MoveCursor(cLINES, 0); CleartoEOLN(); cursoroff(); #ifndef USE_CURSES my_flush(); #endif /* !USE_CURSES */ } }
void ring_bell( void) { #ifdef USE_CURSES if (!cmd_line) beep(); else { #endif /* USE_CURSES */ my_fputc('\007', stdout); my_flush(); #ifdef USE_CURSES } #endif /* USE_CURSES */ }
/* ** Control message from erlang, we handle $f, which is flush. */ static int trace_file_control(ErlDrvData handle, unsigned int command, char* buff, int count, char** res, int res_size) { if (command == 'f') { TraceFileData *data = (TraceFileData *) handle; if (my_flush(data) < 0) { driver_failure_posix(data->port, errno); /* XXX */ } if (res_size < 1) { *res = my_alloc(1); } **res = '\0'; return 1; } return -1; }
void vrpn_Tracker_Dyna::reset() { //static int numResets = 0; // How many resets have we tried?; static char T_PDYN_C_CTL_C[4] ="\003\003\003"; static int T_PDYN_RECORD_LENGTH = 8; vrpn_write_characters(serial_fd, (unsigned char*)T_PDYN_C_CTL_C, strlen(T_PDYN_C_CTL_C)); vrpn_write_characters(serial_fd,(const unsigned char *) "4", 1); // set to polling mode; /* pause 1 second to allow the Dynasight buffer to stabilize */ vrpn_SleepMsecs(1000.0*1); status = get_status(); if ( status != T_OK ) { /* if no data, tracker probably not connected. just bag it. */ if ( status == T_PDYN_NO_DATA ) { fprintf(stderr, "vrpn_Tracker_Dyna::reset(): no data (is tracker turned on?)\n"); status = vrpn_TRACKER_RESETTING; return; } }else { fprintf(stderr, "vrpn_Tracker_Dyna: return valid status report\n"); reportLength = T_PDYN_RECORD_LENGTH; // set it to continues mode; /* clear any leftover data */ my_flush(); /* set the Dynasight to continuous mode */ vrpn_write_characters(serial_fd, (unsigned char*)T_PDYN_C_CTL_C, strlen(T_PDYN_C_CTL_C)); //vrpn_write_characters(serial_fd, (const unsigned char *)"V", 1); vrpn_write_characters(serial_fd, (const unsigned char *)"0", 1); //T_PDYN_C_CONTINUOUS = "V" vrpn_SleepMsecs(1000.0*1); //vrpn_gettimeofday(×tamp, NULL); // Set watchdog now; timestamp.tv_sec = -1; status = vrpn_TRACKER_SYNCING; // We are trying for a new reading; return; } }
int my_fclose(t_fle *file) { if (file == NULL) return (0); gbgc_free(NULL, file->name); if ((file->fmode & O_WRONLY) || (file->fmode & O_RDWR)) my_flush(file); if (file->fd >= 0) { if (close(file->fd) < 0) { gbgc_free(NULL, file); return (0); } } gbgc_free(NULL, file); return (1); }
void spin_cursor( void) { static const char buf[] = "|/-\\|/-\\ "; /* don't remove the tailing space! */ static unsigned short int i = 0; if (batch_mode) return; if (i > 7) i = 0; #ifdef HAVE_COLOR fcol(tinrc.col_message); #endif /* HAVE_COLOR */ my_printf("\b%c", buf[i++]); my_flush(); #ifdef HAVE_COLOR fcol(tinrc.col_normal); #endif /* HAVE_COLOR */ }
/* * progressmeter in % */ void show_progress( const char *txt, long count, long total) { char display[LEN]; int ratio; time_t curr_time; static char last_display[LEN]; static const char *last_txt; static int last_length; static int last_ratio; static long last_total; static time_t last_update; #ifdef HAVE_GETTIMEOFDAY static long last_count; static int average; static int samples; static int sum; static struct timeval last_time; static struct timeval this_time; int time_diff; int secs_left; long count_diff; #endif /* HAVE_GETTIMEOFDAY */ if (batch_mode || count <= 0 || total == 0) return; /* If this is a new progress meter, start recalculating */ if ((last_txt != txt) || (last_total != total)) { last_length = 0; last_ratio = -1; last_display[0] = '\0'; last_update = time(NULL) - 2; } curr_time = time(NULL); ratio = (int) ((count * 100) / total); if ((ratio == last_ratio) && (curr_time - last_update < 2)) /* * return if ratio did not change and less than 1-2 seconds since last * update to reduce output */ return; last_update = curr_time; #ifdef HAVE_GETTIMEOFDAY if (last_length == 0) { /* Don't print a "time remaining" this time */ snprintf(display, sizeof(display), "%s %3d%%", txt, ratio); display[sizeof(display) - 1] = '\0'; last_length = strlen(txt) + 5; /* Reset the variables */ sum = average = samples = 0; } else { /* Get the current time */ gettimeofday(&this_time, NULL); time_diff = (this_time.tv_sec - last_time.tv_sec) * 1000000; time_diff += (this_time.tv_usec - last_time.tv_usec); count_diff = (count - last_count); if (!count_diff) /* avoid div by zero */ count_diff++; /* * Calculate a running average based on the last 20 samples. For the * first 19 samples just add all and divide by the number of samples. * From the 20th sample on use only the last 20 samples to calculate * the running averave. To make things easier we don't want to store * and keep track of all of them, so we assume that the first sample * was close to the current average and substract it from sum. Then, * the new sample is added to the sum and the sum is divided by 20 to * get the new average. */ if (samples == 20) { sum -= average; sum += (time_diff / count_diff); average = sum / 20; } else { sum += (time_diff / count_diff); average = sum / ++samples; } if (average >= 1000000) secs_left = (total - count) * (average / 1000000); else secs_left = ((total - count) * average) / 1000000; if (secs_left < 0) secs_left = 0; /* TODO: -> lang.c, difficult with hardcoded last_length */ snprintf(display, sizeof(display), "%s %3d%% (%d:%02d remaining)", txt, ratio, secs_left / 60, secs_left % 60); last_length = strlen(txt) + 21 + secs_left / 600; } last_count = count; gettimeofday(&last_time, NULL); #else /* HAVE_GETTIMEOFDAY */ snprintf(display, sizeof(display), "%s %3d%%", txt, ratio); #endif /* HAVE_GETTIMEOFDAY */ /* Only display text if it changed from last time */ if (strcmp(display, last_display)) { clear_message(); MoveCursor(cLINES, 0); # ifdef HAVE_COLOR fcol(tinrc.col_message); # endif /* HAVE_COLOR */ my_printf("%s", display); # ifdef HAVE_COLOR fcol(tinrc.col_normal); # endif /* HAVE_COLOR */ my_flush(); STRCPY(last_display, display); } last_txt = txt; last_total = total; last_ratio = ratio; }
void center_line( int line, t_bool inverse, const char *str) { char buffer[256]; int pos; int len; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) int width; wchar_t wbuffer[256]; /* needs same number of elements as buffer */ wchar_t wbuffer2[256]; wchar_t suffix_buf[6]; /* space for TRUNC_TAIL */ #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ STRCPY(buffer, str); /* protect terminal... */ convert_to_printable(buffer); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if ((len = mbstowcs(wbuffer, buffer, ARRAY_SIZE(wbuffer) - 1)) <= 0) len = strlen(buffer); else wbuffer[ARRAY_SIZE(wbuffer) - 1] = (wchar_t) '\0'; if ((width = wcswidth(wbuffer, ARRAY_SIZE(wbuffer) - 1)) <= 0) width = len; #else len = strlen(buffer); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ if (!cmd_line) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (cCOLS >= width) pos = (cCOLS - width) / 2; #else if (cCOLS >= len) pos = (cCOLS - len) / 2; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ else pos = 1; MoveCursor(line, pos); if (inverse) { StartInverse(); my_flush(); } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (width >= cCOLS) { wcspart(wbuffer2, wbuffer, cCOLS - 6, ARRAY_SIZE(wbuffer2) - 5, TRUE); mbstowcs(suffix_buf, TRUNC_TAIL, ARRAY_SIZE(suffix_buf) - 1); wcsncat(wbuffer2, suffix_buf, 4); wcstombs(buffer, wbuffer2, sizeof(buffer) - 1); } #else if (len >= cCOLS) { char *buf; buf = my_strdup(buffer); snprintf(buffer, sizeof(buffer), "%-.*s%s", cCOLS - 6, buf, TRUNC_TAIL); free(buf); } #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ my_fputs(buffer, stdout); if (cmd_line) my_flush(); else { if (inverse) EndInverse(); } }
char * tin_getline( const char *prompt, int number_only, /* 1=positive numbers only, 2=negative too */ const char *str, int max_chars, t_bool passwd, int which_hist) { int c, i, loc, tmp, gl_max; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wint_t wc; #else char *buf = gl_buf; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ is_passwd = passwd; set_xclick_off(); if (prompt == NULL) prompt = ""; gl_buf[0] = 0; /* used as end of input indicator */ gl_fixup(-1, 0); /* this resets gl_fixup */ gl_width = cCOLS - strlen(prompt); gl_prompt = prompt; gl_pos = gl_cnt = 0; if (max_chars == 0) { if (number_only) gl_max = 6; else gl_max = BUF_SIZE; } else gl_max = max_chars; my_fputs(prompt, stdout); cursoron(); my_flush(); if (gl_in_hook) { loc = gl_in_hook(gl_buf); if (loc >= 0) gl_fixup(0, BUF_SIZE); } if (!cmd_line && gl_max == BUF_SIZE) CleartoEOLN(); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (str != NULL) { wchar_t wbuf[LEN]; if (mbstowcs(wbuf, str, ARRAY_SIZE(wbuf) - 1) != (size_t) -1) { wbuf[ARRAY_SIZE(wbuf) - 1] = (wchar_t) '\0'; for (i = 0; wbuf[i]; i++) gl_addwchar(wbuf[i]); } } while ((wc = ReadWch()) != WEOF) { if ((gl_cnt < gl_max) && iswprint(wc)) { if (number_only) { if (iswdigit(wc)) { gl_addwchar(wc); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') { gl_addwchar(wc); } else { ring_bell(); } } else gl_addwchar(wc); } else { c = (int) wc; switch (wc) { #else if (str != NULL) { for (i = 0; str[i]; i++) gl_addchar(str[i]); } while ((c = ReadCh()) != EOF) { c &= 0xff; if ((gl_cnt < gl_max) && my_isprint(c)) { if (number_only) { if (isdigit(c)) { gl_addchar(c); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && c == '-') { gl_addchar(c); } else { ring_bell(); } } else gl_addchar(c); } else { switch (c) { #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ case ESC: /* abort */ #ifdef HAVE_KEY_PREFIX case KEY_PREFIX: #endif /* HAVE_KEY_PREFIX */ switch (get_arrow_key(c)) { case KEYMAP_UP: case KEYMAP_PAGE_UP: hist_prev(which_hist); break; case KEYMAP_PAGE_DOWN: case KEYMAP_DOWN: hist_next(which_hist); break; case KEYMAP_RIGHT: gl_fixup(-1, gl_pos + 1); break; case KEYMAP_LEFT: gl_fixup(-1, gl_pos - 1); break; case KEYMAP_HOME: gl_fixup(-1, 0); break; case KEYMAP_END: gl_fixup(-1, gl_cnt); break; case KEYMAP_DEL: gl_del(0); break; case KEYMAP_INS: #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar((wint_t) ' '); #else gl_addchar(' '); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ break; default: return (char *) 0; } break; case '\n': /* newline */ case '\r': gl_newline(which_hist); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; case CTRL_A: gl_fixup(-1, 0); break; case CTRL_B: gl_fixup(-1, gl_pos - 1); break; case CTRL_D: if (gl_cnt == 0) { gl_buf[0] = 0; my_fputc('\n', stdout); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } else gl_del(0); break; case CTRL_E: gl_fixup(-1, gl_cnt); break; case CTRL_F: gl_fixup(-1, gl_pos + 1); break; case CTRL_H: case DEL: gl_del(-1); break; case TAB: if (gl_tab_hook) { tmp = gl_pos; loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp); if (loc >= 0 || tmp != gl_pos) gl_fixup(loc, tmp); } break; case CTRL_W: gl_kill_back_word(); break; case CTRL_U: gl_fixup(-1, 0); /* FALLTHROUGH */ case CTRL_K: gl_kill(); break; case CTRL_L: case CTRL_R: gl_redraw(); break; case CTRL_N: hist_next(which_hist); break; case CTRL_P: hist_prev(which_hist); break; default: ring_bell(); break; } } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } /* * adds the character c to the input buffer at current location if * the character is in the allowed template of characters */ static void #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar( wint_t wc) #else gl_addchar( int c) #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ { int i; /* * Crashing is always the worst solution IMHO. So as a quick hack, * ignore characters silently, if buffer is full. To allow a final * newline, leave space for one more character. Just a hack too. * This was the original code: * if (gl_cnt >= BUF_SIZE - 1) { error_message("tin_getline: input buffer overflow"); giveup(); } */ if (gl_cnt >= BUF_SIZE - 2) return; for (i = gl_cnt; i >= gl_pos; i--) gl_buf[i + 1] = gl_buf[i]; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[gl_pos] = (wchar_t) wc; #else gl_buf[gl_pos] = c; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ gl_fixup(gl_pos, gl_pos + 1); } /* * Cleans up entire line before returning to caller. A \n is appended. * If line longer than screen, we redraw starting at beginning */ static void gl_newline( int w) { int change = gl_cnt; int len = gl_cnt; int loc = gl_width - 5; /* shifts line back to start position */ if (gl_cnt >= BUF_SIZE - 1) { /* * Like above: avoid crashing if possible. gl_addchar() now * leaves one space left for the newline, so this part of the * code should never be reached. A proper implementation is * desirable though. */ error_message("tin_getline: input buffer overflow"); giveup(); } hist_add(w); /* only adds if nonblank */ if (gl_out_hook) { change = gl_out_hook(gl_buf); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) len = wcslen(gl_buf); #else len = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (loc > len) loc = len; gl_fixup(change, loc); /* must do this before appending \n */ #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[len] = (wchar_t) '\0'; #else gl_buf[len] = '\0'; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } /* * Delete a character. The loc variable can be: * -1 : delete character to left of cursor * 0 : delete character under cursor */ static void gl_del( int loc) { int i; if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) { for (i = gl_pos + loc; i < gl_cnt; i++) gl_buf[i] = gl_buf[i + 1]; gl_fixup(gl_pos + loc, gl_pos + loc); } else ring_bell(); }
/* * This function is used both for redrawing when input changes or for * moving within the input line. The parameters are: * change : the index of the start of changes in the input buffer, * with -1 indicating no changes. * cursor : the desired location of the cursor after the call. * A value of BUF_SIZE can be used to indicate the cursor * should move just past the end of the input line. */ static void gl_fixup( int change, int cursor) { static int gl_shift; /* index of first on screen character */ static int off_right; /* true if more text right of screen */ static int off_left; /* true if more text left of screen */ int left = 0, right = -1; /* bounds for redraw */ int pad; /* how much to erase at end of line */ int backup; /* how far to backup before fixing */ int new_shift; /* value of shift based on cursor */ int extra; /* adjusts when shift (scroll) happens */ int i; if (change == -1 && cursor == 0 && gl_buf[0] == 0) { /* reset */ gl_shift = off_right = off_left = 0; return; } pad = (off_right) ? gl_width - 1 : gl_cnt - gl_shift; /* old length */ backup = gl_pos - gl_shift; if (change >= 0) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_cnt = wcslen(gl_buf); #else gl_cnt = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ if (change > gl_cnt) change = gl_cnt; } if (cursor > gl_cnt) { if (cursor != BUF_SIZE) /* BUF_SIZE means end of line */ ring_bell(); cursor = gl_cnt; } if (cursor < 0) { ring_bell(); cursor = 0; } if (!is_passwd) { if (off_right || (off_left && (cursor < gl_shift + gl_width - SCROLL / 2))) extra = 2; /* shift the scrolling boundary */ else extra = 0; new_shift = cursor + extra + SCROLL - gl_width; if (new_shift > 0) { new_shift /= SCROLL; new_shift *= SCROLL; } else new_shift = 0; if (new_shift != gl_shift) { /* scroll occurs */ gl_shift = new_shift; off_left = (gl_shift) ? 1 : 0; off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0; left = gl_shift; right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt; } else if (change >= 0) { /* no scroll, but text changed */ if (change < gl_shift + off_left) left = gl_shift; else { left = change; backup = gl_pos - change; } off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0; right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt; } pad -= (off_right) ? gl_width - 1 : gl_cnt - gl_shift; pad = (pad < 0) ? 0 : pad; if (left <= right) { /* clean up screen */ for (i = 0; i < backup; i++) my_fputc('\b', stdout); if (left == gl_shift && off_left) { my_fputc('$', stdout); left++; } for (i = left; i < right; i++) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) my_fputwc((wint_t) gl_buf[i], stdout); #else my_fputc(gl_buf[i], stdout); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (off_right) { my_fputc('$', stdout); gl_pos = right + 1; } else { for (i = 0; i < pad; i++) /* erase remains of prev line */ my_fputc(' ', stdout); gl_pos = right + pad; } } i = gl_pos - cursor; /* move to final cursor location */ if (i > 0) { while (i--) my_fputc('\b', stdout); } else { for (i = gl_pos; i < cursor; i++) { #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) my_fputwc((wint_t) gl_buf[i], stdout); #else my_fputc(gl_buf[i], stdout); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } } my_flush(); } gl_pos = cursor; }