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