~ubuntu-branches/ubuntu/maverick/mysql-5.1/maverick-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 14:16:05 UTC
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: package-import@ubuntu.com-20120222141605-nxlu9yzc6attylc2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*      $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $     */
 
1
/*      $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $     */
2
2
 
3
3
/*-
4
4
 * Copyright (c) 1992, 1993
65
65
search_init(EditLine *el)
66
66
{
67
67
 
68
 
        el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
 
68
        el->el_search.patbuf = el_malloc(EL_BUFSIZ *
 
69
            sizeof(*el->el_search.patbuf));
69
70
        if (el->el_search.patbuf == NULL)
70
 
                return (-1);
 
71
                return -1;
71
72
        el->el_search.patlen = 0;
72
73
        el->el_search.patdir = -1;
73
74
        el->el_search.chacha = '\0';
74
75
        el->el_search.chadir = CHAR_FWD;
75
76
        el->el_search.chatflg = 0;
76
 
        return (0);
 
77
        return 0;
77
78
}
78
79
 
79
80
 
84
85
search_end(EditLine *el)
85
86
{
86
87
 
87
 
        el_free((ptr_t) el->el_search.patbuf);
 
88
        el_free(el->el_search.patbuf);
88
89
        el->el_search.patbuf = NULL;
89
90
}
90
91
 
105
106
 *      Return if string matches pattern
106
107
 */
107
108
protected int
108
 
el_match(const char *str, const char *pat)
 
109
el_match(const Char *str, const Char *pat)
109
110
{
 
111
#ifdef WIDECHAR
 
112
        static ct_buffer_t conv;
 
113
#endif
110
114
#if defined (REGEX)
111
115
        regex_t re;
112
116
        int rv;
118
122
        extern int       re_exec(const char *);
119
123
#endif
120
124
 
121
 
        if (strstr(str, pat) != NULL)
122
 
                return (1);
 
125
        if (Strstr(str, pat) != 0)
 
126
                return 1;
123
127
 
124
128
#if defined(REGEX)
125
 
        if (regcomp(&re, pat, 0) == 0) {
126
 
                rv = regexec(&re, str, 0, NULL, 0) == 0;
 
129
        if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
 
130
                rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
 
131
                    0) == 0;
127
132
                regfree(&re);
128
133
        } else {
129
134
                rv = 0;
130
135
        }
131
 
        return (rv);
 
136
        return rv;
132
137
#elif defined(REGEXP)
133
 
        if ((re = regcomp(pat)) != NULL) {
134
 
                rv = regexec(re, str);
135
 
                free((ptr_t) re);
 
138
        if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
 
139
                rv = regexec(re, ct_encode_string(str, &conv));
 
140
                el_free(re);
136
141
        } else {
137
142
                rv = 0;
138
143
        }
139
 
        return (rv);
 
144
        return rv;
140
145
#else
141
 
        if (re_comp(pat) != NULL)
142
 
                return (0);
 
146
        if (re_comp(ct_encode_string(pat, &conv)) != NULL)
 
147
                return 0;
143
148
        else
144
 
                return (re_exec(str) == 1);
 
149
                return re_exec(ct_encode_string(str, &conv) == 1);
145
150
#endif
146
151
}
147
152
 
150
155
 *       return True if the pattern matches the prefix
151
156
 */
152
157
protected int
153
 
c_hmatch(EditLine *el, const char *str)
 
158
c_hmatch(EditLine *el, const Char *str)
154
159
{
155
160
#ifdef SDEBUG
156
161
        (void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
157
162
            el->el_search.patbuf, str);
158
163
#endif /* SDEBUG */
159
164
 
160
 
        return (el_match(str, el->el_search.patbuf));
 
165
        return el_match(str, el->el_search.patbuf);
161
166
}
162
167
 
163
168
 
