~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to cmd-line-utils/libedit/chared.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $       */
 
2
 
 
3
/*-
 
4
 * Copyright (c) 1992, 1993
 
5
 *      The Regents of the University of California.  All rights reserved.
 
6
 *
 
7
 * This code is derived from software contributed to Berkeley by
 
8
 * Christos Zoulas of Cornell University.
 
9
 *
 
10
 * Redistribution and use in source and binary forms, with or without
 
11
 * modification, are permitted provided that the following conditions
 
12
 * are met:
 
13
 * 1. Redistributions of source code must retain the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer.
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in the
 
17
 *    documentation and/or other materials provided with the distribution.
 
18
 * 3. Neither the name of the University nor the names of its contributors
 
19
 *    may be used to endorse or promote products derived from this software
 
20
 *    without specific prior written permission.
 
21
 *
 
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
32
 * SUCH DAMAGE.
 
33
 */
 
34
 
 
35
#include "config.h"
 
36
#if !defined(lint) && !defined(SCCSID)
 
37
#if 0
 
38
static char sccsid[] = "@(#)chared.c    8.1 (Berkeley) 6/4/93";
 
39
#else
 
40
#endif
 
41
#endif /* not lint && not SCCSID */
 
42
 
 
43
/*
 
44
 * chared.c: Character editor utilities
 
45
 */
 
46
#include <stdlib.h>
 
47
#include "el.h"
 
48
 
 
49
private void ch__clearmacro (EditLine *);
 
50
 
 
51
/* value to leave unused in line buffer */
 
52
#define EL_LEAVE        2
 
53
 
 
54
/* cv_undo():
 
55
 *      Handle state for the vi undo command
 
56
 */
 
57
protected void
 
58
cv_undo(EditLine *el)
 
59
{
 
60
        c_undo_t *vu = &el->el_chared.c_undo;
 
61
        c_redo_t *r = &el->el_chared.c_redo;
 
62
        unsigned int size;
 
63
 
 
64
        /* Save entire line for undo */
 
65
        size = el->el_line.lastchar - el->el_line.buffer;
 
66
        vu->len = size;
 
67
        vu->cursor = el->el_line.cursor - el->el_line.buffer;
 
68
        memcpy(vu->buf, el->el_line.buffer, size);
 
69
 
 
70
        /* save command info for redo */
 
71
        r->count = el->el_state.doingarg ? el->el_state.argument : 0;
 
72
        r->action = el->el_chared.c_vcmd.action;
 
73
        r->pos = r->buf;
 
74
        r->cmd = el->el_state.thiscmd;
 
75
        r->ch = el->el_state.thisch;
 
76
}
 
77
 
 
78
/* cv_yank():
 
79
 *      Save yank/delete data for paste
 
80
 */
 
81
protected void
 
82
cv_yank(EditLine *el, const char *ptr, int size)
 
83
{
 
84
        c_kill_t *k = &el->el_chared.c_kill;
 
85
 
 
86
        memcpy(k->buf, ptr, size +0u);
 
87
        k->last = k->buf + size;
 
88
}
 
89
 
 
90
 
 
91
/* c_insert():
 
92
 *      Insert num characters
 
93
 */
 
94
protected void
 
95
c_insert(EditLine *el, int num)
 
96
{
 
97
        char *cp;
 
98
 
 
99
        if (el->el_line.lastchar + num >= el->el_line.limit) {
 
100
                if (!ch_enlargebufs(el, num +0u))
 
101
                        return;         /* can't go past end of buffer */
 
102
        }
 
103
 
 
104
        if (el->el_line.cursor < el->el_line.lastchar) {
 
105
                /* if I must move chars */
 
106
                for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
 
107
                        cp[num] = *cp;
 
108
        }
 
109
        el->el_line.lastchar += num;
 
110
}
 
111
 
 
112
 
 
113
/* c_delafter():
 
114
 *      Delete num characters after the cursor
 
115
 */
 
116
protected void
 
117
c_delafter(EditLine *el, int num)
 
118
{
 
119
 
 
120
        if (el->el_line.cursor + num > el->el_line.lastchar)
 
121
                num = el->el_line.lastchar - el->el_line.cursor;
 
122
 
 
123
        if (el->el_map.current != el->el_map.emacs) {
 
124
                cv_undo(el);
 
125
                cv_yank(el, el->el_line.cursor, num);
 
126
        }
 
127
 
 
128
        if (num > 0) {
 
129
                char *cp;
 
130
 
 
131
                for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
 
132
                        *cp = cp[num];
 
133
 
 
134
                el->el_line.lastchar -= num;
 
135
        }
 
136
}
 
