69
69
/* readline compatibility stuff - look at readline sources/documentation */
70
70
/* to see what these variables mean */
71
71
const char *rl_library_version = "EditLine wrapper";
72
int rl_readline_version = RL_READLINE_VERSION;
72
73
static char empty[] = { '\0' };
73
74
static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
74
75
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
205
_getc_function(EditLine *el, char *c)
207
_getc_function(EditLine *el __attribute__((__unused__)), char *c)
209
211
i = (*rl_getc_function)(NULL);
219
_resize_fun(EditLine *el, void *a)
225
/* a cheesy way to get rid of const cast. */
226
*ap = memchr(li->buffer, *li->buffer, (size_t)1);
230
_default_history_file(void)
233
static char path[PATH_MAX];
237
if ((p = getpwuid(getuid())) == NULL)
239
(void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir);
218
244
* READLINE compatibility stuff
225
251
rl_set_prompt(const char *prompt)
229
257
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
233
261
rl_prompt = strdup(prompt);
234
return rl_prompt == NULL ? -1 : 0;
262
if (rl_prompt == NULL)
265
while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
266
*p = RL_PROMPT_START_IGNORE;
269
302
h = history_init();
273
306
history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
274
307
history_length = 0;
275
308
max_input_history = INT_MAX;
276
309
el_set(e, EL_HIST, history, h);
311
/* Setup resize function */
312
el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
278
314
/* setup getc function if valid */
279
315
if (rl_getc_function)
280
316
el_set(e, EL_GETCFN, _getc_function);
288
el_set(e, EL_PROMPT, _get_prompt);
324
el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
289
325
el_set(e, EL_SIGNAL, rl_catch_signals);
291
327
/* set default mode to "emacs"-style and read setting afterwards */
312
348
"ReadLine compatible suspend function",
314
350
el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
353
* Set some readline compatible key-bindings.
355
el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL);
358
* Allow the use of Home/End keys.
360
el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
361
el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
362
el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL);
363
el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL);
364
el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL);
365
el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL);
368
* Allow the use of the Delete/Insert keys.
370
el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
371
el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL);
374
* Ctrl-left-arrow and Ctrl-right-arrow for word moving.
376
el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
377
el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
378
el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL);
379
el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL);
380
el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
381
el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
316
383
/* read settings from configuration file */
317
384
el_source(e, NULL);
320
387
* Unfortunately, some applications really do use rl_point
321
388
* and rl_line_buffer directly.
324
/* a cheesy way to get rid of const cast. */
325
rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
390
_resize_fun(e, &rl_line_buffer);
326
391
_rl_update_pos();
328
393
if (rl_startup_hook)
329
394
(*rl_startup_hook)(NULL, 0);
587
len = (size_t)idx - (size_t)begin;
523
588
if (sub && cmd[idx] == '?')
525
590
if (sub && len == 0 && last_search_pat && *last_search_pat)
526
591
pat = last_search_pat;
527
592
else if (len == 0)
530
if ((pat = malloc(len + 1)) == NULL)
595
if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
532
597
(void)strncpy(pat, cmd + begin, len);
555
620
history(h, &ev, H_FIRST);
556
621
(void)fprintf(rl_outstream, "%s: Event not found\n", pat);
557
622
if (pat != last_search_pat)
562
627
if (sub && len) {
563
628
if (last_search_match && last_search_match != pat)
564
free(last_search_match);
629
el_free(last_search_match);
565
630
last_search_match = pat;
568
633
if (pat != last_search_pat)
571
636
if (history(h, &ev, H_CURR) != 0)
632
698
qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
633
699
ptr = get_history_event(command + offs, &idx, qchar);
635
has_mods = command[offs + idx] == ':';
701
has_mods = command[offs + (size_t)idx] == ':';
638
704
if (ptr == NULL && aptr == NULL)
642
*result = strdup(aptr? aptr : ptr);
708
*result = strdup(aptr ? aptr : ptr);
648
716
cmd = command + offs + idx + 1;
968
1039
history_arg_extract(int start, int end, const char *str)
970
1041
size_t i, len, max;
1042
char **arr, *result = NULL;
973
1044
arr = history_tokenize(str);
976
if (arr && *arr == NULL) {
1047
if (arr && *arr == NULL)
981
1050
for (max = 0; arr[max]; max++)
985
1054
if (start == '$')
1059
end = (int)max + end + 1;
994
if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end)
1063
if (start < 0 || end < 0 || (size_t)start > max ||
1064
(size_t)end > max || start > end)
997
for (i = start, len = 0; i <= (size_t)end; i++)
1067
for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
998
1068
len += strlen(arr[i]) + 1;
1000
result = malloc(len);
1070
result = el_malloc(len * sizeof(*result));
1001
1071
if (result == NULL)
1004
for (i = start, len = 0; i <= (size_t)end; i++) {
1074
for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
1005
1075
(void)strcpy(result + len, arr[i]);
1006
1076
len += strlen(arr[i]);
1007
1077
if (i < (size_t)end)
1050
1121
if (idx + 2 >= size) {
1051
1122
char **nresult;
1053
nresult = realloc(result, size * sizeof(char *));
1124
nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
1054
1125
if (nresult == NULL) {
1058
1129
result = nresult;
1061
temp = malloc(len + 1);
1131
len = (size_t)i - (size_t)start;
1132
temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
1062
1133
if (temp == NULL) {
1063
1134
for (i = 0; i < idx; i++)
1068
1139
(void)strncpy(temp, &str[start], len);
1115
1186
/* cannot return true answer */
1116
return (max_input_history != INT_MAX);
1187
return max_input_history != INT_MAX;
1190
static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1193
history_truncate_file (const char *filename, int nlines)
1197
char template[sizeof(_history_tmp_template)];
1205
if (filename == NULL && (filename = _default_history_file()) == NULL)
1207
if ((fp = fopen(filename, "r+")) == NULL)
1209
strcpy(template, _history_tmp_template);
1210
if ((fd = mkstemp(template)) == -1) {
1215
if ((tp = fdopen(fd, "r+")) == NULL) {
1222
if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
1227
if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
1232
left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
1240
} else if (fwrite(buf, (size_t)left, (size_t)1, tp)
1248
if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
1256
cp = buf + left - 1;
1260
while (--cp >= buf) {
1262
if (--nlines == 0) {
1263
if (++cp >= buf + sizeof(buf)) {
1271
if (nlines <= 0 || count == 0)
1274
if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
1278
if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
1286
cp = buf + sizeof(buf);
1289
if (ret || nlines > 0)
1292
if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
1297
if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
1304
if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
1309
if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
1315
if((off = ftello(fp)) > 0) {
1316
if (ftruncate(fileno(fp), off) == -1)
1128
1338
if (h == NULL || e == NULL)
1129
1339
rl_initialize();
1130
return (history(h, &ev, H_LOAD, filename) == -1);
1340
if (filename == NULL && (filename = _default_history_file()) == NULL)
1342
return history(h, &ev, H_LOAD, filename) == -1 ?
1343
(errno ? errno : EINVAL) : 0;
1142
1355
if (h == NULL || e == NULL)
1143
1356
rl_initialize();
1144
return (history(h, &ev, H_SAVE, filename) == -1);
1357
if (filename == NULL && (filename = _default_history_file()) == NULL)
1359
return history(h, &ev, H_SAVE, filename) == -1 ?
1360
(errno ? errno : EINVAL) : 0;
1163
1379
/* save current position */
1164
1380
if (history(h, &ev, H_CURR) != 0)
1166
1382
curr_num = ev.num;
1168
/* start from most recent */
1169
if (history(h, &ev, H_FIRST) != 0)
1170
return (NULL); /* error */
1384
/* start from the oldest */
1385
if (history(h, &ev, H_LAST) != 0)
1386
return NULL; /* error */
1172
/* look backwards for event matching specified offset */
1173
if (history(h, &ev, H_NEXT_EVENT, num + 1))
1388
/* look forwards for event matching specified offset */
1389
if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
1176
1392
she.line = ev.str;
1179
1394
/* restore pointer to where it was */
1180
1395
(void)history(h, &ev, H_SET, curr_num);
1209
1424
remove_history(int num)
1214
if (h == NULL || e == NULL)
1217
if (history(h, &ev, H_DEL, num) != 0)
1220
if ((she = malloc(sizeof(*she))) == NULL)
1429
if (h == NULL || e == NULL)
1432
if ((he = el_malloc(sizeof(*he))) == NULL)
1435
if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
1441
if (history(h, &ev, H_GETSIZE) == 0)
1442
history_length = ev.num;
1449
* replace the line and data of the num-th entry
1452
replace_history_entry(int num, const char *line, histdata_t data)
1458
if (h == NULL || e == NULL)
1461
/* save current position */
1462
if (history(h, &ev, H_CURR) != 0)
1466
/* start from the oldest */
1467
if (history(h, &ev, H_LAST) != 0)
1468
return NULL; /* error */
1470
if ((he = el_malloc(sizeof(*he))) == NULL)
1473
/* look forwards for event matching specified offset */
1474
if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
1477
he->line = strdup(ev.str);
1478
if (he->line == NULL)
1481
if (history(h, &ev, H_REPLACE, line, data))
1484
/* restore pointer to where it was */
1485
if (history(h, &ev, H_SET, curr_num))
1231
1495
* clear the history list - delete all entries
1249
1514
int curr_num, off;
1251
1516
if (history(h, &ev, H_CURR) != 0)
1253
1518
curr_num = ev.num;
1255
history(h, &ev, H_FIRST);
1520
(void)history(h, &ev, H_FIRST);
1257
1522
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
1279
1544
history_total_bytes(void)
1284
1550
if (history(h, &ev, H_CURR) != 0)
1286
1552
curr_num = ev.num;
1288
history(h, &ev, H_FIRST);
1554
(void)history(h, &ev, H_FIRST);
1291
size += strlen(ev.str);
1557
size += strlen(ev.str) * sizeof(*ev.str);
1292
1558
while (history(h, &ev, H_NEXT) == 0);
1294
1560
/* get to the same position as before */
1295
1561
history(h, &ev, H_PREV_EVENT, curr_num);
1310
if (pos > history_length || pos < 0)
1576
if (pos >= history_length || pos < 0)
1313
history(h, &ev, H_CURR);
1579
(void)history(h, &ev, H_CURR);
1314
1580
curr_num = ev.num;
1316
if (history(h, &ev, H_SET, pos)) {
1317
history(h, &ev, H_SET, curr_num);
1583
* use H_DELDATA to set to nth history (without delete) by passing
1586
if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
1587
(void)history(h, &ev, H_SET, curr_num);
1356
1626
if (history(h, &ev, H_CURR) != 0)
1358
1628
curr_num = ev.num;
1361
1631
if ((strp = strstr(ev.str, str)) != NULL)
1362
return (int) (strp - ev.str);
1632
return (int)(strp - ev.str);
1363
1633
if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
1366
history(h, &ev, H_SET, curr_num);
1636
(void)history(h, &ev, H_SET, curr_num);
1396
1667
pos = (pos > 0) ? 1 : -1;
1398
1669
if (history(h, &ev, H_CURR) != 0)
1400
1671
curr_num = ev.num;
1402
1673
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
1407
1677
if (strstr(ev.str, str))
1409
1679
if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
1413
1683
/* set "current" pointer back to previous state */
1414
history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1684
(void)history(h, &ev,
1685
pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1436
1707
* a completion generator for usernames; returns _first_ username
1437
1708
* which starts with supplied text
1438
1709
* text contains a partial username preceded by random character
1439
* (usually '~'); state is ignored
1710
* (usually '~'); state resets search from start (??? should we do that anyway)
1440
1711
* it's callers responsibility to free returned value
1443
1714
username_completion_function(const char *text, int state)
1716
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1717
struct passwd pwres;
1720
struct passwd *pass = NULL;
1447
1722
if (text[0] == '\0')
1450
1725
if (*text == '~')
1453
1728
if (state == 0)
1456
/* XXXMYSQL: just use non-_r functions for now */
1457
while ((pwd = getpwent()) && text[0] == pwd->pw_name[0]
1458
&& strcmp(text, pwd->pw_name) == 0);
1732
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1733
getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
1735
(pass = getpwent()) != NULL
1737
&& text[0] == pass->pw_name[0]
1738
&& strcmp(text, pass->pw_name) == 0)
1464
return (strdup(pwd->pw_name));
1745
return strdup(pass->pw_name);
1515
1800
arr[0] = (char)invoking_key;
1517
1802
el_insertstr(e, arr);
1518
return (CC_REFRESH);
1521
1806
/* Just look at how many global variables modify this operation! */
1522
1807
return fn_complete(e,
1523
1808
(CPFunction *)rl_completion_entry_function,
1524
1809
rl_attempted_completion_function,
1525
rl_basic_word_break_characters, rl_special_prefixes,
1526
_rl_completion_append_character_function, rl_completion_query_items,
1810
ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
1811
ct_decode_string(rl_special_prefixes, &sprefix_conv),
1812
_rl_completion_append_character_function,
1813
(size_t)rl_completion_query_items,
1527
1814
&rl_completion_type, &rl_attempted_completion_over,
1528
1815
&rl_point, &rl_end);
1602
1891
rl_initialize();
1604
1893
/* XXX - int -> char conversion can lose on multichars */
1608
1897
for (; count > 0; count--)
1609
1898
el_push(e, arr);
1904
rl_insert_text(const char *text)
1906
if (!text || *text == 0)
1909
if (h == NULL || e == NULL)
1912
if (el_insertstr(e, text) < 0)
1914
return (int)strlen(text);
1616
rl_newline(int count, int c)
1919
rl_newline(int count __attribute__((__unused__)),
1920
int c __attribute__((__unused__)))
1619
1923
* Readline-4.0 appears to ignore the args.
1756
2060
* The proper return value is undocument, but this is what the
1757
2061
* readline source seems to do.
1759
return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0);
2063
return el_set(e, EL_BIND, "", var, value) == -1 ? 1 : 0;
1782
2087
#if defined(FIONREAD)
1783
2088
if (ioctl(el->el_infd, FIONREAD, &n) < 0)
1786
num_read = read(el->el_infd, cp, 1);
2091
num_read = read(el->el_infd, cp, (size_t)1);
1789
2094
#elif defined(F_SETFL) && defined(O_NDELAY)
1790
2095
if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
1792
2097
if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
1794
2099
num_read = read(el->el_infd, cp, 1);
1795
2100
if (fcntl(el->el_infd, F_SETFL, n))
1798
2103
/* not non-blocking, but what you gonna do? */
1799
2104
num_read = read(el->el_infd, cp, 1);
1803
2108
if (num_read < 0 && errno == EAGAIN)
1920
2225
return strcoll(*s1, *s2);
2229
history_get_history_state(void)
2233
if ((hs = el_malloc(sizeof(*hs))) == NULL)
2235
hs->length = history_length;
1925
rl_kill_text(int from, int to)
2241
rl_kill_text(int from __attribute__((__unused__)),
2242
int to __attribute__((__unused__)))
1944
rl_set_keymap(Keymap k)
1950
rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k)
1957
rl_bind_key_in_map(int key, Function *fun, Keymap k)
2261
rl_set_keymap(Keymap k __attribute__((__unused__)))
2267
rl_generic_bind(int type __attribute__((__unused__)),
2268
const char * keyseq __attribute__((__unused__)),
2269
const char * data __attribute__((__unused__)),
2270
Keymap k __attribute__((__unused__)))
2277
rl_bind_key_in_map(int key __attribute__((__unused__)),
2278
rl_command_func_t *fun __attribute__((__unused__)),
2279
Keymap k __attribute__((__unused__)))
2284
/* unsupported, but needed by python */
2286
rl_cleanup_after_signal(void)
2291
rl_on_new_line(void)