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
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include "sys.h"
00070 #include <string.h>
00071 #include <stdlib.h>
00072
00073 #include "el.h"
00074
00075
00076
00077
00078
00079 struct KeyNode_t {
00080 char fCh;
00081 int fType;
00082 KeyValue_t fVal;
00083
00084 struct KeyNode_t* fNext;
00085 struct KeyNode_t* fSibling;
00086 };
00087
00088 el_private int node_trav(EditLine_t*, KeyNode_t*, char*,
00089 KeyValue_t*);
00090 el_private int node__try(EditLine_t*, KeyNode_t*, const char*,
00091 KeyValue_t*, int);
00092 el_private KeyNode_t* node__get(int);
00093 el_private void node__put(EditLine_t*, KeyNode_t*);
00094 el_private int node__delete(EditLine_t*, KeyNode_t**, char*);
00095 el_private int node_lookup(EditLine_t*, const char*, KeyNode_t*, int);
00096 el_private int node_enum(EditLine_t*, KeyNode_t*, int);
00097 el_private int key__decode_char(char*, int, int);
00098
00099 #define KEY_BUFSIZ EL_BUFSIZ
00100
00101
00102
00103
00104
00105 el_protected int
00106 key_init(EditLine_t* el) {
00107 el->fKey.fBuf = (char*) el_malloc(KEY_BUFSIZ);
00108
00109 if (el->fKey.fBuf == NULL) {
00110 return -1;
00111 }
00112 el->fKey.fMap = NULL;
00113 key_reset(el);
00114 return 0;
00115 }
00116
00117
00118
00119
00120
00121 el_protected void
00122 key_end(EditLine_t* el) {
00123 el_free((ptr_t) el->fKey.fBuf);
00124 el->fKey.fBuf = NULL;
00125
00126 el->fKey.fMap = NULL;
00127 }
00128
00129
00130
00131
00132
00133 el_protected KeyValue_t*
00134 key_map_cmd(EditLine_t* el, int cmd) {
00135 el->fKey.fVal.fCmd = (ElAction_t) cmd;
00136 return &el->fKey.fVal;
00137 }
00138
00139
00140
00141
00142
00143 el_protected KeyValue_t*
00144 key_map_str(EditLine_t* el, char* str) {
00145 el->fKey.fVal.fStr = str;
00146 return &el->fKey.fVal;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 el_protected void
00156 key_reset(EditLine_t* el) {
00157 node__put(el, el->fKey.fMap);
00158 el->fKey.fMap = NULL;
00159 return;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 el_protected int
00172 key_get(EditLine_t* el, char* ch, KeyValue_t* val) {
00173 return node_trav(el, el->fKey.fMap, ch, val);
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 el_protected void
00184 key_add(EditLine_t* el, const char* key, KeyValue_t* val, int ntype) {
00185 if (key[0] == '\0') {
00186 (void) fprintf(el->fErrFile,
00187 "key_add: Null extended-key not allowed.\n");
00188 return;
00189 }
00190
00191 if (ntype == XK_CMD && val->fCmd == ED_SEQUENCE_LEAD_IN) {
00192 (void) fprintf(el->fErrFile,
00193 "key_add: sequence-lead-in command not allowed\n");
00194 return;
00195 }
00196
00197 if (el->fKey.fMap == NULL) {
00198
00199 el->fKey.fMap = node__get(key[0]);
00200 }
00201
00202
00203
00204 (void) node__try(el, el->fKey.fMap, key, val, ntype);
00205 return;
00206 }
00207
00208
00209
00210
00211
00212 el_protected void
00213 key_clear(EditLine_t* el, ElAction_t* map, char* in) {
00214 if ((map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) &&
00215 ((map == el->fMap.fKey &&
00216 el->fMap.fAlt[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN) ||
00217 (map == el->fMap.fAlt &&
00218 el->fMap.fKey[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN))) {
00219 (void) key_delete(el, in);
00220 }
00221 }
00222
00223
00224
00225
00226
00227
00228 el_protected int
00229 key_delete(EditLine_t* el, char* key) {
00230 if (key[0] == '\0') {
00231 (void) fprintf(el->fErrFile,
00232 "key_delete: Null extended-key not allowed.\n");
00233 return -1;
00234 }
00235
00236 if (el->fKey.fMap == NULL) {
00237 return 0;
00238 }
00239
00240 (void) node__delete(el, &el->fKey.fMap, key);
00241 return 0;
00242 }
00243
00244
00245
00246
00247
00248
00249 el_protected void
00250 key_print(EditLine_t* el, const char* key) {
00251
00252 if (el->fKey.fMap == NULL && *key == 0) {
00253 return;
00254 }
00255
00256 el->fKey.fBuf[0] = '"';
00257
00258 if (node_lookup(el, key, el->fKey.fMap, 1) <= -1) {
00259
00260 (void) fprintf(el->fErrFile, "Unbound extended key \"%s\"\n",
00261 key);
00262 }
00263 return;
00264 }
00265
00266
00267
00268
00269
00270
00271 el_private int
00272 node_trav(EditLine_t* el, KeyNode_t* ptr, char* ch, KeyValue_t* val) {
00273 if (ptr->fCh == *ch) {
00274
00275 if (ptr->fNext) {
00276
00277 if (el_getc(el, ch) != 1) {
00278 val->fCmd = ED_END_OF_FILE;
00279 return XK_CMD;
00280
00281 }
00282 return node_trav(el, ptr->fNext, ch, val);
00283 } else {
00284 *val = ptr->fVal;
00285
00286 if (ptr->fType != XK_CMD) {
00287 *ch = '\0';
00288 }
00289 return ptr->fType;
00290 }
00291 } else {
00292
00293 if (ptr->fSibling) {
00294
00295 return node_trav(el, ptr->fSibling, ch, val);
00296 } else {
00297
00298 val->fStr = NULL;
00299 return XK_STR;
00300 }
00301 }
00302 }
00303
00304
00305
00306
00307
00308 el_private int
00309 node__try(EditLine_t* el, KeyNode_t* ptr, const char* str, KeyValue_t* val, int ntype) {
00310 if (ptr->fCh != *str) {
00311 KeyNode_t* xm;
00312
00313 for (xm = ptr; xm->fSibling != NULL; xm = xm->fSibling) {
00314 if (xm->fSibling->fCh == *str) {
00315 break;
00316 }
00317 }
00318
00319 if (xm->fSibling == NULL) {
00320 xm->fSibling = node__get(*str);
00321 }
00322 ptr = xm->fSibling;
00323 }
00324
00325 if (*++str == '\0') {
00326
00327 if (ptr->fNext != NULL) {
00328 node__put(el, ptr->fNext);
00329
00330 ptr->fNext = NULL;
00331 }
00332
00333 switch (ptr->fType) {
00334 case XK_CMD:
00335 case XK_NOD:
00336 break;
00337 case XK_STR:
00338 case XK_EXE:
00339
00340 if (ptr->fVal.fStr) {
00341 el_free((ptr_t) ptr->fVal.fStr);
00342 }
00343 break;
00344 default:
00345 EL_ABORT((el->fErrFile, "Bad XK_ type %d\n",
00346 ptr->fType));
00347 break;
00348 }
00349
00350 switch (ptr->fType = ntype) {
00351 case XK_CMD:
00352 ptr->fVal = *val;
00353 break;
00354 case XK_STR:
00355 case XK_EXE:
00356 ptr->fVal.fStr = strdup(val->fStr);
00357 break;
00358 default:
00359 EL_ABORT((el->fErrFile, "Bad XK_ type %d\n", ntype));
00360 break;
00361 }
00362 } else {
00363
00364 if (ptr->fNext == NULL) {
00365 ptr->fNext = node__get(*str);
00366 }
00367 (void) node__try(el, ptr->fNext, str, val, ntype);
00368 }
00369 return 0;
00370 }
00371
00372
00373
00374
00375
00376 el_private int
00377 node__delete(EditLine_t* el, KeyNode_t** inptr, char* str) {
00378 KeyNode_t* ptr;
00379 KeyNode_t* prev_ptr = NULL;
00380
00381 ptr = *inptr;
00382
00383 if (ptr->fCh != *str) {
00384 KeyNode_t* xm;
00385
00386 for (xm = ptr; xm->fSibling != NULL; xm = xm->fSibling) {
00387 if (xm->fSibling->fCh == *str) {
00388 break;
00389 }
00390 }
00391
00392 if (xm->fSibling == NULL) {
00393 return 0;
00394 }
00395 prev_ptr = xm;
00396 ptr = xm->fSibling;
00397 }
00398
00399 if (*++str == '\0') {
00400
00401 if (prev_ptr == NULL) {
00402 *inptr = ptr->fSibling;
00403 } else {
00404 prev_ptr->fSibling = ptr->fSibling;
00405 }
00406 ptr->fSibling = NULL;
00407 node__put(el, ptr);
00408 return 1;
00409 } else if (ptr->fNext != NULL &&
00410 node__delete(el, &ptr->fNext, str) == 1) {
00411 if (ptr->fNext != NULL) {
00412 return 0;
00413 }
00414
00415 if (prev_ptr == NULL) {
00416 *inptr = ptr->fSibling;
00417 } else {
00418 prev_ptr->fSibling = ptr->fSibling;
00419 }
00420 ptr->fSibling = NULL;
00421 node__put(el, ptr);
00422 return 1;
00423 } else {
00424 return 0;
00425 }
00426 }
00427
00428
00429
00430
00431
00432 el_private void
00433 node__put(EditLine_t* el, KeyNode_t* ptr) {
00434 if (ptr == NULL) {
00435 return;
00436 }
00437
00438 if (ptr->fNext != NULL) {
00439 node__put(el, ptr->fNext);
00440 ptr->fNext = NULL;
00441 }
00442 node__put(el, ptr->fSibling);
00443
00444 switch (ptr->fType) {
00445 case XK_CMD:
00446 case XK_NOD:
00447 break;
00448 case XK_EXE:
00449 case XK_STR:
00450
00451 if (ptr->fVal.fStr != NULL) {
00452 el_free((ptr_t) ptr->fVal.fStr);
00453 }
00454 break;
00455 default:
00456 EL_ABORT((el->fErrFile, "Bad XK_ type %d\n", ptr->fType));
00457 break;
00458 }
00459 el_free((ptr_t) ptr);
00460 }
00461
00462
00463
00464
00465
00466 el_private KeyNode_t*
00467 node__get(int ch) {
00468 KeyNode_t* ptr;
00469
00470 ptr = (KeyNode_t*) el_malloc((size_t) sizeof(KeyNode_t));
00471
00472 if (ptr == NULL) {
00473 return NULL;
00474 }
00475 ptr->fCh = ch;
00476 ptr->fType = XK_NOD;
00477 ptr->fVal.fStr = NULL;
00478 ptr->fNext = NULL;
00479 ptr->fSibling = NULL;
00480 return ptr;
00481 }
00482
00483
00484
00485
00486
00487
00488 el_private int
00489 node_lookup(EditLine_t* el, const char* str, KeyNode_t* ptr, int cnt) {
00490 int ncnt;
00491
00492 if (ptr == NULL) {
00493 return -1;
00494
00495 }
00496
00497 if (*str == 0) {
00498
00499 (void) node_enum(el, ptr, cnt);
00500 return 0;
00501 } else {
00502
00503 if (ptr->fCh == *str) {
00504
00505 ncnt = key__decode_char(el->fKey.fBuf, cnt,
00506 (unsigned char) ptr->fCh);
00507
00508 if (ptr->fNext != NULL) {
00509
00510 return node_lookup(el, str + 1, ptr->fNext,
00511 ncnt + 1);
00512 } else {
00513
00514 if (str[1] == 0) {
00515 el->fKey.fBuf[ncnt + 1] = '"';
00516 el->fKey.fBuf[ncnt + 2] = '\0';
00517 key_kprint(el, el->fKey.fBuf,
00518 &ptr->fVal, ptr->fType);
00519 return 0;
00520 } else {
00521 return -1;
00522 }
00523
00524 }
00525 } else {
00526
00527 if (ptr->fSibling) {
00528 return node_lookup(el, str, ptr->fSibling,
00529 cnt);
00530 } else {
00531 return -1;
00532 }
00533 }
00534 }
00535 }
00536
00537
00538
00539
00540
00541 el_private int
00542 node_enum(EditLine_t* el, KeyNode_t* ptr, int cnt) {
00543 int ncnt;
00544
00545 if (cnt >= KEY_BUFSIZ - 5) {
00546 el->fKey.fBuf[++cnt] = '"';
00547 el->fKey.fBuf[++cnt] = '\0';
00548 (void) fprintf(el->fErrFile,
00549 "Some extended keys too long for internal print buffer");
00550 (void) fprintf(el->fErrFile, " \"%s...\"\n", el->fKey.fBuf);
00551 return 0;
00552 }
00553
00554 if (ptr == NULL) {
00555 #ifdef DEBUG_EDIT
00556 (void) fprintf(el->fErrFile,
00557 "node_enum: BUG!! Null ptr passed\n!");
00558 #endif
00559 return -1;
00560 }
00561
00562 ncnt = key__decode_char(el->fKey.fBuf, cnt, (unsigned char) ptr->fCh);
00563
00564 if (ptr->fNext == NULL) {
00565
00566 el->fKey.fBuf[ncnt + 1] = '"';
00567 el->fKey.fBuf[ncnt + 2] = '\0';
00568 key_kprint(el, el->fKey.fBuf, &ptr->fVal, ptr->fType);
00569 } else {
00570 (void) node_enum(el, ptr->fNext, ncnt + 1);
00571 }
00572
00573
00574 if (ptr->fSibling) {
00575 (void) node_enum(el, ptr->fSibling, cnt);
00576 }
00577 return 0;
00578 }
00579
00580
00581
00582
00583
00584
00585 el_protected void
00586 key_kprint(EditLine_t* el, const char* key, KeyValue_t* val, int ntype) {
00587 ElBindings_t* fp;
00588 char unparsbuf[EL_BUFSIZ];
00589 static const char fmt[] = "%-15s-> %s\n";
00590
00591 if (val != NULL) {
00592 switch (ntype) {
00593 case XK_STR:
00594 case XK_EXE:
00595 (void) fprintf(el->fOutFile, fmt, key,
00596 key__decode_str(val->fStr, unparsbuf,
00597 ntype == XK_STR ? "\"\"" : "[]"));
00598 break;
00599 case XK_CMD:
00600
00601 for (fp = el->fMap.fHelp; fp->fName; fp++) {
00602 if (val->fCmd == fp->fFunc) {
00603 (void) fprintf(el->fOutFile, fmt,
00604 key, fp->fName);
00605 break;
00606 }
00607 }
00608 #ifdef DEBUG_KEY
00609
00610 if (fp->fName == NULL) {
00611 (void) fprintf(el->fOutFile,
00612 "BUG! Command not found.\n");
00613 }
00614 #endif
00615
00616 break;
00617 default:
00618 EL_ABORT((el->fErrFile, "Bad XK_ type %d\n", ntype));
00619 break;
00620 }
00621 } else {
00622 (void) fprintf(el->fOutFile, fmt, key, "no input");
00623 }
00624 }
00625
00626
00627
00628
00629
00630 el_private int
00631 key__decode_char(char* buf, int cnt, int ch) {
00632 if (ch == 0) {
00633 buf[cnt++] = '^';
00634 buf[cnt] = '@';
00635 return cnt;
00636 }
00637
00638 if (iscntrl(ch)) {
00639 buf[cnt++] = '^';
00640
00641 if (ch == '\177') {
00642 buf[cnt] = '?';
00643 } else {
00644 buf[cnt] = ch | 0100;
00645 }
00646 } else if (ch == '^') {
00647 buf[cnt++] = '\\';
00648 buf[cnt] = '^';
00649 } else if (ch == '\\') {
00650 buf[cnt++] = '\\';
00651 buf[cnt] = '\\';
00652 } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
00653 buf[cnt] = ch;
00654 } else {
00655 buf[cnt++] = '\\';
00656 buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0';
00657 buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0';
00658 buf[cnt] = (ch & 7) + '0';
00659 }
00660 return cnt;
00661 }
00662
00663
00664
00665
00666
00667 el_protected char*
00668 key__decode_str(char* str, char* buf, const char* sep) {
00669 char* b, * p;
00670
00671 b = buf;
00672
00673 if (sep[0] != '\0') {
00674 *b++ = sep[0];
00675 }
00676
00677 if (*str == 0) {
00678 *b++ = '^';
00679 *b++ = '@';
00680
00681 if (sep[0] != '\0' && sep[1] != '\0') {
00682 *b++ = sep[1];
00683 }
00684 *b++ = 0;
00685 return buf;
00686 }
00687
00688 for (p = str; *p != 0; p++) {
00689 if (iscntrl((unsigned char) *p)) {
00690 *b++ = '^';
00691
00692 if (*p == '\177') {
00693 *b++ = '?';
00694 } else {
00695 *b++ = *p | 0100;
00696 }
00697 } else if (*p == '^' || *p == '\\') {
00698 *b++ = '\\';
00699 *b++ = *p;
00700 } else if (*p == ' ' || (isprint((unsigned char) *p) &&
00701 !isspace((unsigned char) *p))) {
00702 *b++ = *p;
00703 } else {
00704 *b++ = '\\';
00705 *b++ = (((unsigned int) *p >> 6) & 7) + '0';
00706 *b++ = (((unsigned int) *p >> 3) & 7) + '0';
00707 *b++ = (*p & 7) + '0';
00708 }
00709 }
00710
00711 if (sep[0] != '\0' && sep[1] != '\0') {
00712 *b++ = sep[1];
00713 }
00714 *b++ = 0;
00715 return buf;
00716 }