137
 
 
138
 
 
139
/* c_delafter1():
 
140
 *      Delete the character after the cursor, do not yank
 
141
 */
 
142
protected void
 
143
c_delafter1(EditLine *el)
 
144
{
 
145
        char *cp;
 
146
 
 
147
        for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
 
148
                *cp = cp[1];
 
149
 
 
150
        el->el_line.lastchar--;
 
151
}
 
152
 
 
153
 
 
154
/* c_delbefore():
 
155
 *      Delete num characters before the cursor
 
156
 */
 
157
protected void
 
158
c_delbefore(EditLine *el, int num)
 
159
{
 
160
 
 
161
        if (el->el_line.cursor - num < el->el_line.buffer)
 
162
                num = el->el_line.cursor - el->el_line.buffer;
 
163
 
 
164
        if (el->el_map.current != el->el_map.emacs) {
 
165
                cv_undo(el);
 
166
                cv_yank(el, el->el_line.cursor - num, num);
 
167
        }
 
168
 
 
169
        if (num > 0) {
 
170
                char *cp;
 
171
 
 
172
                for (cp = el->el_line.cursor - num;
 
173
                    cp <= el->el_line.lastchar;
 
174
                    cp++)
 
175
                        *cp = cp[num];
 
176
 
 
177
                el->el_line.lastchar -= num;
 
178
        }
 
179
}
 
180
 
 
181
 
 
182
/* c_delbefore1():
 
183
 *      Delete the character before the cursor, do not yank
 
184
 */
 
185
protected void
 
186
c_delbefore1(EditLine *el)
 
187
{
 
188
        char *cp;
 
189
 
 
190
        for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
 
191
                *cp = cp[1];
 
192
 
 
193
        el->el_line.lastchar--;
 
194
}
 
195
 
 
196
 
 
197
/* ce__isword():
 
198
 *      Return if p is part of a word according to emacs
 
199
 */
 
200
protected int
 
201
ce__isword(int p)
 
202
{
 
203
        return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
 
204
}
 
205
 
 
206
 
 
207
/* cv__isword():
 
208
 *      Return if p is part of a word according to vi
 
209
 */
 
210
protected int
 
211
cv__isword(int p)
 
212
{
 
213
        if (isalnum(p) || p == '_')
 
214
                return 1;
 
215
        if (isgraph(p))
 
216
                return 2;
 
217
        return 0;
 
218
}
 
219
 
 
220
 
 
221
/* cv__isWord():
 
222
 *      Return if p is part of a big word according to vi
 
223
 */
 
224
protected int
 
225
cv__isWord(int p)
 
226
{
 
227
        return (!isspace(p));
 
228
}
 
229
 
 
230
 
 
231
/* c__prev_word():
 
232
 *      Find the previous word
 
233
 */
 
234
protected char *
 
235
c__prev_word(char *p, char *low, int n, int (*wtest)(int))
 
236
{
 
237
        p--;
 
238
 
 
239
        while (n--) {
 
240
                while ((p >= low) && !(*wtest)((unsigned char) *p))
 
241
                        p--;
 
242
                while ((p >= low) && (*wtest)((unsigned char) *p))
 
243
                        p--;
 
244
        }
 
245
 
 
246
        /* cp now points to one character before the word */
 
247
        p++;
 
248
        if (p < low)
 
249
                p = low;
 
250
        /* cp now points where we want it */
 
251
        return (p);
 
252
}
 
253
 
 
254
 
 
255
/* c__next_word():
 
256
 *      Find the next word
 
257
 */
 
258
protected char *
 
259
c__next_word(char *p, char *high, int n, int (*wtest)(int))
 
260
{
 
261
        while (n--) {
 
262
                while ((p < high) && !(*wtest)((unsigned char) *p))
 
263
                        p++;
 
264
                while ((p < high) && (*wtest)((unsigned char) *p))
 
265
                        p++;
 
266
        }
 
267
        if (p > high)
 
268
                p = high;
 
269
        /* p now points where we want it */
 
270
        return (p);
 
271
}
 
272
 
 
273
/* cv_next_word():
 
274
 *      Find the next word vi style
 
275
 */
 
276
protected char *
 
277
cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
 
