Annotation of src/usr.bin/mg/search.c, Revision 1.3
1.1 deraadt 1: /*
2: * Search commands.
1.3 ! millert 3: * The functions in this file implement the search commands (both plain and
! 4: * incremental searches are supported) and the query-replace command.
1.1 deraadt 5: *
1.3 ! millert 6: * The plain old search code is part of the original MicroEMACS "distribution".
! 7: * The incremental search code and the query-replace code is by Rich Ellison.
1.1 deraadt 8: */
1.3 ! millert 9:
! 10: #include "def.h"
! 11:
1.1 deraadt 12: #ifndef NO_MACRO
1.3 ! millert 13: #include "macro.h"
! 14: #endif /* !NO_MACRO */
1.1 deraadt 15:
1.2 millert 16: #define SRCH_BEGIN (0) /* Search sub-codes. */
1.1 deraadt 17: #define SRCH_FORW (-1)
18: #define SRCH_BACK (-2)
19: #define SRCH_NOPR (-3)
20: #define SRCH_ACCM (-4)
21: #define SRCH_MARK (-5)
22:
1.2 millert 23: typedef struct {
1.3 ! millert 24: int s_code;
! 25: LINE *s_dotp;
! 26: int s_doto;
! 27: } SRCHCOM;
! 28:
! 29: static int isearch __P((int));
! 30: static VOID is_cpush __P((int));
! 31: static VOID is_lpush __P((void));
! 32: static VOID is_pop __P((void));
! 33: static int is_peek __P((void));
! 34: static VOID is_undo __P((int *, int *));
! 35: static int is_find __P((int));
! 36: static VOID is_prompt __P((int, int, int));
! 37: static VOID is_dspl __P((char *, int));
! 38: static int eq __P((int, int));
! 39:
! 40: static SRCHCOM cmds[NSRCH];
! 41: static int cip;
! 42:
! 43: int srch_lastdir = SRCH_NOPR; /* Last search flags. */
! 44:
! 45: /*
! 46: * Search forward. Get a search string from the user, and search for it
! 47: * starting at ".". If found, "." gets moved to just after the matched
! 48: * characters, and display does all the hard stuff. If not found, it just
! 49: * prints a message.
1.1 deraadt 50: */
1.2 millert 51: /* ARGSUSED */
1.3 ! millert 52: int
1.1 deraadt 53: forwsearch(f, n)
1.3 ! millert 54: int f, n;
1.1 deraadt 55: {
1.3 ! millert 56: int s;
1.1 deraadt 57:
1.2 millert 58: if ((s = readpattern("Search")) != TRUE)
1.1 deraadt 59: return s;
60: if (forwsrch() == FALSE) {
61: ewprintf("Search failed: \"%s\"", pat);
62: return FALSE;
63: }
64: srch_lastdir = SRCH_FORW;
65: return TRUE;
66: }
67:
68: /*
1.3 ! millert 69: * Reverse search. Get a search string from the user, and search, starting
! 70: * at "." and proceeding toward the front of the buffer. If found "." is
! 71: * left pointing at the first character of the pattern [the last character
! 72: * that was matched].
1.1 deraadt 73: */
1.2 millert 74: /* ARGSUSED */
1.3 ! millert 75: int
1.1 deraadt 76: backsearch(f, n)
1.3 ! millert 77: int f, n;
1.1 deraadt 78: {
1.3 ! millert 79: int s;
1.1 deraadt 80:
1.2 millert 81: if ((s = readpattern("Search backward")) != TRUE)
1.1 deraadt 82: return (s);
83: if (backsrch() == FALSE) {
84: ewprintf("Search failed: \"%s\"", pat);
85: return FALSE;
86: }
87: srch_lastdir = SRCH_BACK;
88: return TRUE;
89: }
90:
91: /*
1.3 ! millert 92: * Search again, using the same search string and direction as the last
! 93: * search command. The direction has been saved in "srch_lastdir", so you
! 94: * know which way to go.
1.1 deraadt 95: */
1.2 millert 96: /* ARGSUSED */
1.3 ! millert 97: int
1.1 deraadt 98: searchagain(f, n)
1.3 ! millert 99: int f, n;
1.1 deraadt 100: {
101: if (srch_lastdir == SRCH_FORW) {
102: if (forwsrch() == FALSE) {
103: ewprintf("Search failed: \"%s\"", pat);
104: return FALSE;
105: }
106: return TRUE;
107: }
108: if (srch_lastdir == SRCH_BACK) {
109: if (backsrch() == FALSE) {
110: ewprintf("Search failed: \"%s\"", pat);
111: return FALSE;
112: }
113: return TRUE;
114: }
115: ewprintf("No last search");
116: return FALSE;
117: }
118:
119: /*
1.3 ! millert 120: * Use incremental searching, initially in the forward direction.
1.1 deraadt 121: * isearch ignores any explicit arguments.
122: */
1.2 millert 123: /* ARGSUSED */
1.3 ! millert 124: int
1.1 deraadt 125: forwisearch(f, n)
1.3 ! millert 126: int f, n;
1.1 deraadt 127: {
128: return isearch(SRCH_FORW);
129: }
130:
131: /*
132: * Use incremental searching, initially in the reverse direction.
133: * isearch ignores any explicit arguments.
134: */
1.2 millert 135: /* ARGSUSED */
1.3 ! millert 136: int
1.1 deraadt 137: backisearch(f, n)
1.3 ! millert 138: int f, n;
1.1 deraadt 139: {
140: return isearch(SRCH_BACK);
141: }
142:
143: /*
144: * Incremental Search.
145: * dir is used as the initial direction to search.
146: * ^S switch direction to forward
147: * ^R switch direction to reverse
148: * ^Q quote next character (allows searching for ^N etc.)
149: * <ESC> exit from Isearch
150: * <DEL> undoes last character typed. (tricky job to do this correctly).
151: * other ^ exit search, don't set mark
152: * else accumulate into search string
153: */
1.3 ! millert 154: static int
1.2 millert 155: isearch(dir)
1.3 ! millert 156: int dir;
1.2 millert 157: {
1.3 ! millert 158: LINE *clp;
! 159:
! 160: int c;
! 161: int cbo;
! 162: int success;
! 163: int pptr;
! 164:
! 165: char opat[NPAT];
1.1 deraadt 166:
167: #ifndef NO_MACRO
1.2 millert 168: if (macrodef) {
169: ewprintf("Can't isearch in macro");
170: return FALSE;
1.1 deraadt 171: }
1.3 ! millert 172: #endif /* !NO_MACRO */
1.2 millert 173: for (cip = 0; cip < NSRCH; cip++)
1.1 deraadt 174: cmds[cip].s_code = SRCH_NOPR;
1.3 ! millert 175:
! 176: (VOID)strcpy(opat, pat);
1.1 deraadt 177: cip = 0;
178: pptr = -1;
179: clp = curwp->w_dotp;
180: cbo = curwp->w_doto;
181: is_lpush();
182: is_cpush(SRCH_BEGIN);
183: success = TRUE;
184: is_prompt(dir, TRUE, success);
1.3 ! millert 185:
1.1 deraadt 186: for (;;) {
187: update();
1.3 ! millert 188:
1.1 deraadt 189: switch (c = getkey(FALSE)) {
190: case CCHR('['):
191: srch_lastdir = dir;
192: curwp->w_markp = clp;
193: curwp->w_marko = cbo;
194: ewprintf("Mark set");
195: return (TRUE);
196: case CCHR('G'):
197: if (success != TRUE) {
198: while (is_peek() == SRCH_ACCM)
199: is_undo(&pptr, &dir);
200: success = TRUE;
201: is_prompt(dir, pptr < 0, success);
202: break;
203: }
204: curwp->w_dotp = clp;
205: curwp->w_doto = cbo;
206: curwp->w_flag |= WFMOVE;
207: srch_lastdir = dir;
1.3 ! millert 208: (VOID)ctrlg(FFRAND, 0);
! 209: (VOID)strcpy(pat, opat);
1.1 deraadt 210: return ABORT;
211: case CCHR(']'):
212: case CCHR('S'):
213: if (dir == SRCH_BACK) {
214: dir = SRCH_FORW;
215: is_lpush();
216: is_cpush(SRCH_FORW);
217: success = TRUE;
218: }
1.2 millert 219: if (success == FALSE && dir == SRCH_FORW)
1.1 deraadt 220: break;
221: is_lpush();
222: pptr = strlen(pat);
1.3 ! millert 223: (VOID)forwchar(FFRAND, 1);
1.2 millert 224: if (is_find(SRCH_FORW) != FALSE)
225: is_cpush(SRCH_MARK);
1.1 deraadt 226: else {
1.3 ! millert 227: (VOID)backchar(FFRAND, 1);
1.1 deraadt 228: ttbeep();
229: success = FALSE;
230: }
231: is_prompt(dir, pptr < 0, success);
232: break;
233: case CCHR('R'):
234: if (dir == SRCH_FORW) {
235: dir = SRCH_BACK;
236: is_lpush();
237: is_cpush(SRCH_BACK);
238: success = TRUE;
239: }
1.2 millert 240: if (success == FALSE && dir == SRCH_BACK)
1.1 deraadt 241: break;
242: is_lpush();
243: pptr = strlen(pat);
1.3 ! millert 244: (VOID)backchar(FFRAND, 1);
1.2 millert 245: if (is_find(SRCH_BACK) != FALSE)
246: is_cpush(SRCH_MARK);
1.1 deraadt 247: else {
1.3 ! millert 248: (VOID)forwchar(FFRAND, 1);
1.1 deraadt 249: ttbeep();
250: success = FALSE;
251: }
252: is_prompt(dir, pptr < 0, success);
253: break;
254: case CCHR('H'):
255: case CCHR('?'):
256: is_undo(&pptr, &dir);
1.2 millert 257: if (is_peek() != SRCH_ACCM)
258: success = TRUE;
1.1 deraadt 259: is_prompt(dir, pptr < 0, success);
260: break;
261: case CCHR('\\'):
262: case CCHR('Q'):
1.3 ! millert 263: c = (char)getkey(FALSE);
1.2 millert 264: goto addchar;
1.1 deraadt 265: case CCHR('M'):
266: c = CCHR('J');
1.2 millert 267: goto addchar;
1.1 deraadt 268: default:
269: if (ISCTRL(c)) {
270: ungetkey(c);
271: curwp->w_markp = clp;
272: curwp->w_marko = cbo;
273: ewprintf("Mark set");
274: curwp->w_flag |= WFMOVE;
1.2 millert 275: return TRUE;
1.1 deraadt 276: } /* and continue */
277: case CCHR('I'):
278: case CCHR('J'):
1.2 millert 279: addchar:
1.1 deraadt 280: if (pptr == -1)
281: pptr = 0;
282: if (pptr == 0)
283: success = TRUE;
284: pat[pptr++] = c;
285: if (pptr == NPAT) {
286: ewprintf("Pattern too long");
287: return FALSE;
288: }
289: pat[pptr] = '\0';
290: is_lpush();
291: if (success != FALSE) {
292: if (is_find(dir) != FALSE)
293: is_cpush(c);
294: else {
295: success = FALSE;
296: ttbeep();
297: is_cpush(SRCH_ACCM);
298: }
299: } else
300: is_cpush(SRCH_ACCM);
301: is_prompt(dir, FALSE, success);
302: }
303: }
1.2 millert 304: /* NOTREACHED */
1.1 deraadt 305: }
306:
1.3 ! millert 307: static VOID
1.2 millert 308: is_cpush(cmd)
1.3 ! millert 309: int cmd;
1.2 millert 310: {
1.1 deraadt 311: if (++cip >= NSRCH)
312: cip = 0;
313: cmds[cip].s_code = cmd;
314: }
315:
1.3 ! millert 316: static VOID
1.2 millert 317: is_lpush()
318: {
1.3 ! millert 319: int ctp;
1.1 deraadt 320:
1.2 millert 321: ctp = cip + 1;
1.1 deraadt 322: if (ctp >= NSRCH)
323: ctp = 0;
324: cmds[ctp].s_code = SRCH_NOPR;
325: cmds[ctp].s_doto = curwp->w_doto;
326: cmds[ctp].s_dotp = curwp->w_dotp;
327: }
328:
1.3 ! millert 329: static VOID
1.2 millert 330: is_pop()
331: {
1.1 deraadt 332: if (cmds[cip].s_code != SRCH_NOPR) {
1.2 millert 333: curwp->w_doto = cmds[cip].s_doto;
334: curwp->w_dotp = cmds[cip].s_dotp;
1.1 deraadt 335: curwp->w_flag |= WFMOVE;
336: cmds[cip].s_code = SRCH_NOPR;
337: }
338: if (--cip <= 0)
1.2 millert 339: cip = NSRCH - 1;
1.1 deraadt 340: }
341:
342: static int
1.2 millert 343: is_peek()
344: {
1.1 deraadt 345: return cmds[cip].s_code;
346: }
347:
348: /* this used to always return TRUE (the return value was checked) */
1.3 ! millert 349: static VOID
1.2 millert 350: is_undo(pptr, dir)
1.3 ! millert 351: int *pptr, *dir;
1.2 millert 352: {
1.3 ! millert 353: int redo = FALSE;
! 354:
1.1 deraadt 355: switch (cmds[cip].s_code) {
356: case SRCH_BEGIN:
357: case SRCH_NOPR:
358: *pptr = -1;
359: case SRCH_MARK:
360: break;
361: case SRCH_FORW:
362: *dir = SRCH_BACK;
363: redo = TRUE;
364: break;
365: case SRCH_BACK:
366: *dir = SRCH_FORW;
367: redo = TRUE;
368: break;
369: case SRCH_ACCM:
370: default:
371: *pptr -= 1;
372: if (*pptr < 0)
373: *pptr = 0;
374: pat[*pptr] = '\0';
375: break;
376: }
377: is_pop();
1.2 millert 378: if (redo)
379: is_undo(pptr, dir);
1.1 deraadt 380: }
381:
382: static int
1.2 millert 383: is_find(dir)
1.3 ! millert 384: int dir;
1.2 millert 385: {
1.3 ! millert 386: int plen, odoto;
! 387: LINE *odotp;
1.1 deraadt 388:
389: odoto = curwp->w_doto;
390: odotp = curwp->w_dotp;
391: plen = strlen(pat);
392: if (plen != 0) {
1.2 millert 393: if (dir == SRCH_FORW) {
1.3 ! millert 394: (VOID)backchar(FFARG | FFRAND, plen);
1.1 deraadt 395: if (forwsrch() == FALSE) {
396: curwp->w_doto = odoto;
397: curwp->w_dotp = odotp;
398: return FALSE;
399: }
400: return TRUE;
401: }
1.2 millert 402: if (dir == SRCH_BACK) {
1.3 ! millert 403: (VOID)forwchar(FFARG | FFRAND, plen);
1.1 deraadt 404: if (backsrch() == FALSE) {
405: curwp->w_doto = odoto;
406: curwp->w_dotp = odotp;
407: return FALSE;
408: }
409: return TRUE;
410: }
411: ewprintf("bad call to is_find");
412: return FALSE;
413: }
414: return FALSE;
415: }
416:
417: /*
1.3 ! millert 418: * If called with "dir" not one of SRCH_FORW or SRCH_BACK, this routine used
! 419: * to print an error message. It also used to return TRUE or FALSE, depending
! 420: * on if it liked the "dir". However, none of the callers looked at the
! 421: * status, so I just made the checking vanish.
1.1 deraadt 422: */
1.3 ! millert 423: static VOID
1.2 millert 424: is_prompt(dir, flag, success)
1.3 ! millert 425: int dir, flag, success;
1.2 millert 426: {
1.1 deraadt 427: if (dir == SRCH_FORW) {
428: if (success != FALSE)
429: is_dspl("I-search", flag);
430: else
431: is_dspl("Failing I-search", flag);
432: } else if (dir == SRCH_BACK) {
433: if (success != FALSE)
434: is_dspl("I-search backward", flag);
435: else
436: is_dspl("Failing I-search backward", flag);
1.2 millert 437: } else
438: ewprintf("Broken call to is_prompt");
1.1 deraadt 439: }
440:
441: /*
1.3 ! millert 442: * Prompt writing routine for the incremental search. The "prompt" is just
! 443: * a string. The "flag" determines whether pat should be printed.
1.1 deraadt 444: */
1.3 ! millert 445: static VOID
1.2 millert 446: is_dspl(prompt, flag)
1.3 ! millert 447: char *prompt;
! 448: int flag;
1.2 millert 449: {
1.1 deraadt 450: if (flag != FALSE)
451: ewprintf("%s: ", prompt);
452: else
453: ewprintf("%s: %s", prompt, pat);
454: }
455:
456: /*
457: * Query Replace.
458: * Replace strings selectively. Does a search and replace operation.
459: */
1.2 millert 460: /* ARGSUSED */
1.3 ! millert 461: int
1.1 deraadt 462: queryrepl(f, n)
1.3 ! millert 463: int f, n;
1.1 deraadt 464: {
1.3 ! millert 465: int s;
! 466: int rcnt = 0; /* replacements made so far */
! 467: int plen; /* length of found string */
! 468: char news[NPAT]; /* replacement string */
1.1 deraadt 469:
470: #ifndef NO_MACRO
1.2 millert 471: if (macrodef) {
472: ewprintf("Can't query replace in macro");
473: return FALSE;
1.1 deraadt 474: }
1.3 ! millert 475: #endif /* !NO_MACRO */
! 476:
1.2 millert 477: if ((s = readpattern("Query replace")) != TRUE)
1.1 deraadt 478: return (s);
1.2 millert 479: if ((s = ereply("Query replace %s with: ", news, NPAT, pat)) == ABORT)
1.1 deraadt 480: return (s);
481: if (s == FALSE)
482: news[0] = '\0';
483: ewprintf("Query replacing %s with %s:", pat, news);
484: plen = strlen(pat);
485:
486: /*
487: * Search forward repeatedly, checking each time whether to insert
488: * or not. The "!" case makes the check always true, so it gets put
489: * into a tighter loop for efficiency.
490: */
491: while (forwsrch() == TRUE) {
1.2 millert 492: retry:
1.1 deraadt 493: update();
494: switch (getkey(FALSE)) {
495: case ' ':
1.3 ! millert 496: if (lreplace((RSIZE)plen, news, f) == FALSE)
1.1 deraadt 497: return (FALSE);
498: rcnt++;
499: break;
500: case '.':
1.3 ! millert 501: if (lreplace((RSIZE)plen, news, f) == FALSE)
1.1 deraadt 502: return (FALSE);
503: rcnt++;
504: goto stopsearch;
1.3 ! millert 505: /* ^G or ESC */
! 506: case CCHR('G'):
! 507: (VOID)ctrlg(FFRAND, 0);
1.1 deraadt 508: case CCHR('['):
509: goto stopsearch;
510: case '!':
511: do {
1.3 ! millert 512: if (lreplace((RSIZE)plen, news, f) == FALSE)
1.1 deraadt 513: return (FALSE);
514: rcnt++;
515: } while (forwsrch() == TRUE);
516: goto stopsearch;
517: case CCHR('H'):
1.3 ! millert 518: /* To not replace */
! 519: case CCHR('?'):
1.1 deraadt 520: break;
521: default:
1.2 millert 522: ewprintf("<SP> replace, [.] rep-end, <DEL> don't, [!] repl rest <ESC> quit");
1.1 deraadt 523: goto retry;
524: }
525: }
526: stopsearch:
527: curwp->w_flag |= WFHARD;
528: update();
529: if (rcnt == 0)
530: ewprintf("(No replacements done)");
531: else if (rcnt == 1)
532: ewprintf("(1 replacement done)");
533: else
534: ewprintf("(%d replacements done)", rcnt);
535: return TRUE;
536: }
537:
538: /*
1.3 ! millert 539: * This routine does the real work of a forward search. The pattern is sitting
! 540: * in the external variable "pat". If found, dot is updated, the window system
! 541: * is notified of the change, and TRUE is returned. If the string isn't found,
! 542: * FALSE is returned.
1.1 deraadt 543: */
1.3 ! millert 544: int
1.2 millert 545: forwsrch()
546: {
1.3 ! millert 547: LINE *clp, *tlp;
! 548: int cbo, tbo, c;
! 549: char *pp;
1.1 deraadt 550:
551: clp = curwp->w_dotp;
552: cbo = curwp->w_doto;
1.2 millert 553: for (;;) {
1.1 deraadt 554: if (cbo == llength(clp)) {
1.2 millert 555: if ((clp = lforw(clp)) == curbp->b_linep)
556: break;
1.1 deraadt 557: cbo = 0;
558: c = CCHR('J');
559: } else
560: c = lgetc(clp, cbo++);
561: if (eq(c, pat[0]) != FALSE) {
562: tlp = clp;
563: tbo = cbo;
1.2 millert 564: pp = &pat[1];
1.1 deraadt 565: while (*pp != 0) {
566: if (tbo == llength(tlp)) {
567: tlp = lforw(tlp);
568: if (tlp == curbp->b_linep)
569: goto fail;
570: tbo = 0;
571: c = CCHR('J');
572: } else
573: c = lgetc(tlp, tbo++);
574: if (eq(c, *pp++) == FALSE)
575: goto fail;
576: }
1.2 millert 577: curwp->w_dotp = tlp;
578: curwp->w_doto = tbo;
1.1 deraadt 579: curwp->w_flag |= WFMOVE;
580: return TRUE;
581: }
1.2 millert 582: fail: ;
1.1 deraadt 583: }
584: return FALSE;
585: }
586:
587: /*
1.3 ! millert 588: * This routine does the real work of a backward search. The pattern is
! 589: * sitting in the external variable "pat". If found, dot is updated, the
! 590: * window system is notified of the change, and TRUE is returned. If the
1.1 deraadt 591: * string isn't found, FALSE is returned.
592: */
1.3 ! millert 593: int
1.2 millert 594: backsrch()
595: {
1.3 ! millert 596: LINE *clp, *tlp;
! 597: int cbo, tbo, c;
! 598: char *epp, *pp;
1.1 deraadt 599:
1.2 millert 600: for (epp = &pat[0]; epp[1] != 0; ++epp);
1.1 deraadt 601: clp = curwp->w_dotp;
602: cbo = curwp->w_doto;
603: for (;;) {
604: if (cbo == 0) {
605: clp = lback(clp);
606: if (clp == curbp->b_linep)
607: return FALSE;
1.2 millert 608: cbo = llength(clp) + 1;
1.1 deraadt 609: }
610: if (--cbo == llength(clp))
611: c = CCHR('J');
612: else
1.2 millert 613: c = lgetc(clp, cbo);
1.1 deraadt 614: if (eq(c, *epp) != FALSE) {
615: tlp = clp;
616: tbo = cbo;
1.2 millert 617: pp = epp;
1.1 deraadt 618: while (pp != &pat[0]) {
619: if (tbo == 0) {
620: tlp = lback(tlp);
621: if (tlp == curbp->b_linep)
622: goto fail;
1.2 millert 623: tbo = llength(tlp) + 1;
1.1 deraadt 624: }
625: if (--tbo == llength(tlp))
626: c = CCHR('J');
627: else
1.2 millert 628: c = lgetc(tlp, tbo);
1.1 deraadt 629: if (eq(c, *--pp) == FALSE)
630: goto fail;
631: }
1.2 millert 632: curwp->w_dotp = tlp;
633: curwp->w_doto = tbo;
1.1 deraadt 634: curwp->w_flag |= WFMOVE;
635: return TRUE;
636: }
1.2 millert 637: fail: ;
1.1 deraadt 638: }
1.2 millert 639: /* NOTREACHED */
1.1 deraadt 640: }
641:
642: /*
1.3 ! millert 643: * Compare two characters. The "bc" comes from the buffer. It has its case
! 644: * folded out. The "pc" is from the pattern.
1.1 deraadt 645: */
646: static int
647: eq(bc, pc)
1.3 ! millert 648: int bc, pc;
1.1 deraadt 649: {
650: bc = CHARMASK(bc);
651: pc = CHARMASK(pc);
1.2 millert 652: if (bc == pc)
653: return TRUE;
654: if (ISUPPER(bc))
655: return TOLOWER(bc) == pc;
656: if (ISUPPER(pc))
657: return bc == TOLOWER(pc);
1.1 deraadt 658: return FALSE;
659: }
660:
661: /*
1.3 ! millert 662: * Read a pattern. Stash it in the external variable "pat". The "pat" is not
! 663: * updated if the user types in an empty line. If the user typed an empty
! 664: * line, and there is no old pattern, it is an error. Display the old pattern,
! 665: * in the style of Jeff Lomicka. There is some do-it-yourself control
! 666: * expansion.
1.1 deraadt 667: */
1.3 ! millert 668: int
1.2 millert 669: readpattern(prompt)
1.3 ! millert 670: char *prompt;
1.2 millert 671: {
1.3 ! millert 672: int s;
! 673: char tpat[NPAT];
1.1 deraadt 674:
1.2 millert 675: if (tpat[0] == '\0')
676: s = ereply("%s: ", tpat, NPAT, prompt);
677: else
678: s = ereply("%s: (default %s) ", tpat, NPAT, prompt, pat);
1.1 deraadt 679:
1.3 ! millert 680: /* specified */
! 681: if (s == TRUE)
1.1 deraadt 682: (VOID) strcpy(pat, tpat);
1.3 ! millert 683: /* CR, but old one */
! 684: else if (s == FALSE && pat[0] != 0)
1.1 deraadt 685: s = TRUE;
686: return s;
687: }