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 #include "sys.h"
00051
00052 #include <stdlib.h>
00053 #include "el.h"
00054
00055
00056 #define EL_LEAVE 2
00057
00058
00059
00060
00061 el_protected void
00062 cv_undo(EditLine_t* el, int action, size_t size, char* ptr) {
00063 CUndo_t* vu = &el->fCharEd.fUndo;
00064 vu->fAction = action;
00065 vu->fPtr = ptr;
00066 vu->fISize = size;
00067 (void) memcpy(vu->fBuf, vu->fPtr, size);
00068 #ifdef DEBUG_UNDO
00069 (void) fprintf(el->fErrFile, "Undo buffer \"%s\" size = +%d -%d\n",
00070 vu->fPtr, vu->fISize, vu->fDSize);
00071 #endif
00072 }
00073
00074
00075
00076
00077
00078 el_protected void
00079 c_insert(EditLine_t* el, int num) {
00080 char* cp;
00081
00082 if (el->fLine.fLastChar + num >= el->fLine.fLimit) {
00083 return;
00084
00085 }
00086
00087 if (el->fLine.fCursor < el->fLine.fLastChar) {
00088
00089 for (cp = el->fLine.fLastChar; cp >= el->fLine.fCursor; cp--) {
00090 cp[num] = *cp;
00091 }
00092
00093
00094 int colCursor = el->fLine.fCursor - el->fLine.fBuffer;
00095 int colLastChar = el->fLine.fLastChar - el->fLine.fBuffer;
00096
00097
00098 for (int i = colLastChar; i >= colCursor; i--) {
00099 el->fLine.fBufColor[i + num] = el->fLine.fBufColor[i];
00100 }
00101
00102 }
00103 el->fLine.fLastChar += num;
00104 }
00105
00106
00107
00108
00109
00110 el_protected void
00111 c_delafter(EditLine_t* el, int num) {
00112 if (el->fLine.fCursor + num > el->fLine.fLastChar) {
00113 num = el->fLine.fLastChar - el->fLine.fCursor;
00114 }
00115
00116 if (num > 0) {
00117 char* cp;
00118
00119 if (el->fMap.fCurrent != el->fMap.fEmacs) {
00120 cv_undo(el, INSERT, (size_t) num, el->fLine.fCursor);
00121 }
00122
00123 for (cp = el->fLine.fCursor; cp <= el->fLine.fLastChar; cp++) {
00124 *cp = cp[num];
00125 }
00126
00127 el->fLine.fLastChar -= num;
00128 }
00129 }
00130
00131
00132
00133
00134
00135 el_protected void
00136 c_delbefore(EditLine_t* el, int num) {
00137 if (el->fLine.fCursor - num < el->fLine.fBuffer) {
00138 num = el->fLine.fCursor - el->fLine.fBuffer;
00139 }
00140
00141 if (num > 0) {
00142 char* cp;
00143
00144 if (el->fMap.fCurrent != el->fMap.fEmacs) {
00145 cv_undo(el, INSERT, (size_t) num,
00146 el->fLine.fCursor - num);
00147 }
00148
00149 for (cp = el->fLine.fCursor - num;
00150 cp <= el->fLine.fLastChar;
00151 cp++) {
00152 *cp = cp[num];
00153 }
00154
00155 el->fLine.fLastChar -= num;
00156 }
00157 }
00158
00159
00160
00161
00162
00163 el_protected int
00164 ce__isword(int p) {
00165 return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL;
00166 }
00167
00168
00169
00170
00171
00172 el_protected int
00173 cv__isword(int p) {
00174 return !isspace(p);
00175 }
00176
00177
00178
00179
00180
00181 el_protected char*
00182 c__prev_word(char* p, char* low, int n, int (* wtest)(int)) {
00183 p--;
00184
00185 while (n--) {
00186 while ((p >= low) && !(*wtest)((unsigned char) *p))
00187 p--;
00188
00189 while ((p >= low) && (*wtest)((unsigned char) *p))
00190 p--;
00191 }
00192
00193
00194 p++;
00195
00196 if (p < low) {
00197 p = low;
00198 }
00199
00200 return p;
00201 }
00202
00203
00204
00205
00206
00207 el_protected char*
00208 c__next_word(char* p, char* high, int n, int (* wtest)(int)) {
00209 while (n--) {
00210 while ((p < high) && !(*wtest)((unsigned char) *p))
00211 p++;
00212
00213 while ((p < high) && (*wtest)((unsigned char) *p))
00214 p++;
00215 }
00216
00217 if (p > high) {
00218 p = high;
00219 }
00220
00221 return p;
00222 }
00223
00224
00225
00226
00227
00228 el_protected char*
00229 cv_next_word(EditLine_t* el, char* p, char* high, int n, int (* wtest)(int)) {
00230 int test;
00231
00232 while (n--) {
00233 test = (*wtest)((unsigned char) *p);
00234
00235 while ((p < high) && (*wtest)((unsigned char) *p) == test)
00236 p++;
00237
00238
00239
00240
00241
00242 if (el->fCharEd.fVCmd.fAction != (DELETE | INSERT)) {
00243 while ((p < high) && isspace((unsigned char) *p))
00244 p++;
00245 }
00246 }
00247
00248
00249 if (p > high) {
00250 return high;
00251 } else {
00252 return p;
00253 }
00254 }
00255
00256
00257
00258
00259
00260 el_protected char*
00261 cv_prev_word(EditLine_t* el, char* p, char* low, int n, int (* wtest)(int)) {
00262 int test;
00263
00264 while (n--) {
00265 p--;
00266
00267
00268
00269
00270
00271 if (el->fCharEd.fVCmd.fAction != (DELETE | INSERT)) {
00272 while ((p > low) && isspace((unsigned char) *p))
00273 p--;
00274 }
00275 test = (*wtest)((unsigned char) *p);
00276
00277 while ((p >= low) && (*wtest)((unsigned char) *p) == test)
00278 p--;
00279 p++;
00280
00281 while (isspace((unsigned char) *p))
00282 p++;
00283 }
00284
00285
00286 if (p < low) {
00287 return low;
00288 } else {
00289 return p;
00290 }
00291 }
00292
00293
00294 #ifdef notdef
00295
00296
00297
00298
00299
00300
00301 el_protected char*
00302 c__number(
00303 char* p,
00304 int* num,
00305 int dval) {
00306 int i;
00307 int sign = 1;
00308
00309 if (*++p == '^') {
00310 *num = 1;
00311 return p;
00312 }
00313
00314 if (*p == '$') {
00315 if (*++p != '-') {
00316 *num = 0x7fffffff;
00317 return --p;
00318 }
00319 sign = -1;
00320 ++p;
00321 }
00322
00323 for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0') {
00324 continue;
00325 }
00326 *num = (sign < 0 ? dval - i : i);
00327 return --p;
00328 }
00329
00330
00331 #endif
00332
00333
00334
00335
00336 el_protected void
00337 cv_delfini(EditLine_t* el) {
00338 int size;
00339 int oaction;
00340
00341 if (el->fCharEd.fVCmd.fAction & INSERT) {
00342 el->fMap.fCurrent = el->fMap.fKey;
00343 }
00344
00345 oaction = el->fCharEd.fVCmd.fAction;
00346 el->fCharEd.fVCmd.fAction = NOP;
00347
00348 if (el->fCharEd.fVCmd.fPos == 0) {
00349 return;
00350 }
00351
00352 if (el->fLine.fCursor > el->fCharEd.fVCmd.fPos) {
00353 size = (int) (el->fLine.fCursor - el->fCharEd.fVCmd.fPos);
00354 c_delbefore(el, size);
00355 el->fLine.fCursor = el->fCharEd.fVCmd.fPos;
00356 re_refresh_cursor(el);
00357 } else if (el->fLine.fCursor < el->fCharEd.fVCmd.fPos) {
00358 size = (int) (el->fCharEd.fVCmd.fPos - el->fLine.fCursor);
00359 c_delafter(el, size);
00360 } else {
00361 size = 1;
00362 c_delafter(el, size);
00363 }
00364
00365 switch (oaction) {
00366 case DELETE | INSERT:
00367 el->fCharEd.fUndo.fAction = DELETE | INSERT;
00368 break;
00369 case DELETE:
00370 el->fCharEd.fUndo.fAction = INSERT;
00371 break;
00372 case NOP:
00373 case INSERT:
00374 default:
00375 EL_ABORT((el->fErrFile, "Bad oaction %d\n", oaction));
00376 break;
00377 }
00378
00379
00380 el->fCharEd.fUndo.fPtr = el->fLine.fCursor;
00381 el->fCharEd.fUndo.fDSize = size;
00382 }
00383
00384
00385 #ifdef notdef
00386
00387
00388
00389
00390 el_protected char*
00391 ce__endword(char* p, char* high, int n) {
00392 p++;
00393
00394 while (n--) {
00395 while ((p < high) && isspace((unsigned char) *p))
00396 p++;
00397
00398 while ((p < high) && !isspace((unsigned char) *p))
00399 p++;
00400 }
00401
00402 p--;
00403 return p;
00404 }
00405
00406
00407 #endif
00408
00409
00410
00411
00412
00413 el_protected char*
00414 cv__endword(char* p, char* high, int n) {
00415 p++;
00416
00417 while (n--) {
00418 while ((p < high) && isspace((unsigned char) *p))
00419 p++;
00420
00421 if (isalnum((unsigned char) *p)) {
00422 while ((p < high) && isalnum((unsigned char) *p))
00423 p++;
00424 } else {
00425 while ((p < high) && !(isspace((unsigned char) *p) ||
00426 isalnum((unsigned char) *p)))
00427 p++;
00428 }
00429 }
00430 p--;
00431 return p;
00432 }
00433
00434
00435
00436
00437
00438 el_protected int
00439 ch_init(EditLine_t* el) {
00440 el->fLine.fBuffer = (char*) el_malloc(EL_BUFSIZ);
00441 el->fLine.fBufColor = (ElColor_t*) el_malloc(EL_BUFSIZ * sizeof(ElColor_t));
00442
00443 if (el->fLine.fBuffer == NULL) {
00444 return -1;
00445 }
00446
00447 (void) memset(el->fLine.fBuffer, 0, EL_BUFSIZ);
00448 (void) memset(el->fLine.fBufColor, 0, EL_BUFSIZ * sizeof(ElColor_t));
00449 el->fLine.fCursor = el->fLine.fBuffer;
00450 el->fLine.fLastChar = el->fLine.fBuffer;
00451 el->fLine.fLimit = &el->fLine.fBuffer[EL_BUFSIZ - 2];
00452
00453 el->fCharEd.fUndo.fBuf = (char*) el_malloc(EL_BUFSIZ);
00454
00455 if (el->fCharEd.fUndo.fBuf == NULL) {
00456 return -1;
00457 }
00458 (void) memset(el->fCharEd.fUndo.fBuf, 0, EL_BUFSIZ);
00459 el->fCharEd.fUndo.fAction = NOP;
00460 el->fCharEd.fUndo.fISize = 0;
00461 el->fCharEd.fUndo.fDSize = 0;
00462 el->fCharEd.fUndo.fPtr = el->fLine.fBuffer;
00463
00464 el->fCharEd.fVCmd.fAction = NOP;
00465 el->fCharEd.fVCmd.fPos = el->fLine.fBuffer;
00466 el->fCharEd.fVCmd.fIns = el->fLine.fBuffer;
00467
00468 el->fCharEd.fKill.fBuf = (char*) el_malloc(EL_BUFSIZ);
00469
00470 if (el->fCharEd.fKill.fBuf == NULL) {
00471 return -1;
00472 }
00473 (void) memset(el->fCharEd.fKill.fBuf, 0, EL_BUFSIZ);
00474 el->fCharEd.fKill.fMark = el->fLine.fBuffer;
00475 el->fCharEd.fKill.fLast = el->fCharEd.fKill.fBuf;
00476
00477 el->fMap.fCurrent = el->fMap.fKey;
00478
00479 el->fState.fInputMode = MODE_INSERT;
00480 el->fState.fDoingArg = 0;
00481 el->fState.fMetaNext = 0;
00482 el->fState.fArgument = 1;
00483 el->fState.fReplayHist = -1;
00484 el->fState.fLastCmd = ED_UNASSIGNED;
00485
00486 el->fCharEd.fMacro.fNLine = NULL;
00487 el->fCharEd.fMacro.fLevel = -1;
00488 el->fCharEd.fMacro.fMacro = (char**) el_malloc(EL_MAXMACRO *
00489 sizeof(char*));
00490
00491 if (el->fCharEd.fMacro.fMacro == NULL) {
00492 return -1;
00493 }
00494 return 0;
00495 }
00496
00497
00498
00499
00500
00501 el_protected void
00502 ch_reset(EditLine_t* el) {
00503 el->fLine.fCursor = el->fLine.fBuffer;
00504 el->fLine.fLastChar = el->fLine.fBuffer;
00505
00506 el->fCharEd.fUndo.fAction = NOP;
00507 el->fCharEd.fUndo.fISize = 0;
00508 el->fCharEd.fUndo.fDSize = 0;
00509 el->fCharEd.fUndo.fPtr = el->fLine.fBuffer;
00510
00511 el->fCharEd.fVCmd.fAction = NOP;
00512 el->fCharEd.fVCmd.fPos = el->fLine.fBuffer;
00513 el->fCharEd.fVCmd.fIns = el->fLine.fBuffer;
00514
00515 el->fCharEd.fKill.fMark = el->fLine.fBuffer;
00516
00517 el->fMap.fCurrent = el->fMap.fKey;
00518
00519 el->fState.fInputMode = MODE_INSERT;
00520 el->fState.fDoingArg = 0;
00521 el->fState.fMetaNext = 0;
00522 el->fState.fArgument = 1;
00523 el->fState.fLastCmd = ED_UNASSIGNED;
00524
00525 el->fCharEd.fMacro.fLevel = -1;
00526
00527 el->fHistory.fEventNo = 0;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536 el_protected int
00537 ch_enlargebufs(EditLine_t* el, size_t addlen) {
00538 size_t sz, newsz;
00539 char* newbuffer, * oldbuf, * oldkbuf;
00540 ElColor_t* newcolorbuf, * oldcolorbuf;
00541
00542 sz = el->fLine.fLimit - el->fLine.fBuffer + EL_LEAVE;
00543 newsz = sz * 2;
00544
00545
00546
00547
00548
00549 if (addlen > sz) {
00550 while (newsz - sz < addlen)
00551 newsz *= 2;
00552 }
00553
00554
00555
00556
00557 newbuffer = (char*) el_realloc(el->fLine.fBuffer, newsz);
00558 if (!newbuffer) {
00559 return 0;
00560 }
00561
00562 newcolorbuf = (ElColor_t*) el_realloc(el->fLine.fBufColor, newsz * sizeof(ElColor_t));
00563 if (!newcolorbuf) {
00564 el_free((ptr_t) newbuffer);
00565 return 0;
00566 }
00567
00568
00569
00570 (void) memset(&newbuffer[sz], 0, newsz - sz);
00571 (void) memset(&newcolorbuf[sz], 0, newsz - sz);
00572
00573 oldbuf = el->fLine.fBuffer;
00574 oldcolorbuf = el->fLine.fBufColor;
00575
00576 el->fLine.fBuffer = newbuffer;
00577 el->fLine.fBufColor = newcolorbuf;
00578 el->fLine.fCursor = newbuffer + (el->fLine.fCursor - oldbuf);
00579 el->fLine.fLastChar = newbuffer + (el->fLine.fLastChar - oldbuf);
00580 el->fLine.fLimit = &newbuffer[newsz - EL_LEAVE];
00581
00582
00583
00584
00585
00586
00587 newbuffer = (char*) el_realloc(el->fCharEd.fKill.fBuf, newsz);
00588
00589 if (!newbuffer) {
00590 return 0;
00591 }
00592
00593
00594 (void) memset(&newbuffer[sz], 0, newsz - sz);
00595
00596
00597 oldkbuf = el->fCharEd.fKill.fBuf;
00598
00599 el->fCharEd.fKill.fBuf = newbuffer;
00600 el->fCharEd.fKill.fLast = newbuffer +
00601 (el->fCharEd.fKill.fLast - oldkbuf);
00602 el->fCharEd.fKill.fMark = el->fLine.fBuffer +
00603 (el->fCharEd.fKill.fMark - oldbuf);
00604
00605
00606
00607
00608 newbuffer = (char*) el_realloc(el->fCharEd.fUndo.fBuf, newsz);
00609
00610 if (!newbuffer) {
00611 return 0;
00612 }
00613
00614
00615 (void) memset(&newbuffer[sz], 0, newsz - sz);
00616
00617 el->fCharEd.fUndo.fPtr = el->fLine.fBuffer +
00618 (el->fCharEd.fUndo.fPtr - oldbuf);
00619 el->fCharEd.fUndo.fBuf = newbuffer;
00620
00621 if (!hist_enlargebuf(el, sz, newsz)) {
00622 return 0;
00623 }
00624
00625 return 1;
00626 }
00627
00628
00629
00630
00631
00632 el_protected void
00633 ch_end(EditLine_t* el) {
00634 el_free((ptr_t) el->fLine.fBuffer);
00635 el->fLine.fBuffer = NULL;
00636 el_free((ptr_t) el->fLine.fBufColor);
00637 el->fLine.fBufColor = NULL;
00638 el->fLine.fLimit = NULL;
00639 el_free((ptr_t) el->fCharEd.fUndo.fBuf);
00640 el->fCharEd.fUndo.fBuf = NULL;
00641 el_free((ptr_t) el->fCharEd.fKill.fBuf);
00642 el->fCharEd.fKill.fBuf = NULL;
00643 el_free((ptr_t) el->fCharEd.fMacro.fMacro);
00644 el->fCharEd.fMacro.fMacro = NULL;
00645 ch_reset(el);
00646 }
00647
00648
00649
00650
00651
00652 el_public int
00653 el_insertstr(EditLine_t* el, const char* s) {
00654 size_t len;
00655
00656 if ((len = strlen(s)) == 0) {
00657 return -1;
00658 }
00659
00660 if (el->fLine.fLastChar + len >= el->fLine.fLimit) {
00661 if (!ch_enlargebufs(el, len)) {
00662 return -1;
00663 }
00664 }
00665
00666 c_insert(el, (int) len);
00667
00668 while (*s) {
00669
00670 el->fLine.fBufColor[el->fLine.fCursor - el->fLine.fBuffer] = -1;
00671
00672 *el->fLine.fCursor++ = *s++;
00673 }
00674 return 0;
00675 }
00676
00677
00678
00679
00680
00681 el_public void
00682 el_deletestr(EditLine_t* el, int n) {
00683 if (n <= 0) {
00684 return;
00685 }
00686
00687 if (el->fLine.fCursor < &el->fLine.fBuffer[n]) {
00688 return;
00689 }
00690
00691 c_delbefore(el, n);
00692 el->fLine.fCursor -= n;
00693
00694 if (el->fLine.fCursor < el->fLine.fBuffer) {
00695 el->fLine.fCursor = el->fLine.fBuffer;
00696 }
00697 }
00698
00699
00700
00701
00702
00703 el_protected int
00704 c_gets(EditLine_t* el, char* buf) {
00705 char ch;
00706 int len = 0;
00707
00708 for (ch = 0; ch == 0;) {
00709 if (el_getc(el, &ch) != 1) {
00710 return ed_end_of_file(el, 0);
00711 }
00712
00713 switch (ch) {
00714 case 0010:
00715 case 0177:
00716
00717 if (len > 1) {
00718 *el->fLine.fCursor-- = '\0';
00719 el->fLine.fLastChar = el->fLine.fCursor;
00720 buf[len--] = '\0';
00721 } else {
00722 el->fLine.fBuffer[0] = '\0';
00723 el->fLine.fLastChar = el->fLine.fBuffer;
00724 el->fLine.fCursor = el->fLine.fBuffer;
00725 return CC_REFRESH;
00726 }
00727 re_refresh(el);
00728 ch = 0;
00729 break;
00730
00731 case 0033:
00732 case '\r':
00733 case '\n':
00734 break;
00735
00736 default:
00737
00738 if (len >= EL_BUFSIZ) {
00739 term_beep(el);
00740 } else {
00741 buf[len++] = ch;
00742
00743 el->fLine.fBufColor[el->fLine.fCursor - el->fLine.fBuffer] = -1;
00744
00745 *el->fLine.fCursor++ = ch;
00746 el->fLine.fLastChar = el->fLine.fCursor;
00747 }
00748 re_refresh(el);
00749 ch = 0;
00750 break;
00751 }
00752 }
00753 buf[len] = ch;
00754 return len;
00755 }
00756
00757
00758
00759
00760
00761 el_protected int
00762 c_hpos(EditLine_t* el) {
00763 char* ptr;
00764
00765
00766
00767
00768 if (el->fLine.fCursor == el->fLine.fBuffer) {
00769 return 0;
00770 } else {
00771 for (ptr = el->fLine.fCursor - 1;
00772 ptr >= el->fLine.fBuffer && *ptr != '\n';
00773 ptr--) {
00774 continue;
00775 }
00776 return el->fLine.fCursor - ptr - 1;
00777 }
00778 }