278
{
 
279
        int test;
 
280
 
 
281
        while (n--) {
 
282
                test = (*wtest)((unsigned char) *p);
 
283
                while ((p < high) && (*wtest)((unsigned char) *p) == test)
 
284
                        p++;
 
285
                /*
 
286
                 * vi historically deletes with cw only the word preserving the
 
287
                 * trailing whitespace! This is not what 'w' does..
 
288
                 */
 
289
                if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
 
290
                        while ((p < high) && isspace((unsigned char) *p))
 
291
                                p++;
 
292
        }
 
293
 
 
294
        /* p now points where we want it */
 
295
        if (p > high)
 
296
                return (high);
 
297
        else
 
298
                return (p);
 
299
}
 
300
 
 
301
 
 
302
/* cv_prev_word():
 
303
 *      Find the previous word vi style
 
304
 */
 
305
protected char *
 
306
cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
 
307
{
 
308
        int test;
 
309
 
 
310
        p--;
 
311
        while (n--) {
 
312
                while ((p > low) && isspace((unsigned char) *p))
 
313
                        p--;
 
314
                test = (*wtest)((unsigned char) *p);
 
315
                while ((p >= low) && (*wtest)((unsigned char) *p) == test)
 
316
                        p--;
 
317
        }
 
318
        p++;
 
319
 
 
320
        /* p now points where we want it */
 
321
        if (p < low)
 
322
                return (low);
 
323
        else
 
324
                return (p);
 
325
}
 
326
 
 
327
 
 
328
#ifdef notdef
 
329
/* c__number():
 
330
 *      Ignore character p points to, return number appearing after that.
 
331
 *      A '$' by itself means a big number; "$-" is for negative; '^' means 1.
 
332
 *      Return p pointing to last char used.
 
333
 */
 
334
protected char *
 
335
c__number(
 
336
    char *p,    /* character position */
 
337
    int *num,   /* Return value */
 
338
    int dval)   /* dval is the number to subtract from like $-3 */
 
339
{
 
340
        int i;
 
341
        int sign = 1;
 
342
 
 
343
        if (*++p == '^') {
 
344
                *num = 1;
 
345
                return (p);
 
346
        }
 
347
        if (*p == '$') {
 
348
                if (*++p != '-') {
 
349
                        *num = 0x7fffffff;      /* Handle $ */
 
350
                        return (--p);
 
351
                }
 
352
                sign = -1;                      /* Handle $- */
 
353
                ++p;
 
354
        }
 
355
        for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
 
356
                continue;
 
357
        *num = (sign < 0 ? dval - i : i);
 
358
        return (--p);
 
359
}
 
360
#endif
 
361
 
 
362
/* cv_delfini():
 
363
 *      Finish vi delete action
 
364
 */
 
365
protected void
 
366
cv_delfini(EditLine *el)
 
367
{
 
368
        int size;
 
369
        int action = el->el_chared.c_vcmd.action;
 
370
 
 
371
        if (action & INSERT)
 
372
                el->el_map.current = el->el_map.key;
 
373
 
 
374
        if (el->el_chared.c_vcmd.pos == 0)
 
375
                /* sanity */
 
376
                return;
 
377
 
 
378
        size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
 
379
        if (size == 0)
 
380
                size = 1;
 
381
        el->el_line.cursor = el->el_chared.c_vcmd.pos;
 
382
        if (action & YANK) {
 
383
                if (size > 0)
 
384
                        cv_yank(el, el->el_line.cursor, size);
 
385
                else
 
386
                        cv_yank(el, el->el_line.cursor + size, -size);
 
387
        } else {
 
388
                if (size > 0) {
 
389
                        c_delafter(el, size);
 
390
                        re_refresh_cursor(el);
 
391
                } else  {
 
392
                        c_delbefore(el, -size);
 
393
                        el->el_line.cursor += size;
 
394
                }
 
395
        }
 
396
        el->el_chared.c_vcmd.action = NOP;
 
397
}
 
398
 
 
399
 
 
400
#ifdef notdef
 
401
/* ce__endword():
 
402
 *      Go to the end of this word according to emacs
 
403
 */
 
404
protected char *
 
405
ce__endword(char *p, char *high, int n)
 
406
{
 
407
        p++;
 
408
 
 
409
        while (n--) {
 
410
                while ((p < high) && isspace((unsigned char) *p))
 
411
                        p++;
 
412
                while ((p < high) && !isspace((unsigned char) *p))
 
413
                        p++;
 
414
        }
 
415
 
 
416
        p--;
 
417
        return (p);
 
418
}
 
419
#endif
 
420
 
 
421
 
 
422
/* cv__endword():
 
423
 *      Go to the end of this word according to vi
 
424
 */
 
