00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static int gl_tab(char *buf, int offset, int *loc);
00233
00234
00235
00236 char *Getline(const char *prompt);
00237 char *Getlinem(int mode, const char *prompt);
00238 void Gl_config(const char *which, int value);
00239 void Gl_setwidth(int w);
00240 void Gl_windowchanged();
00241 void Gl_histinit(char *file);
00242 void Gl_histadd(char *buf);
00243
00244 int (*Gl_in_hook)(char *buf) = 0;
00245 int (*Gl_out_hook)(char *buf) = 0;
00246 int (*Gl_tab_hook)(char *buf, int prompt_width, int *loc) = gl_tab;
00247 int (*Gl_beep_hook)() = 0;
00248 int (*Gl_in_key)(int ch) = 0;
00249
00250
00251
00252 #include <string.h>
00253 #include <ctype.h>
00254 #include <errno.h>
00255 #include <signal.h>
00256 #include <stdlib.h>
00257 #include <stdio.h>
00258
00259
00260
00261 #define BUF_SIZE 1024
00262
00263 static int gl_init_done = -1;
00264 static int gl_notty = 0;
00265 static int gl_eof = 0;
00266 static int gl_termw = 80;
00267 static int gl_scroll = 27;
00268 static int gl_width = 0;
00269 static int gl_extent = 0;
00270 static int gl_overwrite = 0;
00271 static int gl_no_echo = 0;
00272 static int gl_passwd = 0;
00273 static int gl_erase_line = 0;
00274 static int gl_pos, gl_cnt = 0;
00275 static char gl_buf[BUF_SIZE];
00276 static char gl_killbuf[BUF_SIZE]="";
00277 static const char *gl_prompt;
00278 static char gl_intrc = 0;
00279 static char gl_quitc = 0;
00280 static char gl_suspc = 0;
00281 static char gl_dsuspc = 0;
00282 static int gl_search_mode = 0;
00283 static int gl_savehist = 0;
00284 static char gl_histfile[256];
00285
00286 static void gl_init();
00287 static void gl_cleanup();
00288 static void gl_char_init();
00289 static void gl_char_cleanup();
00290
00291 static void gl_addchar(int c);
00292 static void gl_del(int loc);
00293 static void gl_error(char *buf);
00294 static void gl_fixup(const char *p, int c, int cur);
00295 static int gl_getc();
00296 static void gl_kill();
00297 static void gl_newline();
00298 static void gl_putc(int c);
00299 static void gl_puts(const char *buf);
00300 static void gl_redraw();
00301 static void gl_transpose();
00302 static void gl_yank();
00303
00304 static int is_whitespace(char c);
00305 static void gl_back_1_word();
00306 static void gl_kill_1_word();
00307 static void gl_kill_back_1_word();
00308 static void gl_kill_region(int i, int j);
00309 static void gl_fwd_1_word();
00310 static void gl_set_mark();
00311 static void gl_exch();
00312 static void gl_wipe();
00313 static int gl_mark = -1;
00314
00315 static void hist_init();
00316 static char *hist_next();
00317 static char *hist_prev();
00318 static char *hist_save(char *p);
00319
00320 static void search_addchar(int c);
00321 static void search_term();
00322 static void search_back(int s);
00323 static void search_forw(int s);
00324
00325
00326
00327 #ifdef MSDOS
00328 #include <bios.h>
00329 #endif
00330
00331 #ifdef WIN32
00332 # define MSDOS
00333 # include <io.h>
00334 # include <windows.h>
00335 #endif
00336
00337 #if defined(_AIX) || defined(__Lynx__) || defined(__APPLE__) || \
00338 defined(__OpenBSD__)
00339 #define unix
00340 #endif
00341
00342 #if defined(__hpux) || defined(__osf__)
00343 #ifndef unix
00344 #define unix
00345 #endif
00346 #endif
00347
00348 #ifdef unix
00349 #include <unistd.h>
00350 #if !defined(__osf__) && !defined(_AIX)
00351 #include <sys/ioctl.h>
00352 #endif
00353
00354 #if defined(__linux__) && defined(__powerpc__)
00355 # define R__PPCLINUX
00356 #endif
00357 #if defined(__linux__) && defined(__alpha__)
00358 # define R__ALPHALINUX
00359 #endif
00360 #if defined(__linux__) && defined(__mips)
00361 # define R__MIPSLINUX
00362 #endif
00363
00364 #if defined(TIOCGETP) && !defined(__sgi) && !defined(R__PPCLINUX) && \
00365 !defined(R__ALPHALINUX) && !defined(R__MIPSLINUX)
00366 #include <sgtty.h>
00367 struct sgttyb new_tty, old_tty;
00368 struct tchars tch;
00369 struct ltchars ltch;
00370 #else
00371 #ifdef SIGTSTP
00372 #include <termios.h>
00373 #if defined(__sun) || defined(__sgi) || defined(R__PPCLINUX) || \
00374 defined(R__ALPHALINUX) || defined(R__MIPSLINUX)
00375 #undef TIOCGETP
00376 #undef TIOCSETP
00377 #endif
00378 struct termios new_termios, old_termios;
00379 #else
00380 #include <termio.h>
00381 struct termio new_termio, old_termio;
00382 #endif
00383 #endif
00384 #endif
00385
00386 #ifdef VMS
00387 #include <descrip.h>
00388 #include <ttdef.h>
00389 #include <iodef.h>
00390 #include <starlet.h>
00391 #include <unistd.h>
00392 #include unixio
00393
00394 static int setbuff[2];
00395 static short chan = -1;
00396 struct dsc$descriptor_s descrip;
00397 #endif
00398
00399 void
00400 Gl_config(const char *which, int value)
00401 {
00402 if (strcmp(which, "noecho") == 0)
00403 gl_no_echo = value;
00404 else if (strcmp(which, "erase") == 0)
00405 gl_erase_line = value;
00406 else
00407 printf("gl_config: %s ?\n", which);
00408 }
00409
00410 static void
00411 gl_char_init()
00412 {
00413 if (gl_notty) return;
00414 #ifdef unix
00415 #ifdef TIOCGETP
00416 ioctl(0, TIOCGETC, &tch);
00417 ioctl(0, TIOCGLTC, <ch);
00418 gl_intrc = tch.t_intrc;
00419 gl_quitc = tch.t_quitc;
00420 gl_suspc = ltch.t_suspc;
00421 gl_dsuspc = ltch.t_dsuspc;
00422 ioctl(0, TIOCGETP, &old_tty);
00423 new_tty = old_tty;
00424 new_tty.sg_flags |= RAW;
00425 new_tty.sg_flags &= ~ECHO;
00426 ioctl(0, TIOCSETP, &new_tty);
00427 #else
00428 #ifdef SIGTSTP
00429 tcgetattr(0, &old_termios);
00430 gl_intrc = old_termios.c_cc[VINTR];
00431 gl_quitc = old_termios.c_cc[VQUIT];
00432 #ifdef VSUSP
00433 gl_suspc = old_termios.c_cc[VSUSP];
00434 #endif
00435 #ifdef VDSUSP
00436 gl_dsuspc = old_termios.c_cc[VDSUSP];
00437 #endif
00438 new_termios = old_termios;
00439 new_termios.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
00440 new_termios.c_iflag |= (IGNBRK|IGNPAR);
00441 new_termios.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
00442 new_termios.c_cc[VMIN] = 1;
00443 new_termios.c_cc[VTIME] = 0;
00444 tcsetattr(0, TCSANOW, &new_termios);
00445 #else
00446 ioctl(0, TCGETA, &old_termio);
00447 gl_intrc = old_termio.c_cc[VINTR];
00448 gl_quitc = old_termio.c_cc[VQUIT];
00449 new_termio = old_termio;
00450 new_termio.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
00451 new_termio.c_iflag |= (IGNBRK|IGNPAR);
00452 new_termio.c_lflag &= ~(ICANON|ISIG|ECHO);
00453 new_termio.c_cc[VMIN] = 1;
00454 new_termio.c_cc[VTIME] = 0;
00455 ioctl(0, TCSETA, &new_termio);
00456 #endif
00457 #endif
00458 #endif
00459
00460 #ifdef MSDOS
00461 gl_intrc = 'C' - '@';
00462 gl_quitc = 'Q' - '@';
00463
00464 #endif
00465
00466 #ifdef vms
00467 descrip.dsc$w_length = strlen("tt:");
00468 descrip.dsc$b_dtype = DSC$K_DTYPE_T;
00469 descrip.dsc$b_class = DSC$K_CLASS_S;
00470 descrip.dsc$a_pointer = "tt:";
00471 (void)sys$assign(&descrip,&chan,0,0);
00472 (void)sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,setbuff,8,0,0,0,0);
00473 setbuff[1] |= TT$M_NOECHO;
00474 (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);
00475 #endif
00476 }
00477
00478 static void
00479 gl_char_cleanup()
00480 {
00481 if (gl_notty) return;
00482 #ifdef unix
00483 #ifdef TIOCSETP
00484 ioctl(0, TIOCSETP, &old_tty);
00485 #else
00486 #ifdef SIGTSTP
00487 tcsetattr(0, TCSANOW, &old_termios);
00488 #else
00489 ioctl(0, TCSETA, &old_termio);
00490 #endif
00491 #endif
00492 #endif
00493
00494 #ifdef vms
00495 setbuff[1] &= ~TT$M_NOECHO;
00496 (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);
00497 sys$dassgn(chan);
00498 chan = -1;
00499 #endif
00500 }
00501
00502 #if defined(MSDOS) && !defined(WIN32)
00503 # include <conio.h>
00504 int pause_()
00505 {
00506 int first_char;
00507 first_char = _getch();
00508 if (first_char == 0 || first_char == 0xE0) first_char = -_getch();
00509 return first_char;
00510 }
00511 #endif
00512
00513 #if defined(MSDOS) && defined(WIN32)
00514 int pause_()
00515 {
00516 static HANDLE hConsoleInput = NULL;
00517 static iCharCount = 0;
00518 static int chLastChar = 0;
00519
00520 DWORD cRead;
00521
00522 INPUT_RECORD pirBuffer;
00523 KEY_EVENT_RECORD *KeyEvent= (KEY_EVENT_RECORD *)&(pirBuffer.Event);
00524
00525 if (!hConsoleInput) hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
00526
00527 if (iCharCount) iCharCount--;
00528 else {
00529 chLastChar = 0;
00530 while (chLastChar == 0) {
00531 if (!ReadConsoleInput(hConsoleInput,
00532 &pirBuffer,
00533 1,
00534 &cRead
00535 )) return 0;
00536
00537 if (pirBuffer.EventType == KEY_EVENT && KeyEvent->bKeyDown == TRUE){
00538 iCharCount = KeyEvent->wRepeatCount - 1;
00539 chLastChar = ((int) (KeyEvent->uChar).AsciiChar & 0xffff);
00540 if (chLastChar)
00541 OemToCharBuff((char const *)&chLastChar,(char *)&chLastChar,1);
00542 else
00543 chLastChar = - (KeyEvent->wVirtualScanCode);
00544
00545 }
00546 }
00547 }
00548 return chLastChar;
00549
00550 }
00551 #endif
00552
00553
00554 static int
00555 gl_getc()
00556
00557 {
00558 #ifdef MSDOS
00559 # define k_ctrl_C 3
00560 # define k_ctrl_Z 26
00561 # define k_ctrl_Q 17
00562 # define k_ctrl_K 11
00563 # define k_rt_arr -77
00564 # define k_lt_arr -75
00565 # define k_up_arr -72
00566 # define k_dn_arr -80
00567 # define k_PGUP -73
00568 # define k_PGDW -81
00569 # define k_HOME -71
00570 # define k_END -79
00571 # define k_INS -82
00572 # define k_DEL -83
00573 # define k_ENTER 13
00574 # define k_CR 13
00575 # define k_BS 8
00576 # define k_ESC 27
00577 # define k_alt_H -35
00578 # define k_beep 7
00579 # ifndef WIN32
00580 int get_cursor__(int *,int *);
00581 int display_off__(int *);
00582 int display_on__();
00583 int locate_(int *,int *);
00584 int ixc, iyc;
00585 # endif
00586 int pause_();
00587 #endif
00588
00589 int c;
00590
00591 #if defined(unix)
00592 unsigned char ch;
00593 while ((c = (read(0, &ch, 1) > 0) ? ch : -1) == -1 && errno == EINTR)
00594 errno = 0;
00595 #endif
00596
00597 #ifdef MSDOS
00598 c = pause_();
00599 if (c < 0) {
00600 switch (c) {
00601 case k_up_arr: c = 'P' - '@';
00602 break;
00603 case k_dn_arr: c = 'N' - '@';
00604 break;
00605 case k_lt_arr: c = 'B' - '@';
00606 break;
00607 case k_rt_arr: c = 'F' - '@';
00608 break;
00609 case k_INS: c = 'O' - '@';
00610 break;
00611 case k_DEL: c = 'D' - '@';
00612 break;
00613 case k_END: c = 'E' - '@';
00614 break;
00615 case k_HOME: c = 'A' - '@';
00616 break;
00617 default: c = 0;
00618 }
00619 }
00620 else {
00621 switch(c) {
00622 case k_ESC: c = 'U' - '@';
00623 break;
00624 default:
00625 break;
00626 }
00627 }
00628 #endif
00629
00630 #ifdef vms
00631 if(chan < 0) {
00632 c='\0';
00633 }
00634 (void)sys$qiow(0,chan,IO$_TTYREADALL,0,0,0,&c,1,0,0,0,0);
00635 c &= 0177;
00636 #endif
00637 return c;
00638 }
00639
00640 static void
00641 gl_putc(int c)
00642 {
00643 char ch = c;
00644
00645 if (gl_notty) return;
00646
00647 if ( !gl_passwd || !isgraph(c))
00648 {
00649 if (c == '\007' && Gl_beep_hook && Gl_beep_hook())
00650 return;
00651
00652 #ifdef WIN32
00653 CharToOemBuff((char const *)&c,&ch,1);
00654 #endif
00655
00656 write(1, &ch, 1);
00657 }
00658 #if defined(unix) || defined(MSDOS) || defined(WIN32)
00659 #ifdef TIOCSETP
00660 if (ch == '\n') {
00661 ch = '\r';
00662 write(1, &ch, 1);
00663 }
00664 #endif
00665 #endif
00666 }
00667
00668
00669
00670 static void
00671 gl_puts(const char *buf)
00672 {
00673 int len = strlen(buf);
00674
00675 if (gl_notty) return;
00676 #ifdef WIN32
00677 {
00678 char *OemBuf = (char *)malloc(2*len);
00679 CharToOemBuff(buf,OemBuf,len);
00680 write(1, OemBuf, len);
00681 free(OemBuf);
00682 }
00683 #else
00684 write(1, buf, len);
00685 #endif
00686 }
00687
00688 static void
00689 gl_error(char *buf)
00690 {
00691 int len = strlen(buf);
00692
00693 gl_cleanup();
00694 #ifdef WIN32
00695 {
00696 char *OemBuf = (char *)malloc(2*len);
00697 CharToOemBuff(buf,OemBuf,len);
00698 write(2, OemBuf, len);
00699 free(OemBuf);
00700 }
00701 #else
00702 write(2, buf, len);
00703 #endif
00704 exit(1);
00705 }
00706
00707 static void
00708 gl_init()
00709
00710 {
00711 if (gl_init_done < 0) {
00712 hist_init();
00713 }
00714 if (isatty(0) == 0 || isatty(1) == 0)
00715 gl_notty = 1;
00716 gl_char_init();
00717 gl_init_done = 1;
00718 }
00719
00720 static void
00721 gl_cleanup()
00722
00723 {
00724 if (gl_init_done > 0)
00725 gl_char_cleanup();
00726 gl_init_done = 0;
00727 }
00728
00729 void
00730 Gl_setwidth(int w)
00731 {
00732 if (w > 20) {
00733 gl_termw = w;
00734 gl_scroll = w / 3;
00735 } else {
00736 gl_error("\n*** Error: minimum screen width is 21\n");
00737 }
00738 }
00739
00740 void
00741 Gl_windowchanged()
00742 {
00743 #ifdef TIOCGWINSZ
00744 if (isatty(0)) {
00745 static char lenv[32], cenv[32];
00746 struct winsize wins;
00747 ioctl(0, TIOCGWINSZ, &wins);
00748
00749 if (wins.ws_col == 0) wins.ws_col = 80;
00750 if (wins.ws_row == 0) wins.ws_row = 24;
00751
00752 Gl_setwidth(wins.ws_col);
00753
00754 sprintf(lenv, "LINES=%d", wins.ws_row);
00755 putenv(lenv);
00756 sprintf(cenv, "COLUMNS=%d", wins.ws_col);
00757 putenv(cenv);
00758 }
00759 #endif
00760 }
00761
00762
00763
00764 char *
00765 Getlinem(int mode, const char *prompt)
00766 {
00767 int c, loc, tmp;
00768 int sig;
00769
00770 if (mode == 2) {
00771 gl_cleanup();
00772 return NULL;
00773 }
00774
00775 if (mode < 1) {
00776 if (mode == -1) {
00777
00778 Gl_config("erase", 0);
00779 }
00780 gl_init();
00781 gl_prompt = (prompt) ? prompt : "";
00782 gl_buf[0] = 0;
00783 if (Gl_in_hook)
00784 Gl_in_hook(gl_buf);
00785 gl_fixup(gl_prompt, -2, BUF_SIZE);
00786 if (mode == -1) return NULL;
00787 }
00788 while ((c = gl_getc()) >= 0) {
00789 gl_extent = 0;
00790
00791 if (Gl_in_key)
00792 Gl_in_key(c);
00793 #ifndef WIN32
00794 if (isprint(c)) {
00795 #else
00796 if (c >= ' ') {
00797 #endif
00798 if (gl_search_mode)
00799 search_addchar(c);
00800 else
00801 gl_addchar(c);
00802 } else {
00803 if (gl_search_mode) {
00804 if (c == '\016' || c == '\020') {
00805 search_term();
00806 c = 0;
00807 } else if (c == '\010' || c == '\177') {
00808 search_addchar(-1);
00809 c = 0;
00810 } else if (c != '\022' && c != '\023') {
00811 search_term();
00812 }
00813 }
00814
00815
00816
00817
00818
00819 switch (c)
00820 {
00821 case 'b'+128:
00822 case 'B'+128:
00823 gl_back_1_word();
00824 break;
00825 case 'd'+128:
00826 case 'D'+128:
00827 gl_kill_1_word();
00828 break;
00829 case 'f'+128:
00830 case 'F'+128:
00831 gl_fwd_1_word();
00832 break;
00833 case '\000':
00834 gl_set_mark();
00835 break;
00836 case '\027':
00837 gl_wipe();
00838 break;
00839 case '\030':
00840 gl_exch();
00841 break;
00842 case '\n':
00843 case '\r':
00844 gl_newline();
00845 gl_cleanup();
00846 return gl_buf;
00847
00848 break;
00849 case '\001': gl_fixup(gl_prompt, -1, 0);
00850 break;
00851 case '\002':
00852 gl_fixup(gl_prompt, -1, gl_pos-1);
00853 break;
00854 case '\004':
00855 if (gl_cnt == 0) {
00856 gl_buf[0] = 0;
00857 gl_cleanup();
00858 gl_putc('\n');
00859 return gl_buf;
00860 } else {
00861 gl_del(0);
00862 }
00863 break;
00864 case '\005': gl_fixup(gl_prompt, -1, gl_cnt);
00865 break;
00866 case '\006':
00867 gl_fixup(gl_prompt, -1, gl_pos+1);
00868 break;
00869 case '\010': case '\177': gl_del(-1);
00870 break;
00871 case '\t':
00872 if (Gl_tab_hook) {
00873 tmp = gl_pos;
00874 loc = Gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp);
00875 if (loc >= 0 || tmp != gl_pos || loc == -2)
00876 gl_fixup(gl_prompt, loc, tmp);
00877 }
00878 break;
00879 case '\013': gl_kill();
00880 break;
00881 case '\014': gl_redraw();
00882 break;
00883 case '\016':
00884 strcpy(gl_buf, hist_next());
00885 if (Gl_in_hook)
00886 Gl_in_hook(gl_buf);
00887 gl_fixup(gl_prompt, 0, BUF_SIZE);
00888 break;
00889 case '\017': gl_overwrite = !gl_overwrite;
00890 break;
00891 case '\020':
00892 strcpy(gl_buf, hist_prev());
00893 if (Gl_in_hook)
00894 Gl_in_hook(gl_buf);
00895 gl_fixup(gl_prompt, 0, BUF_SIZE);
00896 break;
00897 case '\022': search_back(1);
00898 break;
00899 case '\023': search_forw(1);
00900 break;
00901 case '\024': gl_transpose();
00902 break;
00903 case '\025': gl_fixup(gl_prompt,-1,0); gl_kill();
00904 break;
00905 case '\031': gl_yank();
00906 break;
00907 case '\033':
00908 switch(c = gl_getc())
00909 {
00910 case 'b':
00911 case 'B':
00912 gl_back_1_word();
00913 break;
00914 case 'd':
00915 case 'D':
00916 gl_kill_1_word();
00917 break;
00918 case 'f':
00919 case 'F':
00920 gl_fwd_1_word();
00921 break;
00922 case '[':
00923 case 'O':
00924 switch(c = gl_getc())
00925 {
00926 case 'A':
00927 strcpy(gl_buf, hist_prev());
00928 if (Gl_in_hook)
00929 Gl_in_hook(gl_buf);
00930 gl_fixup(gl_prompt, 0, BUF_SIZE);
00931 break;
00932 case 'B':
00933 strcpy(gl_buf, hist_next());
00934 if (Gl_in_hook)
00935 Gl_in_hook(gl_buf);
00936 gl_fixup(gl_prompt, 0, BUF_SIZE);
00937 break;
00938 case 'C': gl_fixup(gl_prompt, -1, gl_pos+1);
00939 break;
00940 case 'D': gl_fixup(gl_prompt, -1, gl_pos-1);
00941 break;
00942 case 'H': gl_fixup(gl_prompt, -1, 0);
00943 break;
00944 case 'F': gl_fixup(gl_prompt, -1, gl_cnt);
00945 break;
00946 case '3':
00947 gl_del(0);
00948 c = gl_getc();
00949 break;
00950 default:
00951 gl_putc('\007');
00952 break;
00953 }
00954 break;
00955 case '\010':
00956 case '\177':
00957 gl_kill_back_1_word();
00958 break;
00959 default:
00960 gl_putc('\007');
00961 }
00962 break;
00963 default:
00964
00965 #if defined(unix) || defined(WIN32)
00966 if (c > 0) {
00967 sig = 0;
00968 #ifdef SIGINT
00969 if (c == gl_intrc)
00970 sig = SIGINT;
00971 #endif
00972 #ifdef SIGQUIT
00973 if (c == gl_quitc)
00974 sig = SIGQUIT;
00975 #endif
00976 #ifdef SIGTSTP
00977 if (c == gl_suspc || c == gl_dsuspc)
00978 sig = SIGTSTP;
00979 #endif
00980 if (sig != 0) {
00981 gl_cleanup();
00982 #if !defined(WIN32)
00983 raise(sig);
00984 #endif
00985 #ifdef WIN32
00986 if (sig == SIGINT) GenerateConsoleCtrlEvent(CTRL_C_EVENT,0);
00987 else raise(sig);
00988 #endif
00989 gl_init();
00990 gl_redraw();
00991 c = 0;
00992 }
00993 }
00994 #endif
00995 if (c > 0)
00996 gl_putc('\007');
00997 break;
00998 }
00999 }
01000 if (mode == 1) return NULL;
01001 }
01002 if (c == -1 && gl_notty)
01003 gl_eof = 1;
01004 else
01005 gl_eof = 0;
01006
01007 gl_cleanup();
01008 gl_buf[0] = 0;
01009 return gl_buf;
01010 }
01011
01012 int
01013 Gl_eof()
01014 {
01015 return gl_eof;
01016 }
01017
01018 char *
01019 Getline(const char *prompt)
01020 {
01021 return Getlinem(0, prompt);
01022 }
01023
01024 static void
01025 gl_addchar(int c)
01026
01027 {
01028 int i;
01029
01030 if (gl_cnt >= BUF_SIZE - 1)
01031 gl_error("\n*** Error: Getline(): input buffer overflow\n");
01032 if (gl_overwrite == 0 || gl_pos == gl_cnt) {
01033 for (i=gl_cnt; i >= gl_pos; i--)
01034 gl_buf[i+1] = gl_buf[i];
01035 gl_buf[gl_pos] = c;
01036 gl_fixup(gl_prompt, gl_pos, gl_pos+1);
01037 } else {
01038 gl_buf[gl_pos] = c;
01039 gl_extent = 1;
01040 gl_fixup(gl_prompt, gl_pos, gl_pos+1);
01041 }
01042 }
01043
01044 static void
01045 gl_yank()
01046
01047 {
01048 int i, len;
01049
01050 len = strlen(gl_killbuf);
01051 if (len > 0) {
01052 gl_mark = gl_pos;
01053 if (gl_overwrite == 0) {
01054 if (gl_cnt + len >= BUF_SIZE - 1)
01055 gl_error("\n*** Error: Getline(): input buffer overflow\n");
01056 for (i=gl_cnt; i >= gl_pos; i--)
01057 gl_buf[i+len] = gl_buf[i];
01058 for (i=0; i < len; i++)
01059 gl_buf[gl_pos+i] = gl_killbuf[i];
01060 gl_fixup(gl_prompt, gl_pos, gl_pos+len);
01061 } else {
01062 if (gl_pos + len > gl_cnt) {
01063 if (gl_pos + len >= BUF_SIZE - 1)
01064 gl_error("\n*** Error: Getline(): input buffer overflow\n");
01065 gl_buf[gl_pos + len] = 0;
01066 }
01067 for (i=0; i < len; i++)
01068 gl_buf[gl_pos+i] = gl_killbuf[i];
01069 gl_extent = len;
01070 gl_fixup(gl_prompt, gl_pos, gl_pos+len);
01071 }
01072 } else
01073 gl_putc('\007');
01074 }
01075
01076 static void
01077 gl_transpose()
01078
01079 {
01080 int c;
01081
01082 if (gl_pos > 0 && gl_cnt > gl_pos) {
01083 c = gl_buf[gl_pos-1];
01084 gl_buf[gl_pos-1] = gl_buf[gl_pos];
01085 gl_buf[gl_pos] = c;
01086 gl_extent = 2;
01087 gl_fixup(gl_prompt, gl_pos-1, gl_pos);
01088 } else
01089 gl_putc('\007');
01090 }
01091
01092 static void
01093 gl_newline()
01094
01095
01096
01097
01098 {
01099 int change = gl_cnt;
01100 int len = gl_cnt;
01101 int loc = gl_width - 5;
01102
01103 if (gl_cnt >= BUF_SIZE - 1)
01104 gl_error("\n*** Error: Getline(): input buffer overflow\n");
01105 if (Gl_out_hook) {
01106 change = Gl_out_hook(gl_buf);
01107 len = strlen(gl_buf);
01108 }
01109 if (gl_erase_line) {
01110 char gl_buf0 = gl_buf[0];
01111 gl_buf[0] = '\0';
01112 gl_fixup("", 0, 0);
01113 gl_buf[0] = gl_buf0;
01114 }
01115 else {
01116 if (loc > len)
01117 loc = len;
01118 gl_fixup(gl_prompt, change, loc);
01119 gl_putc('\n');
01120 }
01121 gl_buf[len] = '\n';
01122 gl_buf[len+1] = '\0';
01123 gl_mark = -1;
01124 }
01125
01126 static void
01127 gl_del(int loc)
01128
01129
01130
01131
01132
01133 {
01134 int i;
01135
01136 if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) {
01137 for (i=gl_pos+loc; i < gl_cnt; i++)
01138 gl_buf[i] = gl_buf[i+1];
01139 gl_fixup(gl_prompt, gl_pos+loc, gl_pos+loc);
01140 } else
01141 gl_putc('\007');
01142 }
01143
01144 static void
01145 gl_kill()
01146
01147 {
01148 if (gl_pos < gl_cnt) {
01149 strcpy(gl_killbuf, gl_buf + gl_pos);
01150 gl_buf[gl_pos] = '\0';
01151 gl_fixup(gl_prompt, gl_pos, gl_pos);
01152 } else
01153 gl_putc('\007');
01154 }
01155
01156 static void
01157 gl_redraw()
01158
01159 {
01160 if (gl_init_done > 0) {
01161 gl_putc('\n');
01162 gl_fixup(gl_prompt, -2, gl_pos);
01163 }
01164 }
01165
01166 static void setCursorPosition(int x)
01167 {
01168
01169
01170
01171 #ifdef WIN32
01172 CONSOLE_SCREEN_BUFFER_INFO ci;
01173 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
01174 if (out == INVALID_HANDLE_VALUE) return;
01175
01176 if (!GetConsoleScreenBufferInfo(out, &ci)) return;
01177
01178 ci.dwCursorPosition.X = x;
01179 SetConsoleCursorPosition(out, ci.dwCursorPosition);
01180 SleepEx(0, TRUE);
01181 #else
01182 if (x) { }
01183 #endif
01184 }
01185
01186
01187 static void
01188 gl_fixup(const char *prompt, int change, int cursor)
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 {
01201 static int gl_shift;
01202 static int off_right;
01203 static int off_left;
01204 static char last_prompt[BUF_SIZE] = "";
01205 int left = 0, right = -1;
01206 int padl;
01207 int backup;
01208 int new_shift;
01209 int extra;
01210 int i;
01211 int new_right = -1;
01212 int l1, l2;
01213
01214 if (change == -2) {
01215 gl_pos = gl_cnt = gl_shift = off_right = off_left = 0;
01216 gl_passwd = 0;
01217 gl_puts(prompt);
01218 gl_passwd = gl_no_echo;
01219 if (strlen(prompt) > (BUF_SIZE-1)) {
01220 strncpy(last_prompt, prompt, BUF_SIZE-1);
01221 last_prompt[BUF_SIZE-1] = '\0';
01222 } else
01223 strcpy(last_prompt, prompt);
01224 change = 0;
01225 gl_width = gl_termw - strlen(prompt);
01226 } else if (strcmp(prompt, last_prompt) != 0) {
01227 l1 = strlen(last_prompt);
01228 l2 = strlen(prompt);
01229 gl_cnt = gl_cnt + l1 - l2;
01230 if (strlen(prompt) > (BUF_SIZE-1)) {
01231 strncpy(last_prompt, prompt, BUF_SIZE-1);
01232 last_prompt[BUF_SIZE-1] = '\0';
01233 } else
01234 strcpy(last_prompt, prompt);
01235 backup = gl_pos - gl_shift + l1;
01236 for (i=0; i < backup; i++)
01237 gl_putc('\b');
01238 gl_passwd = 0;
01239 gl_puts(prompt);
01240 gl_passwd = gl_no_echo;
01241 gl_pos = gl_shift;
01242 gl_width = gl_termw - l2;
01243 change = 0;
01244 }
01245 padl = (off_right)? gl_width - 1 : gl_cnt - gl_shift;
01246 backup = gl_pos - gl_shift;
01247 if (change >= 0) {
01248 gl_cnt = strlen(gl_buf);
01249 if (change > gl_cnt)
01250 change = gl_cnt;
01251 }
01252 if (cursor > gl_cnt) {
01253 if (cursor != BUF_SIZE)
01254 gl_putc('\007');
01255 cursor = gl_cnt;
01256 }
01257 if (cursor < 0) {
01258 gl_putc('\007');
01259 cursor = 0;
01260 }
01261 if (off_right || (off_left && cursor < gl_shift + gl_width - gl_scroll / 2))
01262 extra = 2;
01263 else
01264 extra = 0;
01265 new_shift = cursor + extra + gl_scroll - gl_width;
01266 if (new_shift > 0) {
01267 new_shift /= gl_scroll;
01268 new_shift *= gl_scroll;
01269 } else
01270 new_shift = 0;
01271 if (new_shift != gl_shift) {
01272 gl_shift = new_shift;
01273 off_left = (gl_shift)? 1 : 0;
01274 off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
01275 left = gl_shift;
01276 new_right = right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
01277 } else if (change >= 0) {
01278 if (change < gl_shift + off_left) {
01279 left = gl_shift;
01280 } else {
01281 left = change;
01282 backup = gl_pos - change;
01283 }
01284 off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
01285 right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
01286 new_right = (gl_extent && (right > left + gl_extent))?
01287 left + gl_extent : right;
01288 }
01289 padl -= (off_right)? gl_width - 1 : gl_cnt - gl_shift;
01290 padl = (padl < 0)? 0 : padl;
01291 if (left <= right) {
01292 for (i=0; i < backup; i++)
01293 gl_putc('\b');
01294 if (left == gl_shift && off_left) {
01295 gl_putc('$');
01296 left++;
01297 }
01298 for (i=left; i < new_right; i++)
01299 gl_putc(gl_buf[i]);
01300 gl_pos = new_right;
01301 if (off_right && new_right == right) {
01302 gl_putc('$');
01303 gl_pos++;
01304 } else {
01305 for (i=0; i < padl; i++)
01306 gl_putc(' ');
01307 gl_pos += padl;
01308 }
01309 }
01310 i = gl_pos - cursor;
01311 if (i > 0) {
01312 while (i--) {
01313 gl_putc('\b');
01314 }
01315 } else {
01316 for (i=gl_pos; i < cursor; i++) {
01317 gl_putc(gl_buf[i]);
01318 }
01319 }
01320 gl_pos = cursor;
01321 setCursorPosition(gl_pos + strlen(prompt) - gl_shift);
01322 }
01323
01324 static int
01325 gl_tab(char *buf, int offset, int *loc)
01326
01327 {
01328 int i, count, len;
01329
01330 len = strlen(buf);
01331 count = 8 - (offset + *loc) % 8;
01332 for (i=len; i >= *loc; i--)
01333 buf[i+count] = buf[i];
01334 for (i=0; i < count; i++)
01335 buf[*loc+i] = ' ';
01336 i = *loc;
01337 *loc = i + count;
01338 return i;
01339 }
01340
01341
01342
01343 #ifndef HIST_SIZE
01344 #define HIST_SIZE 500
01345 #endif
01346 #ifndef HIST_SAVE
01347 #define HIST_SAVE 400
01348 #endif
01349
01350 static int hist_pos = 0, hist_last = 0;
01351 static int num_hist_size = HIST_SIZE, num_hist_save = HIST_SAVE;
01352 static char **hist_buf = 0;
01353
01354 static void
01355 hist_init()
01356 {
01357 int i;
01358
01359 if (hist_buf != 0)
01360 return;
01361
01362 i = num_hist_size;
01363 if (i == 0)
01364 i = 1;
01365 hist_buf = malloc(i * sizeof(char*));
01366 hist_buf[0] = "";
01367 for (i=1; i < num_hist_size; i++)
01368 hist_buf[i] = (char *)0;
01369 }
01370
01371 void
01372 Gl_histsize(int size, int save)
01373 {
01374 num_hist_size = size;
01375 if (num_hist_size < 0)
01376 num_hist_size = 0;
01377 num_hist_save = save;
01378 if (num_hist_save > num_hist_size)
01379 num_hist_save = -1;
01380 if (num_hist_save < 0)
01381 num_hist_save = 4 * num_hist_size / 5;
01382 if (num_hist_size == 0)
01383 num_hist_save = 0;
01384 }
01385
01386 void
01387 Gl_histinit(char *file)
01388 {
01389 char line[BUFSIZ];
01390 FILE *fp;
01391 int nline = 1;
01392
01393 gl_savehist = 0;
01394
01395 hist_init();
01396
01397 if (!strcmp(file, "-") || num_hist_size == 0)
01398 return;
01399
01400 sprintf(gl_histfile, "%s", file);
01401
01402 fp = fopen(gl_histfile, "r");
01403 if (fp)
01404 while (fgets(line, BUFSIZ, fp)) {
01405 nline++;
01406 Gl_histadd(line);
01407 }
01408 else
01409 fp = fopen(gl_histfile, "w");
01410
01411 if (fp) fclose(fp);
01412
01413 gl_savehist = nline;
01414 }
01415
01416 void
01417 Gl_histadd(char *buf)
01418 {
01419 static char *prev = 0;
01420 char *p = buf;
01421 int len;
01422
01423 if (num_hist_size == 0 || hist_buf == 0)
01424 return;
01425
01426 while (*p == ' ' || *p == '\t' || *p == '\n')
01427 p++;
01428 if (*p) {
01429 len = strlen(buf);
01430 if (strchr(p, '\n'))
01431 len--;
01432 if (prev == 0 || (int)strlen(prev) != len ||
01433 strncmp(prev, buf, len) != 0) {
01434 hist_buf[hist_last] = hist_save(buf);
01435 prev = hist_buf[hist_last];
01436 hist_last = (hist_last + 1) % num_hist_size;
01437 if (hist_buf[hist_last] && *hist_buf[hist_last]) {
01438 free(hist_buf[hist_last]);
01439 }
01440 hist_buf[hist_last] = "";
01441
01442
01443 if (gl_savehist) {
01444 FILE *fp;
01445 fp = fopen(gl_histfile, "a+");
01446 if (fp) {
01447 fprintf(fp, "%s\n", prev);
01448 gl_savehist++;
01449 fclose(fp);
01450 }
01451
01452
01453
01454 if (gl_savehist > num_hist_size) {
01455 FILE *ftmp;
01456 char tname[L_tmpnam];
01457 char line[BUFSIZ];
01458
01459 fp = fopen(gl_histfile, "r");
01460 tmpnam(tname);
01461 ftmp = fopen(tname, "w");
01462 if (fp && ftmp) {
01463 int nline = 0;
01464 while (fgets(line, BUFSIZ, fp)) {
01465 nline++;
01466 gl_savehist = 1;
01467 if (nline > num_hist_size-num_hist_save) {
01468 gl_savehist++;
01469 fprintf(ftmp, "%s", line);
01470 }
01471 }
01472 }
01473 if (fp) fclose(fp);
01474 if (ftmp) fclose(ftmp);
01475
01476
01477 fp = fopen(gl_histfile, "w");
01478 ftmp = fopen(tname, "r");
01479 if (fp && ftmp)
01480 while (fgets(line, BUFSIZ, ftmp))
01481 fprintf(fp, "%s", line);
01482
01483 if (fp) fclose(fp);
01484 if (ftmp) fclose(ftmp);
01485 remove(tname);
01486 }
01487 }
01488 }
01489 }
01490 hist_pos = hist_last;
01491 }
01492
01493 static char *
01494 hist_prev()
01495
01496 {
01497 char *p = 0;
01498 int next;
01499
01500 if (num_hist_size > 0) {
01501 next = (hist_pos - 1 + num_hist_size) % num_hist_size;
01502
01503 if (hist_buf[hist_pos] != 0 && next != hist_last) {
01504 hist_pos = next;
01505 p = hist_buf[hist_pos];
01506 }
01507 }
01508 if (p == 0) {
01509 p = "";
01510 gl_putc('\007');
01511 }
01512 return p;
01513 }
01514
01515 static char *
01516 hist_next()
01517
01518 {
01519 char *p = 0;
01520
01521 if (num_hist_size > 0 && hist_pos != hist_last) {
01522 hist_pos = (hist_pos+1) % num_hist_size;
01523 p = hist_buf[hist_pos];
01524 }
01525 if (p == 0) {
01526 p = "";
01527 gl_putc('\007');
01528 }
01529 return p;
01530 }
01531
01532 static char *
01533 hist_save(char *p)
01534
01535 {
01536 char *s = 0;
01537 int len = strlen(p);
01538 char *nl = strchr(p, '\n');
01539
01540 if (nl) {
01541 if ((s = (char *)malloc(len)) != 0) {
01542 strncpy(s, p, len-1);
01543 s[len-1] = 0;
01544 }
01545 } else {
01546 if ((s = (char *)malloc(len+1)) != 0) {
01547 strcpy(s, p);
01548 }
01549 }
01550 if (s == 0)
01551 gl_error("\n*** Error: hist_save() failed on malloc\n");
01552 return s;
01553 }
01554
01555
01556
01557 static char search_prompt[101];
01558 static char search_string[100];
01559 static int search_pos = 0;
01560 static int search_forw_flg = 0;
01561 static int search_last = 0;
01562
01563 static void
01564 search_update(int c)
01565 {
01566 if (c == 0) {
01567 search_pos = 0;
01568 search_string[0] = 0;
01569 search_prompt[0] = '?';
01570 search_prompt[1] = ' ';
01571 search_prompt[2] = 0;
01572 } else if (c > 0) {
01573 search_string[search_pos] = c;
01574 search_string[search_pos+1] = 0;
01575 search_prompt[search_pos] = c;
01576 search_prompt[search_pos+1] = '?';
01577 search_prompt[search_pos+2] = ' ';
01578 search_prompt[search_pos+3] = 0;
01579 search_pos++;
01580 } else {
01581 if (search_pos > 0) {
01582 search_pos--;
01583 search_string[search_pos] = 0;
01584 search_prompt[search_pos] = '?';
01585 search_prompt[search_pos+1] = ' ';
01586 search_prompt[search_pos+2] = 0;
01587 } else {
01588 gl_putc('\007');
01589 hist_pos = hist_last;
01590 }
01591 }
01592 }
01593
01594 static void
01595 search_addchar(int c)
01596 {
01597 char *loc;
01598
01599 search_update(c);
01600 if (c < 0) {
01601 if (search_pos > 0) {
01602 hist_pos = search_last;
01603 } else {
01604 gl_buf[0] = 0;
01605 hist_pos = hist_last;
01606 }
01607 strcpy(gl_buf, hist_buf[hist_pos]);
01608 }
01609 if ((loc = strstr(gl_buf, search_string)) != 0) {
01610 gl_fixup(search_prompt, 0, loc - gl_buf);
01611 } else if (search_pos > 0) {
01612 if (search_forw_flg) {
01613 search_forw(0);
01614 } else {
01615 search_back(0);
01616 }
01617 } else {
01618 gl_fixup(search_prompt, 0, 0);
01619 }
01620 }
01621
01622 static void
01623 search_term()
01624 {
01625 gl_search_mode = 0;
01626 if (gl_buf[0] == 0)
01627 hist_pos = hist_last;
01628 if (Gl_in_hook)
01629 Gl_in_hook(gl_buf);
01630 gl_fixup(gl_prompt, 0, gl_pos);
01631 }
01632
01633 static void
01634 search_back(int new_search)
01635 {
01636 int found = 0;
01637 char *p, *loc;
01638
01639 search_forw_flg = 0;
01640 if (gl_search_mode == 0) {
01641 search_last = hist_pos = hist_last;
01642 search_update(0);
01643 gl_search_mode = 1;
01644 gl_buf[0] = 0;
01645 gl_fixup(search_prompt, 0, 0);
01646 } else if (search_pos > 0) {
01647 while (!found) {
01648 p = hist_prev();
01649 if (*p == 0) {
01650 gl_buf[0] = 0;
01651 gl_fixup(search_prompt, 0, 0);
01652 found = 1;
01653 } else if ((loc = strstr(p, search_string)) != 0) {
01654 strcpy(gl_buf, p);
01655 gl_fixup(search_prompt, 0, loc - p);
01656 if (new_search)
01657 search_last = hist_pos;
01658 found = 1;
01659 }
01660 }
01661 } else {
01662 gl_putc('\007');
01663 }
01664 }
01665
01666 static void
01667 search_forw(int new_search)
01668 {
01669 int found = 0;
01670 char *p, *loc;
01671
01672 search_forw_flg = 1;
01673 if (gl_search_mode == 0) {
01674 search_last = hist_pos = hist_last;
01675 search_update(0);
01676 gl_search_mode = 1;
01677 gl_buf[0] = 0;
01678 gl_fixup(search_prompt, 0, 0);
01679 } else if (search_pos > 0) {
01680 while (!found) {
01681 p = hist_next();
01682 if (*p == 0) {
01683 gl_buf[0] = 0;
01684 gl_fixup(search_prompt, 0, 0);
01685 found = 1;
01686 } else if ((loc = strstr(p, search_string)) != 0) {
01687 strcpy(gl_buf, p);
01688 gl_fixup(search_prompt, 0, loc - p);
01689 if (new_search)
01690 search_last = hist_pos;
01691 found = 1;
01692 }
01693 }
01694 } else {
01695 gl_putc('\007');
01696 }
01697 }
01698
01699 #if 0
01700
01701
01702
01703
01704
01705
01706 static char *strip(char *s)
01707 {
01708 char *r, *t1, *t2;
01709 int l;
01710
01711 l = strlen(s);
01712 r = (char *)calloc(l+1, 1);
01713
01714 if (l == 0) {
01715 *r = '\0';
01716 return r;
01717 }
01718
01719
01720 t1 = s;
01721 while (*t1 == ' ')
01722 t1++;
01723
01724 t2 = s + l - 1;
01725 while (*t2 == ' ' && t2 > s)
01726 t2--;
01727
01728 if (t1 > t2) {
01729 *r = '\0';
01730 return r;
01731 }
01732 strncpy(r, t1, (size_t) (t2-t1+1));
01733
01734 return r;
01735 }
01736 #endif
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 static void gl_back_1_word( void )
01747 {
01748 int i = gl_pos;
01749
01750
01751
01752 if( i>0 && is_whitespace(gl_buf[i-1]) ) {
01753 i-=1;
01754 }
01755
01756
01757 while( i>0 && is_whitespace(gl_buf[i]) ) {
01758 i-=1;
01759 }
01760
01761
01762
01763
01764 while( i>0 && !is_whitespace(gl_buf[i-1]) ) {
01765 i-=1;
01766 }
01767
01768
01769 gl_fixup(gl_prompt, -1, i);
01770 }
01771
01772
01773 static void gl_kill_back_1_word( void )
01774 {
01775 int i = gl_pos;
01776
01777
01778 while( i>0 && is_whitespace(gl_buf[i-1]) ) {
01779 i--;
01780 }
01781
01782
01783 while( i>0 && !is_whitespace(gl_buf[i-1]) ) {
01784 i--;
01785 }
01786
01787
01788 gl_mark = i;
01789 gl_wipe();
01790 }
01791
01792
01793 static void gl_kill_1_word( void )
01794 {
01795 int i = gl_pos;
01796 int j = gl_pos;
01797
01798
01799 #if 0
01800
01801 if( is_whitespace(gl_buf[j]) && gl_buf[j]!=' ' ) {
01802 return;
01803 }
01804
01805 while( j<gl_cnt && gl_buf[j]==' ' ) {
01806 j+=1;
01807 }
01808 #endif
01809
01810
01811 while( j<gl_cnt && is_whitespace(gl_buf[j]) ) {
01812 j+=1;
01813 }
01814
01815
01816 while( j<gl_cnt && !is_whitespace(gl_buf[j+1]) ) {
01817 j+=1;
01818 }
01819
01820
01821 gl_kill_region( i, j );
01822
01823
01824 gl_fixup(gl_prompt, gl_pos, gl_pos);
01825 }
01826
01827 static void gl_kill_region( int i, int j )
01828 {
01829
01830 strncpy( gl_killbuf, gl_buf+i, j-i+1 );
01831 gl_killbuf[j-i+1]='\0';
01832
01833
01834 while( j<gl_cnt ) {
01835 gl_buf[i]=gl_buf[j+1];
01836 i+=1;
01837 j+=1;
01838 }
01839 gl_buf[i]='\0';
01840 }
01841
01842
01843 static void gl_fwd_1_word( void )
01844 {
01845 int i = gl_pos;
01846
01847
01848 while( i<gl_cnt && !is_whitespace(gl_buf[i]) ) {
01849 i+=1;
01850 }
01851
01852
01853 while( i<gl_cnt && is_whitespace(gl_buf[i]) ) {
01854 i+=1;
01855 }
01856
01857
01858 gl_fixup(gl_prompt, -1, i);
01859 }
01860
01861
01862 static int is_whitespace( char c )
01863 {
01864 int decent_character;
01865
01866 decent_character = isalpha(c) || isdigit(c) || c=='_';
01867
01868 return !decent_character;
01869 }
01870
01871
01872 static void gl_set_mark( void )
01873 {
01874 gl_mark = gl_pos;
01875 }
01876
01877
01878 static void gl_wipe( void )
01879 {
01880 int left, right;
01881
01882 if( gl_mark < 0 ) return;
01883 if( gl_mark == gl_pos ) return;
01884
01885 if( gl_mark < gl_pos ) {
01886 left = gl_mark;
01887 right = gl_pos;
01888 }
01889 else {
01890 left = gl_pos;
01891 right = gl_mark;
01892 }
01893
01894 gl_kill_region( left, right-1 );
01895 gl_fixup( gl_prompt, left, left );
01896 }
01897
01898
01899 static void gl_exch( void )
01900 {
01901 int tmp;
01902
01903
01904 if( gl_mark < 0 ) return;
01905
01906 tmp = gl_pos;
01907 gl_fixup( gl_prompt, -1, gl_mark );
01908 gl_mark = tmp;
01909 }