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 #include "compat.h"
00047
00048
00049
00050
00051
00052 #include "sys.h"
00053 #include <errno.h>
00054 #include <unistd.h>
00055 #include <stdlib.h>
00056 #include "el.h"
00057 #include "enhance.h"
00058
00059
00060 #define OKCMD -1
00061
00062 el_private int read__fixio(int, int);
00063 el_private int read_preread(EditLine_t*);
00064 el_private int read_getcmd(EditLine_t*, ElAction_t*, char*);
00065 el_private int read_char(EditLine_t*, char*);
00066
00067 #ifdef DEBUG_EDIT
00068 el_private void
00069 read_debug(EditLine_t* el) {
00070 if (el->fLine.fCursor > el->fLine.fLastChar) {
00071 (void) fprintf(el->fErrFile, "cursor > lastchar\r\n");
00072 }
00073
00074 if (el->fLine.fCursor < el->fLine.fBuffer) {
00075 (void) fprintf(el->fErrFile, "cursor < buffer\r\n");
00076 }
00077
00078 if (el->fLine.fCursor > el->fLine.fLimit) {
00079 (void) fprintf(el->fErrFile, "cursor > limit\r\n");
00080 }
00081
00082 if (el->fLine.fLastChar > el->fLine.fLimit) {
00083 (void) fprintf(el->fErrFile, "lastchar > limit\r\n");
00084 }
00085
00086 if (el->fLine.fLimit != &el->fLine.fBuffer[EL_BUFSIZ - 2]) {
00087 (void) fprintf(el->fErrFile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
00088 }
00089 }
00090
00091
00092 #endif
00093
00094
00095
00096
00097
00098
00099 el_private int
00100 read__fixio(int
00101 # if (defined(F_SETFL) && defined(O_NDELAY)) \
00102 || defined(FIONBIO)
00103 fd
00104 #endif
00105 , int e) {
00106 switch (e) {
00107 case - 1:
00108
00109 #ifdef EWOULDBLOCK
00110 case EWOULDBLOCK:
00111 # ifndef TRY_AGAIN
00112 # define TRY_AGAIN
00113 # endif
00114 #endif
00115
00116 #if defined(POSIX) && defined(EAGAIN)
00117 # if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
00118 case EAGAIN:
00119 # ifndef TRY_AGAIN
00120 # define TRY_AGAIN
00121 # endif
00122 # endif
00123 #endif
00124
00125 e = 0;
00126 #ifdef TRY_AGAIN
00127 # if defined(F_SETFL) && defined(O_NDELAY)
00128
00129 if ((e = fcntl(fd, F_GETFL, 0)) == -1) {
00130 return -1;
00131 }
00132
00133 if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) {
00134 return -1;
00135 } else {
00136 e = 1;
00137 }
00138 # endif
00139
00140 # ifdef FIONBIO
00141 {
00142 int zero = 0;
00143
00144 if (ioctl(fd, FIONBIO, (ioctl_t) &zero) == -1) {
00145 return -1;
00146 } else {
00147 e = 1;
00148 }
00149 }
00150 # endif
00151
00152 #endif
00153 return e ? 0 : -1;
00154
00155 case EINTR:
00156 return 0;
00157
00158 default:
00159 return -1;
00160 }
00161 }
00162
00163
00164
00165
00166
00167 el_private int
00168 read_preread(EditLine_t* el) {
00169 int chrs = 0;
00170
00171 if (el->fCharEd.fMacro.fNLine) {
00172 el_free((ptr_t) el->fCharEd.fMacro.fNLine);
00173 el->fCharEd.fMacro.fNLine = NULL;
00174 }
00175
00176 if (el->fTTY.t_mode == ED_IO) {
00177 return 0;
00178 }
00179
00180 #ifdef FIONREAD
00181 if (!el->fIn) {
00182 (void) ioctl(el->fInFD, FIONREAD, (ioctl_t) &chrs);
00183
00184 if (chrs > 0) {
00185 char buf[EL_BUFSIZ];
00186
00187 chrs = read(el->fInFD, buf,
00188 (size_t) MIN(chrs, EL_BUFSIZ - 1));
00189
00190 if (chrs > 0) {
00191 buf[chrs] = '\0';
00192 el->fCharEd.fMacro.fNLine = strdup(buf);
00193 el_push(el, el->fCharEd.fMacro.fNLine);
00194 }
00195 }
00196 }
00197 #endif
00198
00199 return chrs > 0;
00200 }
00201
00202
00203
00204
00205
00206 el_public void
00207 el_push(EditLine_t* el, const char* str) {
00208 CMacro_t* ma = &el->fCharEd.fMacro;
00209
00210 if (str != NULL && ma->fLevel + 1 < EL_MAXMACRO) {
00211 ma->fLevel++;
00212
00213 ma->fMacro[ma->fLevel] = (char*) str;
00214 } else {
00215 term_beep(el);
00216 term__flush();
00217 }
00218 }
00219
00220
00221
00222
00223
00224 el_private int
00225 read_getcmd(EditLine_t* el, ElAction_t* cmdnum, char* ch) {
00226 ElAction_t cmd = ED_UNASSIGNED;
00227 int num;
00228
00229 while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) {
00230 if ((num = el_getc(el, ch)) != 1) {
00231 return num;
00232 }
00233
00234 #ifdef KANJI
00235
00236 if ((*ch & 0200)) {
00237 el->fState.fMetaNext = 0;
00238 cmd = CcViMap[' '];
00239 break;
00240 } else
00241 #endif
00242
00243 if (el->fState.fMetaNext) {
00244 el->fState.fMetaNext = 0;
00245 *ch |= 0200;
00246 }
00247
00248
00249
00250
00251
00252 cmd = el->fMap.fCurrent[(unsigned char) *ch];
00253
00254 if (cmd == ED_SEQUENCE_LEAD_IN) {
00255 KeyValue_t val;
00256
00257 switch (key_get(el, ch, &val)) {
00258 case XK_CMD:
00259 cmd = val.fCmd;
00260 break;
00261 case XK_STR:
00262 el_push(el, val.fStr);
00263 break;
00264 #ifdef notyet
00265 case XK_EXE:
00266
00267 RunCommand(val.fStr);
00268 break;
00269 #endif
00270 default:
00271 EL_ABORT((el->fErrFile, "Bad XK_ type \n"));
00272 break;
00273 }
00274 }
00275
00276 if (el->fMap.fAlt == NULL) {
00277 el->fMap.fCurrent = el->fMap.fKey;
00278 }
00279 }
00280 *cmdnum = cmd;
00281 return OKCMD;
00282 }
00283
00284
00285
00286
00287
00288
00289 el_private int
00290 read_char(EditLine_t* el, char* cp) {
00291 int num_read;
00292 int tried = 0;
00293
00294 if (!el->fIn) {
00295 while ((num_read = read(el->fInFD, cp, 1)) == -1) {
00296 if (!tried && read__fixio(el->fInFD, errno) == 0) {
00297 tried = 1;
00298 } else {
00299 *cp = '\0';
00300 return -1;
00301 }
00302 }
00303 } else {
00304 if (feof(el->fIn)) {
00305 *cp = 0;
00306 return 0;
00307 }
00308 int chread = fgetc(el->fIn);
00309 #ifdef DEBUG_READ
00310 if (chread < 0 || chread > 255) {
00311 fprintf(el->fErrFile,
00312 "Read unexpected character value %d\n", chread);
00313 }
00314 #endif
00315 *cp = (char)chread;
00316 num_read = 1;
00317 }
00318
00319
00320
00321
00322 return num_read;
00323 }
00324
00325
00326
00327
00328
00329 el_public int
00330 el_getc(EditLine_t* el, char* cp) {
00331 int num_read;
00332 CMacro_t* ma = &el->fCharEd.fMacro;
00333
00334 term__flush();
00335
00336 for ( ; ;) {
00337 if (ma->fLevel < 0) {
00338 if (!read_preread(el)) {
00339 break;
00340 }
00341 }
00342
00343 if (ma->fLevel < 0) {
00344 break;
00345 }
00346
00347 if (*ma->fMacro[ma->fLevel] == 0) {
00348 ma->fLevel--;
00349 continue;
00350 }
00351 *cp = *ma->fMacro[ma->fLevel]++ & 0377;
00352
00353 if (*ma->fMacro[ma->fLevel] == 0) {
00354
00355 ma->fLevel--;
00356 }
00357 return 1;
00358 }
00359
00360 #ifdef DEBUG_READ
00361 (void) fprintf(el->fErrFile, "Turning raw mode on\n");
00362 #endif
00363
00364 if (tty_rawmode(el) < 0) {
00365 return 0;
00366 }
00367
00368 #ifdef DEBUG_READ
00369 (void) fprintf(el->fErrFile, "Reading a character\n");
00370 #endif
00371 num_read = read_char(el, cp);
00372 #ifdef DEBUG_READ
00373 (void) fprintf(el->fErrFile, "Got it %c\n", *cp);
00374 #endif
00375 return num_read;
00376 }
00377
00378
00379 int
00380 el_chop_at_newline(EditLine_t* el) {
00381
00382 char* str = el->fLine.fBuffer;
00383
00384 if (str) {
00385 for ( ; str <= el->fLine.fLastChar; ++str) {
00386 if (*str != '\n' && *str != '\r') {
00387 continue;
00388 }
00389
00390 *str = '\0';
00391 }
00392 }
00393
00394 return strlen(el->fLine.fBuffer);
00395 }
00396
00397
00398 el_public const char*
00399 el_gets(EditLine_t* el, int* nread) {
00400 int retval;
00401 ElAction_t cmdnum = 0;
00402 int num;
00403 char ch;
00404 #ifdef FIONREAD
00405 CMacro_t* ma = &el->fCharEd.fMacro;
00406 #endif
00407
00408
00409
00410 if (el->fFlags & NO_TTY) {
00411 char* cp = el->fLine.fBuffer;
00412 size_t idx;
00413 size_t numRead = 0;
00414
00415 while ((numRead = read_char(el, cp)) == 1) {
00416
00417 if (cp + 4 >= el->fLine.fLimit) {
00418 idx = (cp - el->fLine.fBuffer);
00419
00420 if (!ch_enlargebufs(el, 2)) {
00421 break;
00422 }
00423 cp = &el->fLine.fBuffer[idx];
00424 }
00425 cp++;
00426
00427 if (cp[-1] == '\r' || cp[-1] == '\n') {
00428
00429
00430
00431
00432
00433 break;
00434 }
00435 }
00436
00437 if (!numRead) {
00438
00439 *cp = 0;
00440 cp++;
00441 strcpy(cp, "EOF");
00442 cp += 3;
00443 }
00444
00445 el->fLine.fCursor = el->fLine.fLastChar = cp;
00446 *cp = '\0';
00447
00448 if (nread) {
00449 *nread = el->fLine.fCursor - el->fLine.fBuffer;
00450 }
00451 return el->fLine.fBuffer;
00452 }
00453
00454 if (el->fFlags & EDIT_DISABLED) {
00455
00456 char* cp = el->fLine.fBuffer;
00457 size_t idx;
00458
00459 term__flush();
00460
00461 while (read_char(el, cp) == 1) {
00462
00463 if (cp + 1 >= el->fLine.fLimit) {
00464 idx = (cp - el->fLine.fBuffer);
00465
00466 if (!ch_enlargebufs(el, 2)) {
00467 break;
00468 }
00469 cp = &el->fLine.fBuffer[idx];
00470 }
00471 cp++;
00472
00473 if (cp[-1] == '\r' || cp[-1] == '\n') {
00474
00475
00476
00477
00478
00479 break;
00480 }
00481 }
00482 *cp = '\0';
00483 el->fLine.fCursor = el->fLine.fLastChar = cp;
00484
00485 if (nread) {
00486 *nread = el->fLine.fCursor - el->fLine.fBuffer;
00487 }
00488 return el->fLine.fBuffer;
00489 }
00490
00491
00492
00493
00494 #ifdef DEBUG_EDIT
00495 read_debug(el);
00496 #endif
00497
00498
00499
00500
00501 if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
00502 #ifdef DEBUG_READ
00503 (void) fprintf(el->fErrFile,
00504 "Returning from el_gets %d\n", num);
00505 #endif
00506
00507 }
00508
00509 if ((int) cmdnum >= el->fMap.fNFunc) {
00510 #ifdef DEBUG_EDIT
00511 (void) fprintf(el->fErrFile,
00512 "ERROR: illegal command from key 0%o\r\n", ch);
00513 #endif
00514
00515 }
00516
00517 #ifdef DEBUG_READ
00518 {
00519 ElBindings_t* b;
00520
00521 for (b = el->fMap.fHelp; b->fName; b++) {
00522 if (b->fFunc == cmdnum) {
00523 break;
00524 }
00525 }
00526
00527 if (b->fName) {
00528 (void) fprintf(el->fErrFile,
00529 "Executing %s\n", b->fName);
00530 } else {
00531 (void) fprintf(el->fErrFile,
00532 "Error command = %d\n", cmdnum);
00533 }
00534 }
00535 #endif
00536 retval = (*el->fMap.fFunc[cmdnum])(el, ch);
00537
00538
00539 el->fState.fLastCmd = cmdnum;
00540
00541 if (el->fMap.fFunc[cmdnum] != ed_replay_hist) {
00542 el->fState.fReplayHist = -1;
00543 }
00544
00545 switch (retval) {
00546 case CC_CURSOR:
00547 el->fState.fArgument = 1;
00548 el->fState.fDoingArg = 0;
00549 re_refresh_cursor(el);
00550 break;
00551
00552 case CC_REDISPLAY:
00553 re_clear_lines(el);
00554 re_clear_display(el);
00555
00556
00557 case CC_REFRESH:
00558 el->fState.fArgument = 1;
00559 el->fState.fDoingArg = 0;
00560 re_refresh(el);
00561 break;
00562
00563 case CC_REFRESH_BEEP:
00564 el->fState.fArgument = 1;
00565 el->fState.fDoingArg = 0;
00566 re_refresh(el);
00567 term_beep(el);
00568 break;
00569
00570 case CC_NORM:
00571 el->fState.fArgument = 1;
00572 el->fState.fDoingArg = 0;
00573 num = el->fLine.fLastChar - el->fLine.fBuffer;
00574 break;
00575
00576 case CC_ARGHACK:
00577
00578 break;
00579
00580 case CC_EOF:
00581 num = 0;
00582 break;
00583
00584 case CC_NEWLINE:
00585 num = el->fLine.fLastChar - el->fLine.fBuffer;
00586
00587 if (0 == num) {
00588
00589
00590
00591
00592
00593 el->fLine.fLastChar = el->fLine.fBuffer;
00594 *el->fLine.fBuffer = '\0';
00595 num = 1;
00596 }
00597
00598 break;
00599
00600 case CC_FATAL:
00601 #ifdef DEBUG_READ
00602 (void) fprintf(el->fErrFile,
00603 "*** editor fatal ERROR ***\r\n\n");
00604 #endif
00605
00606 re_clear_display(el);
00607 ch_reset(el);
00608 re_refresh(el);
00609 el->fState.fArgument = 1;
00610 el->fState.fDoingArg = 0;
00611 break;
00612
00613 case CC_ERROR:
00614 default:
00615 #ifdef DEBUG_READ
00616 (void) fprintf(el->fErrFile,
00617 "*** editor ERROR ***\r\n\n");
00618 #endif
00619 el->fState.fArgument = 1;
00620 el->fState.fDoingArg = 0;
00621 term_beep(el);
00622 term__flush();
00623 break;
00624
00625 }
00626
00627
00628
00629
00630
00631
00632 term__flush();
00633
00634
00635
00636 if (nread) {
00637 *nread = num;
00638 }
00639
00640 if (retval == 1) {
00641 *el->fLine.fLastChar = '\n';
00642 el->fLine.fLastChar++;
00643 *el->fLine.fLastChar = 0;
00644
00645 return el->fLine.fBuffer;
00646 }
00647
00648 CMacro_t* ma = &el->fCharEd.fMacro;
00649
00650 if (retval == CC_REFRESH && ma->fLevel >= 0 && ma->fMacro[ma->fLevel]) {
00651 int subnread;
00652 el_gets(el, &subnread);
00653
00654 if (nread) {
00655 *nread += subnread;
00656 }
00657 } else {
00658
00659
00660 highlightKeywords(el);
00661
00662
00663 if (el->fLine.fCursor <= el->fLine.fLastChar) {
00664 matchParentheses(el);
00665 }
00666
00667
00668
00669 *el->fLine.fLastChar = '\a';
00670 }
00671
00672 return num ? el->fLine.fBuffer : NULL;
00673 }
00674
00675
00676 el_public const char*
00677 el_gets_newline(EditLine_t* el, int* nread) {
00678 if (el->fFlags & HANDLE_SIGNALS) {
00679 sig_set(el);
00680 }
00681 re_clear_display(el);
00682
00683
00684 if (*el->fLine.fLastChar == '\a') {
00685
00686
00687 } else {
00688
00689 ch_reset(el);
00690 if (el->fState.fReplayHist >= 0) {
00691 el->fHistory.fEventNo = el->fState.fReplayHist;
00692
00693 ed_prev_history(el, 0);
00694 }
00695
00696 }
00697
00698 if (!(el->fFlags & NO_TTY)) {
00699 re_refresh(el);
00700 }
00701 term__flush();
00702
00703 if (nread) {
00704 *nread = 0;
00705 }
00706 return NULL;
00707 }
00708
00709
00710 el_public bool
00711 el_eof(EditLine_t* el) {
00712 return !el->fLine.fBuffer[0] && !strcmp(el->fLine.fBuffer + 1, "EOF");
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724