425
protected char *
 
426
cv__endword(char *p, char *high, int n, int (*wtest)(int))
 
427
{
 
428
        int test;
 
429
 
 
430
        p++;
 
431
 
 
432
        while (n--) {
 
433
                while ((p < high) && isspace((unsigned char) *p))
 
434
                        p++;
 
435
 
 
436
                test = (*wtest)((unsigned char) *p);
 
437
                while ((p < high) && (*wtest)((unsigned char) *p) == test)
 
438
                        p++;
 
439
        }
 
440
        p--;
 
441
        return (p);
 
442
}
 
443
 
 
444
/* ch_init():
 
445
 *      Initialize the character editor
 
446
 */
 
447
protected int
 
448
ch_init(EditLine *el)
 
449
{
 
450
        c_macro_t *ma = &el->el_chared.c_macro;
 
451
 
 
452
        el->el_line.buffer              = (char *) el_malloc(EL_BUFSIZ);
 
453
        if (el->el_line.buffer == NULL)
 
454
                return (-1);
 
455
 
 
456
        (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
 
457
        el->el_line.cursor              = el->el_line.buffer;
 
458
        el->el_line.lastchar            = el->el_line.buffer;
 
459
        el->el_line.limit               = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
 
460
 
 
461
        el->el_chared.c_undo.buf        = (char *) el_malloc(EL_BUFSIZ);
 
462
        if (el->el_chared.c_undo.buf == NULL)
 
463
                return (-1);
 
464
        (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
 
465
        el->el_chared.c_undo.len        = -1;
 
466
        el->el_chared.c_undo.cursor     = 0;
 
467
        el->el_chared.c_redo.buf        = (char *) el_malloc(EL_BUFSIZ);
 
468
        if (el->el_chared.c_redo.buf == NULL)
 
469
                return (-1);
 
470
        el->el_chared.c_redo.pos        = el->el_chared.c_redo.buf;
 
471
        el->el_chared.c_redo.lim        = el->el_chared.c_redo.buf + EL_BUFSIZ;
 
472
        el->el_chared.c_redo.cmd        = ED_UNASSIGNED;
 
473
 
 
474
        el->el_chared.c_vcmd.action     = NOP;
 
475
        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
 
476
 
 
477
        el->el_chared.c_kill.buf        = (char *) el_malloc(EL_BUFSIZ);
 
478
        if (el->el_chared.c_kill.buf == NULL)
 
479
                return (-1);
 
480
        (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
 
481
        el->el_chared.c_kill.mark       = el->el_line.buffer;
 
482
        el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
 
483
 
 
484
        el->el_map.current              = el->el_map.key;
 
485
 
 
486
        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
 
487
        el->el_state.doingarg           = 0;
 
488
        el->el_state.metanext           = 0;
 
489
        el->el_state.argument           = 1;
 
490
        el->el_state.lastcmd            = ED_UNASSIGNED;
 
491
 
 
492
        ma->level       = -1;
 
493
        ma->offset      = 0;
 
494
        ma->macro       = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
 
495
        if (ma->macro == NULL)
 
496
                return (-1);
 
497
        return (0);
 
498
}
 
499
 
 
500
/* ch_reset():
 
501
 *      Reset the character editor
 
502
 */
 
503
protected void
 
504
ch_reset(EditLine *el, int mclear)
 
505
{
 
506
        el->el_line.cursor              = el->el_line.buffer;
 
507
        el->el_line.lastchar            = el->el_line.buffer;
 
508
 
 
509
        el->el_chared.c_undo.len        = -1;
 
510
        el->el_chared.c_undo.cursor     = 0;
 
511
 
 
512
        el->el_chared.c_vcmd.action     = NOP;
 
513
        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
 
514
 
 
515
        el->el_chared.c_kill.mark       = el->el_line.buffer;
 
516
 
 
517
        el->el_map.current              = el->el_map.key;
 
518
 
 
519
        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
 
520
        el->el_state.doingarg           = 0;
 
521
        el->el_state.metanext           = 0;
 
522
        el->el_state.argument           = 1;
 
523
        el->el_state.lastcmd            = ED_UNASSIGNED;
 
524
 
 
525
        el->el_history.eventno          = 0;
 
526
 
 
527
        if (mclear)
 
528
                ch__clearmacro(el);
 
529
}
 
530
 
 
531
private void
 
532
ch__clearmacro(el)
 
533
        EditLine *el;
 
534
{
 
535
        c_macro_t *ma = &el->el_chared.c_macro;
 
536
        while (ma->level >= 0)
 
537
                el_free((ptr_t)ma->macro[ma->level--]);
 
538
}
 
539
 
 
540
/* ch_enlargebufs():
 
541
 *      Enlarge line buffer to be able to hold twice as much characters.
 
542
 *      Returns 1 if successful, 0 if not.
 
543
 */
 
544
protected int
 
545
ch_enlargebufs(el, addlen)
 
546
        EditLine *el;
 
547
        size_t addlen;
 
548
{
 
549
        size_t sz, newsz;
 
550
        char *newbuffer, *oldbuf, *oldkbuf;
 
551
 
 
552
        sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
 
553
        newsz = sz * 2;
 
554
        /*
 
555
         * If newly required length is longer than current buffer, we need
 
556
         * to make the buffer big enough to hold both old and new stuff.
 
557
         */
 
558
        if (addlen > sz) {
 
559
                while(newsz - sz < addlen)
 
560
                        newsz *= 2;
 
561
        }
 
562
 
 
563
        /*
 
564
         * Reallocate line buffer.
 
565
         */
 
566
        newbuffer = el_realloc(el->el_line.buffer, newsz);
 
567
        if (!newbuffer)
 
568
                return 0;
 
569
 
 
570
        /* zero the newly added memory, leave old data in */
 
571
        (void) memset(&newbuffer[sz], 0, newsz - sz);
 
572
            
 
573
        oldbuf = el->el_line.buffer;
 
574
 
 
575
        el->el_line.buffer = newbuffer;
 
576
        el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
 
577
        el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
 
578
        /* don't set new size until all buffers are enlarged */
 
579
        el->el_line.limit  = &newbuffer[sz - EL_LEAVE];
 
580
 
 
581
        /*
 
582
         * Reallocate kill buffer.
 
583
         */
 
584
        newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
 
585
        if (!newbuffer)
 
586
                return 0;
 
587
 
 
588
        /* zero the newly added memory, leave old data in */
 
589
        (void) memset(&newbuffer[sz], 0, newsz - sz);
 
590
 
 
591
        oldkbuf = el->el_chared.c_kill.buf;
 
592
 
 
593
        el->el_chared.c_kill.buf = newbuffer;
 
594
        el->el_chared.c_kill.last = newbuffer +
 
595
                                        (el->el_chared.c_kill.last - oldkbuf);
 
596
        el->el_chared.c_kill.mark = el->el_line.buffer +
 
597
                                        (el->el_chared.c_kill.mark - oldbuf);
 
598
 
 
599
        /*
 
600
         * Reallocate undo buffer.
 
601
         */
 
602
        newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
 
603
        if (!newbuffer)
 
604
                return 0;
 
605
 
 
606
        /* zero the newly added memory, leave old data in */
 
607
        (void) memset(&newbuffer[sz], 0, newsz - sz);
 
608
        el->el_chared.c_undo.buf = newbuffer;
 
609
 
 
610
        newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
 
611
        if (!newbuffer)
 
612
                return 0;
 
613
        el->el_chared.c_redo.pos = newbuffer +
 
614
                        (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
 
615
        el->el_chared.c_redo.lim = newbuffer +
 
616
                        (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
 
617
        el->el_chared.c_redo.buf = newbuffer;
 
618
        
 
619
        if (!hist_enlargebuf(el, sz, newsz))
 
620
                return 0;
 
621
 
 
622
        /* Safe to set enlarged buffer size */
 
623
        el->el_line.limit  = &el->el_line.buffer[newsz - EL_LEAVE];
 
624
        return 1;
 
625
}
 
626
 
 
627
/* ch_end():
 
628
 *      Free the data structures used by the editor
 
629
 */
 
630
protected void
 
631
ch_end(EditLine *el)
 
632
{
 
633
        el_free((ptr_t) el->el_line.buffer);
 
634
        el->el_line.buffer = NULL;
 
635
        el->el_line.limit = NULL;
 
636
        el_free((ptr_t) el->el_chared.c_undo.buf);
 
637
        el->el_chared.c_undo.buf = NULL;
 
638
        el_free((ptr_t) el->el_chared.c_redo.buf);
 
639
        el->el_chared.c_redo.buf = NULL;
 
640
        el->el_chared.c_redo.pos = NULL;
 
641
        el->el_chared.c_redo.lim = NULL;
 
642
        el->el_chared.c_redo.cmd = ED_UNASSIGNED;
 
643
        el_free((ptr_t) el->el_chared.c_kill.buf);
 
644
        el->el_chared.c_kill.buf = NULL;
 
645
        ch_reset(el, 1);
 
646
        el_free((ptr_t) el->el_chared.c_macro.macro);
 
647
        el->el_chared.c_macro.macro = NULL;
 
648
}
 
649
 
 
650
 
 
651
/* el_insertstr():
 
652
 *      Insert string at cursorI
 
653
 */
 
654
public int
 
655
el_insertstr(EditLine *el, const char *s)
 
656
{
 
657
        size_t len;
 
658
 
 
659
        if ((len = strlen(s)) == 0)
 
660
                return (-1);
 
661
        if (el->el_line.lastchar + len >= el->el_line.limit) {
 
662
                if (!ch_enlargebufs(el, len))
 
663
                        return (-1);
 
664
        }
 
665
 
 
666
        c_insert(el, (int)len);
 
667
        while (*s)
 
668
                *el->el_line.cursor++ = *s++;
 
669
        return (0);
 
670
}
 
671
 
 
672
 
 
673
/* el_deletestr():
 
674
 *      Delete num characters before the cursor
 
675
 */
 
676
public void
 
677
el_deletestr(EditLine *el, int n)
 
678
{
 
679
        if (n <= 0)
 
680
                return;
 
681
 
 
682
        if (el->el_line.cursor < &el->el_line.buffer[n])
 
683
                return;
 
684
 
 
685
        c_delbefore(el, n);             /* delete before dot */
 
686
        el->el_line.cursor -= n;
 
687
        if (el->el_line.cursor < el->el_line.buffer)
 
688
                el->el_line.cursor = el->el_line.buffer;
 
689
}
 
690
 
 
691
/* c_gets():
 
692
 *      Get a string
 
693
 */
 
694
protected int
 
695
c_gets(EditLine *el, char *buf, const char *prompt)
 
696
{
 
697
        char ch;
 
698
        int len;
 
699
        char *cp = el->el_line.buffer;
 
700
 
 
701
        if (prompt) {
 
702
                len = strlen(prompt);
 
703
                memcpy(cp, prompt, len + 0u);
 
704
                cp += len;
 
705
        }
 
706
        len = 0;
 
707
 
 
708
        for (;;) {
 
709
                el->el_line.cursor = cp;
 
710
                *cp = ' ';
 
711
                el->el_line.lastchar = cp + 1;
 
712
                re_refresh(el);
 
713
 
 
714
                if (el_getc(el, &ch) != 1) {
 
715
                        ed_end_of_file(el, 0);
 
716
                        len = -1;
 
717
                        break;
 
718
                }
 
719
 
 
720
                switch (ch) {
 
721
 
 
722
                case 0010:      /* Delete and backspace */
 
723
                case 0177:
 
724
                        if (len <= 0) {
 
725
                                len = -1;
 
726
                                break;
 
727
                        }
 
728
                        cp--;
 
729
                        continue;
 
730
 
 
731
                case 0033:      /* ESC */
 
732
                case '\r':      /* Newline */
 
733
                case '\n':
 
734
                        buf[len] = ch;
 
735
                        break;
 
736
 
 
737
                default:
 
738
                        if (len >= EL_BUFSIZ - 16)
 
739
                                term_beep(el);
 
740
                        else {
 
741
                                buf[len++] = ch;
 
742
                                *cp++ = ch;
 
743
                        }
 
744
                        continue;
 
745
                }
 
746
                break;
 
747
        }
 
748
 
 
749
        el->el_line.buffer[0] = '\0';
 
750
        el->el_line.lastchar = el->el_line.buffer;
 
751
        el->el_line.cursor = el->el_line.buffer;
 
752
        return len;
 
753
}
 
754
 
 
755
 
 
756
/* c_hpos():
 
757
 *      Return the current horizontal position of the cursor
 
758
 */
 
759
protected int
 
760
c_hpos(EditLine *el)
 
761
{
 
762
        char *ptr;
 
763
 
 
764
        /*
 
765
         * Find how many characters till the beginning of this line.
 
766
         */
 
767
        if (el->el_line.cursor == el->el_line.buffer)
 
768
                return (0);
 
769
        else {
 
770
                for (ptr = el->el_line.cursor - 1;
 
771
                     ptr >= el->el_line.buffer && *ptr != '\n';
 
772
                     ptr--)
 
773
                        continue;
 
774
                return (el->el_line.cursor - ptr - 1);
 
775
        }
 
776
}