169
174
{
170
175
        if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
171
176
            el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
172
 
                el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
 
177
                el->el_search.patlen =
 
178
                    (size_t)(EL_CURSOR(el) - el->el_line.buffer);
173
179
                if (el->el_search.patlen >= EL_BUFSIZ)
174
180
                        el->el_search.patlen = EL_BUFSIZ - 1;
175
181
                if (el->el_search.patlen != 0) {
176
 
                        (void) strncpy(el->el_search.patbuf, el->el_line.buffer,
 
182
                        (void) Strncpy(el->el_search.patbuf, el->el_line.buffer,
177
183
                            el->el_search.patlen);
178
184
                        el->el_search.patbuf[el->el_search.patlen] = '\0';
179
185
                } else
180
 
                        el->el_search.patlen = strlen(el->el_search.patbuf);
 
186
                        el->el_search.patlen = Strlen(el->el_search.patbuf);
181
187
        }
182
188
#ifdef SDEBUG
183
189
        (void) fprintf(el->el_errfile, "\neventno = %d\n",
198
204
protected el_action_t
199
205
ce_inc_search(EditLine *el, int dir)
200
206
{
201
 
        static const char STRfwd[] = {'f', 'w', 'd', '\0'},
 
207
        static const Char STRfwd[] = {'f', 'w', 'd', '\0'},
202
208
             STRbck[] = {'b', 'c', 'k', '\0'};
203
 
        static char pchar = ':';/* ':' = normal, '?' = failed */
204
 
        static char endcmd[2] = {'\0', '\0'};
205
 
        char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
206
 
        const char *cp;
 
209
        static Char pchar = ':';/* ':' = normal, '?' = failed */
 
210
        static Char endcmd[2] = {'\0', '\0'};
 
211
        Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
 
212
        const Char *cp;
207
213
 
208
214
        el_action_t ret = CC_NORM;
209
215
 
210
216
        int ohisteventno = el->el_history.eventno;
211
 
        int oldpatlen = el->el_search.patlen;
 
217
        size_t oldpatlen = el->el_search.patlen;
212
218
        int newdir = dir;
213
219
        int done, redo;
214
220
 
215
 
        if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
 
221
        if (el->el_line.lastchar + sizeof(STRfwd) /
 
222
            sizeof(*el->el_line.lastchar) + 2 +
216
223
            el->el_search.patlen >= el->el_line.limit)
217
 
                return (CC_ERROR);
 
224
                return CC_ERROR;
218
225
 
219
226
        for (;;) {
220
227
 
241
248
                *el->el_line.lastchar = '\0';
242
249
                re_refresh(el);
243
250
 
244
 
                if (el_getc(el, &ch) != 1)
245
 
                        return (ed_end_of_file(el, 0));
 
251
                if (FUN(el,getc)(el, &ch) != 1)
 
252
                        return ed_end_of_file(el, 0);
246
253
 
247
254
                switch (el->el_map.current[(unsigned char) ch]) {
248
255
                case ED_INSERT:
249
256
                case ED_DIGIT:
250
257
                        if (el->el_search.patlen >= EL_BUFSIZ - LEN)
251
 
                                term_beep(el);
 
258
                                terminal_beep(el);
252
259
                        else {
253
260
                                el->el_search.patbuf[el->el_search.patlen++] =
254
261
                                    ch;
273
280
                        if (el->el_search.patlen > LEN)
274
281
                                done++;
275
282
                        else
276
 
                                term_beep(el);
 
283
                                terminal_beep(el);
277
284
                        break;
278
285
 
279
286
                default:
297
304
                                            *el->el_line.cursor != '\n') {
298
305
                                                if (el->el_search.patlen >=
299
306
                                                    EL_BUFSIZ - LEN) {
300
 
                                                        term_beep(el);
 
307
                                                        terminal_beep(el);
301
308
                                                        break;
302
309
                                                }
303
310
                                                el->el_search.patbuf[el->el_search.patlen++] =
310
317
                                        re_refresh(el);
311
318
                                        break;
312
319
                                    } else if (isglob(*cp)) {
313
 
                                            term_beep(el);
 
320
                                            terminal_beep(el);
314
321
                                            break;
315
322
                                    }
316
323
                                break;
317
324
 
318
325
                        default:        /* Terminate and execute cmd */
319
326
                                endcmd[0] = ch;
320
 
                                el_push(el, endcmd);
 
327
                                FUN(el,push)(el, endcmd);
321
328
                                /* FALLTHROUGH */
322
329
 
323
330
                        case 0033:      /* ESC: Terminate */
379
386
                                        /* avoid c_setpat */
380
387
                                        el->el_state.lastcmd =
381
388
                                            (el_action_t) newdir;
382
 
                                        ret = newdir == ED_SEARCH_PREV_HISTORY ?
 
389
                                        ret = (el_action_t)
 
390
                                            (newdir == ED_SEARCH_PREV_HISTORY ?
383
391
                                            ed_search_prev_history(el, 0) :
384
 
                                            ed_search_next_history(el, 0);
 
392
                                            ed_search_next_history(el, 0));
385
393
                                        if (ret != CC_ERROR) {
386
394
                                                el->el_line.cursor = newdir ==
387
395
                                                    ED_SEARCH_PREV_HISTORY ?
395
403
                                el->el_search.patbuf[el->el_search.patlen] =
396
404
                                    '\0';
397
405
                                if (ret == CC_ERROR) {
398
 
                                        term_beep(el);
 
406
                                        terminal_beep(el);
399
407
                                        if (el->el_history.eventno !=
400
408
                                            ohisteventno) {
401
409
                                                el->el_history.eventno =
402
410
                                                    ohisteventno;
403
411
                                                if (hist_get(el) == CC_ERROR)
404
 
                                                        return (CC_ERROR);
 
412
                                                        return CC_ERROR;
405
413
                                        }
406
414
                                        el->el_line.cursor = ocursor;
407
415
                                        pchar = '?';
426
434
                        if (el->el_history.eventno != ohisteventno) {
427
435
                                el->el_history.eventno = ohisteventno;
428
436
                                if (hist_get(el) == CC_ERROR)
429
 
                                        return (CC_ERROR);
 
437
                                        return CC_ERROR;
430
438
                        }
431
439
                        el->el_line.cursor = ocursor;
432
440
                        if (ret == CC_ERROR)
433
441
                                re_refresh(el);
434
442
                }
435
443
                if (done || ret != CC_NORM)
436
 
                        return (ret);
 
444
                        return ret;
437
445
        }
438
446
}
439
447
 
444
452
protected el_action_t
445
453
cv_search(EditLine *el, int dir)
446
454
{
447
 
        char ch;
448
 
        char tmpbuf[EL_BUFSIZ];
449
 
        int tmplen;
 
455
        Char ch;
 
456
        Char tmpbuf[EL_BUFSIZ];
 
457
        ssize_t tmplen;
450
458
 
451
459
#ifdef ANCHOR
452
460
        tmpbuf[0] = '.';
457
465
        el->el_search.patdir = dir;
458
466
 
459
467
        tmplen = c_gets(el, &tmpbuf[LEN],
460
 
                dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
 
468
                dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
461
469
        if (tmplen == -1)
462
470
                return CC_REFRESH;
463
471
 
471
479
                 */
472
480
                if (el->el_search.patlen == 0) {
473
481
                        re_refresh(el);
474
 
                        return (CC_ERROR);
 
482
                        return CC_ERROR;
475
483
                }
476
484
#ifdef ANCHOR
477
485
                if (el->el_search.patbuf[0] != '.' &&
478
486
                    el->el_search.patbuf[0] != '*') {
479
 
                        (void) strncpy(tmpbuf, el->el_search.patbuf,
480
 
                            sizeof(tmpbuf) - 1);
 
487
                        (void) Strncpy(tmpbuf, el->el_search.patbuf,
 
488
                            sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
481
489
                        el->el_search.patbuf[0] = '.';
482
490
                        el->el_search.patbuf[1] = '*';
483
 
                        (void) strncpy(&el->el_search.patbuf[2], tmpbuf,
 
491
                        (void) Strncpy(&el->el_search.patbuf[2], tmpbuf,
484
492
                            EL_BUFSIZ - 3);
485
493
                        el->el_search.patlen++;
486
494
                        el->el_search.patbuf[el->el_search.patlen++] = '.';
494
502
                tmpbuf[tmplen++] = '*';
495
503
#endif
496
504
                tmpbuf[tmplen] = '\0';
497
 
                (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
498
 
                el->el_search.patlen = tmplen;
 
505
                (void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
 
506
                el->el_search.patlen = (size_t)tmplen;
499
507
        }
500
508
        el->el_state.lastcmd = (el_action_t) dir;       /* avoid c_setpat */
501
509
        el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
502
510
        if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
503
511
            ed_search_next_history(el, 0)) == CC_ERROR) {
504
512
                re_refresh(el);
505
 
                return (CC_ERROR);
 
513
                return CC_ERROR;
506
514
        }
507
515
        if (ch == 0033) {
508
516
                re_refresh(el);
509
517
                return ed_newline(el, 0);
510
518
        }
511
 
        return (CC_REFRESH);
 
519
        return CC_REFRESH;
512
520
}
513
521
 
514
522
 
518
526
protected el_action_t
519
527
ce_search_line(EditLine *el, int dir)
520
528
{
521
 
        char *cp = el->el_line.cursor;
522
 
        char *pattern = el->el_search.patbuf;
523
 
        char oc, *ocp;
 
529
        Char *cp = el->el_line.cursor;
 
530
        Char *pattern = el->el_search.patbuf;
 
531
        Char oc, *ocp;
524
532
#ifdef ANCHOR
525
533
        ocp = &pattern[1];
526
534
        oc = *ocp;
535
543
                        if (el_match(cp, ocp)) {
536
544
                                *ocp = oc;
537
545
                                el->el_line.cursor = cp;
538
 
                                return (CC_NORM);
 
546
                                return CC_NORM;
539
547
                        }
540
548
                }
541
549
                *ocp = oc;
542
 
                return (CC_ERROR);
 
550
                return CC_ERROR;
543
551
        } else {
544
552
                for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
545
553
                        if (el_match(cp, ocp)) {
546
554
                                *ocp = oc;
547
555
                                el->el_line.cursor = cp;
548
 
                                return (CC_NORM);
 
556
                                return CC_NORM;
549
557
                        }
550
558
                }
551
559
                *ocp = oc;
552
 
                return (CC_ERROR);
 
560
                return CC_ERROR;
553
561
        }
554
562
}
555
563
 
558
566
 *      Vi repeat search
559
567
 */
560
568
protected el_action_t
561
 
cv_repeat_srch(EditLine *el, int c)
 
569
cv_repeat_srch(EditLine *el, Int c)
562
570
{
563
571
 
564
572
#ifdef SDEBUG
565
573
        (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
566
 
            c, el->el_search.patlen, el->el_search.patbuf);
 
574
            c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf));
567
575
#endif
568
576
 
569
577
        el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
571
579
 
572
580
        switch (c) {
573
581
        case ED_SEARCH_NEXT_HISTORY:
574
 
                return (ed_search_next_history(el, 0));
 
582
                return ed_search_next_history(el, 0);
575
583
        case ED_SEARCH_PREV_HISTORY:
576
 
                return (ed_search_prev_history(el, 0));
 
584
                return ed_search_prev_history(el, 0);
577
585
        default:
578
 
                return (CC_ERROR);
 
586
                return CC_ERROR;
579
587
        }
580
588
}
581
589
 
584
592
 *      Vi character search
585
593
 */
586
594
protected el_action_t
587
 
cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
 
595
cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag)
588
596
{
589
 
        char *cp;
 
597
        Char *cp;
590
598
 
591
599
        if (ch == 0)
592
600
                return CC_ERROR;
593
601
 
594
 
        if (ch == -1) {
595
 
                char c;
596
 
                if (el_getc(el, &c) != 1)
 
602
        if (ch == (Int)-1) {
 
603
                Char c;
 
604
                if (FUN(el,getc)(el, &c) != 1)
597
605
                        return ed_end_of_file(el, 0);
598
606
                ch = c;
599
607
        }
601
609
        /* Save for ';' and ',' commands */
602
610
        el->el_search.chacha = ch;
603
611
        el->el_search.chadir = direction;
604
 
        el->el_search.chatflg = tflag;
 
612
        el->el_search.chatflg = (char)tflag;
605
613
 
606
614
        cp = el->el_line.cursor;
607
615
        while (count--) {
608
 
                if (*cp == ch)
 
616
                if ((Int)*cp == ch)
609
617
                        cp += direction;
610
618
                for (;;cp += direction) {
611
619
                        if (cp >= el->el_line.lastchar)
612
620
                                return CC_ERROR;
613
621
                        if (cp < el->el_line.buffer)
614
622
                                return CC_ERROR;
615
 
                        if (*cp == ch)
 
623
                        if ((Int)*cp == ch)
616
624
                                break;
617
625
                }
618
626
        }