BSD 4_4 release
[unix-history] / usr / src / usr.bin / more / prim.c
CommitLineData
bfe13c81
KB
1/*
2 * Copyright (c) 1988 Mark Nudleman
ad787160
C
3 * Copyright (c) 1988, 1993
4 * The Regents of the University of California. All rights reserved.
bfe13c81 5 *
ad787160
C
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. 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.
bfe13c81
KB
33 */
34
35#ifndef lint
ad787160 36static char sccsid[] = "@(#)prim.c 8.1 (Berkeley) 6/6/93";
bfe13c81
KB
37#endif /* not lint */
38
39/*
40 * Primitives for displaying the file on the screen.
41 */
42
966c6ec0
KB
43#include <sys/types.h>
44#include <stdio.h>
45#include <ctype.h>
46#include <less.h>
bfe13c81 47
966c6ec0
KB
48int back_scroll = -1;
49int hit_eof; /* keeps track of how many times we hit end of file */
50int screen_trashed;
bfe13c81
KB
51
52static int squished;
53
bfe13c81 54extern int sigs;
bfe13c81 55extern int top_scroll;
bfe13c81 56extern int sc_width, sc_height;
bfe13c81
KB
57extern int caseless;
58extern int linenums;
bfe13c81 59extern int tagoption;
966c6ec0 60extern char *line;
441de7b4 61extern int retain_below;
bfe13c81 62
966c6ec0
KB
63off_t position(), forw_line(), back_line(), forw_raw_line(), back_raw_line();
64off_t ch_length(), ch_tell();
bfe13c81
KB
65
66/*
67 * Check to see if the end of file is currently "displayed".
68 */
bfe13c81
KB
69eof_check()
70{
966c6ec0 71 off_t pos;
bfe13c81
KB
72
73 if (sigs)
74 return;
75 /*
76 * If the bottom line is empty, we are at EOF.
77 * If the bottom line ends at the file length,
78 * we must be just at EOF.
79 */
80 pos = position(BOTTOM_PLUS_ONE);
81 if (pos == NULL_POSITION || pos == ch_length())
82 hit_eof++;
83}
84
85/*
86 * If the screen is "squished", repaint it.
87 * "Squished" means the first displayed line is not at the top
88 * of the screen; this can happen when we display a short file
89 * for the first time.
90 */
bfe13c81
KB
91squish_check()
92{
966c6ec0
KB
93 if (squished) {
94 squished = 0;
95 repaint();
96 }
bfe13c81
KB
97}
98
99/*
966c6ec0 100 * Display n lines, scrolling forward, starting at position pos in the
4a7551ea
KB
101 * input file. "only_last" means display only the last screenful if
102 * n > screen size.
bfe13c81 103 */
4a7551ea 104forw(n, pos, only_last)
bfe13c81 105 register int n;
966c6ec0 106 off_t pos;
bfe13c81
KB
107 int only_last;
108{
4a7551ea 109 extern int short_file;
bfe13c81 110 static int first_time = 1;
966c6ec0 111 int eof = 0, do_repaint;
bfe13c81
KB
112
113 squish_check();
114
115 /*
116 * do_repaint tells us not to display anything till the end,
117 * then just repaint the entire screen.
118 */
119 do_repaint = (only_last && n > sc_height-1);
120
966c6ec0
KB
121 if (!do_repaint) {
122 if (top_scroll && n >= sc_height - 1) {
bfe13c81
KB
123 /*
124 * Start a new screen.
125 * {{ This is not really desirable if we happen
126 * to hit eof in the middle of this screen,
127 * but we don't yet know if that will happen. }}
128 */
966c6ec0 129 clear();
bfe13c81 130 home();
966c6ec0 131 } else {
bfe13c81
KB
132 lower_left();
133 clear_eol();
134 }
135
966c6ec0
KB
136 /*
137 * This is not contiguous with what is currently displayed.
138 * Clear the screen image (position table) and start a new
139 * screen.
140 */
141 if (pos != position(BOTTOM_PLUS_ONE)) {
bfe13c81
KB
142 pos_clear();
143 add_forw_pos(pos);
966c6ec0
KB
144 if (top_scroll) {
145 clear();
bfe13c81
KB
146 home();
147 } else if (!first_time)
bfe13c81 148 putstr("...skipping...\n");
bfe13c81
KB
149 }
150 }
151
4a7551ea 152 for (short_file = 0; --n >= 0;) {
bfe13c81
KB
153 /*
154 * Read the next line of input.
155 */
156 pos = forw_line(pos);
966c6ec0 157 if (pos == NULL_POSITION) {
bfe13c81 158 /*
4a7551ea
KB
159 * end of file; copy the table if the file was
160 * too small for an entire screen.
bfe13c81
KB
161 */
162 eof = 1;
4a7551ea
KB
163 if (position(TOP) == NULL_POSITION) {
164 copytable();
165 if (!position(TOP))
166 short_file = 1;
167 }
168 break;
bfe13c81
KB
169 }
170 /*
171 * Add the position of the next line to the position table.
172 * Display the current line on the screen.
173 */
174 add_forw_pos(pos);
bfe13c81
KB
175 if (do_repaint)
176 continue;
177 /*
966c6ec0
KB
178 * If this is the first screen displayed and we hit an early
179 * EOF (i.e. before the requested number of lines), we
180 * "squish" the display down at the bottom of the screen.
181 * But don't do this if a -t option was given; it can cause
182 * us to start the display after the beginning of the file,
bfe13c81
KB
183 * and it is not appropriate to squish in that case.
184 */
966c6ec0 185 if (first_time && line == NULL && !top_scroll && !tagoption) {
bfe13c81
KB
186 squished = 1;
187 continue;
188 }
bfe13c81
KB
189 put_line();
190 }
191
192 if (eof && !sigs)
193 hit_eof++;
194 else
195 eof_check();
966c6ec0 196 if (do_repaint)
bfe13c81
KB
197 repaint();
198 first_time = 0;
199 (void) currline(BOTTOM);
200}
201
202/*
203 * Display n lines, scrolling backward.
204 */
4a7551ea 205back(n, pos, only_last)
bfe13c81 206 register int n;
966c6ec0 207 off_t pos;
bfe13c81
KB
208 int only_last;
209{
bfe13c81
KB
210 int do_repaint;
211
212 squish_check();
213 do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
214 hit_eof = 0;
215 while (--n >= 0)
216 {
217 /*
218 * Get the previous line of input.
219 */
220 pos = back_line(pos);
221 if (pos == NULL_POSITION)
4a7551ea 222 break;
bfe13c81
KB
223 /*
224 * Add the position of the previous line to the position table.
225 * Display the line on the screen.
226 */
227 add_back_pos(pos);
bfe13c81
KB
228 if (!do_repaint)
229 {
441de7b4
EW
230 if (retain_below)
231 {
232 lower_left();
233 clear_eol();
234 }
bfe13c81
KB
235 home();
236 add_line();
237 put_line();
238 }
239 }
240
241 eof_check();
966c6ec0 242 if (do_repaint)
bfe13c81
KB
243 repaint();
244 (void) currline(BOTTOM);
245}
246
247/*
248 * Display n more lines, forward.
249 * Start just after the line currently displayed at the bottom of the screen.
250 */
bfe13c81
KB
251forward(n, only_last)
252 int n;
253 int only_last;
254{
966c6ec0 255 off_t pos;
bfe13c81 256
966c6ec0 257 if (hit_eof) {
bfe13c81 258 /*
966c6ec0
KB
259 * If we're trying to go forward from end-of-file,
260 * go on to the next file.
bfe13c81
KB
261 */
262 next_file(1);
263 return;
264 }
265
266 pos = position(BOTTOM_PLUS_ONE);
267 if (pos == NULL_POSITION)
268 {
bfe13c81
KB
269 hit_eof++;
270 return;
271 }
4a7551ea 272 forw(n, pos, only_last);
bfe13c81
KB
273}
274
275/*
276 * Display n more lines, backward.
277 * Start just before the line currently displayed at the top of the screen.
278 */
bfe13c81
KB
279backward(n, only_last)
280 int n;
281 int only_last;
282{
966c6ec0 283 off_t pos;
bfe13c81
KB
284
285 pos = position(TOP);
966c6ec0
KB
286 /*
287 * This will almost never happen, because the top line is almost
288 * never empty.
289 */
bfe13c81 290 if (pos == NULL_POSITION)
bfe13c81 291 return;
4a7551ea 292 back(n, pos, only_last);
bfe13c81
KB
293}
294
295/*
296 * Repaint the screen, starting from a specified position.
297 */
966c6ec0
KB
298prepaint(pos)
299 off_t pos;
bfe13c81
KB
300{
301 hit_eof = 0;
4a7551ea 302 forw(sc_height-1, pos, 0);
bfe13c81
KB
303 screen_trashed = 0;
304}
305
306/*
307 * Repaint the screen.
308 */
bfe13c81
KB
309repaint()
310{
311 /*
312 * Start at the line currently at the top of the screen
313 * and redisplay the screen.
314 */
315 prepaint(position(TOP));
316}
317
318/*
319 * Jump to the end of the file.
320 * It is more convenient to paint the screen backward,
321 * from the end of the file toward the beginning.
322 */
bfe13c81
KB
323jump_forw()
324{
966c6ec0 325 off_t pos;
bfe13c81
KB
326
327 if (ch_end_seek())
328 {
329 error("Cannot seek to end of file");
330 return;
331 }
332 lastmark();
333 pos = ch_tell();
334 clear();
335 pos_clear();
336 add_back_pos(pos);
4a7551ea 337 back(sc_height - 1, pos, 0);
bfe13c81
KB
338}
339
340/*
341 * Jump to line n in the file.
342 */
bfe13c81
KB
343jump_back(n)
344 register int n;
345{
966c6ec0 346 register int c, nlines;
bfe13c81
KB
347
348 /*
349 * This is done the slow way, by starting at the beginning
350 * of the file and counting newlines.
351 *
352 * {{ Now that we have line numbering (in linenum.c),
353 * we could improve on this by starting at the
354 * nearest known line rather than at the beginning. }}
355 */
966c6ec0 356 if (ch_seek((off_t)0)) {
bfe13c81
KB
357 /*
358 * Probably a pipe with beginning of file no longer buffered.
359 * If he wants to go to line 1, we do the best we can,
360 * by going to the first line which is still buffered.
361 */
362 if (n <= 1 && ch_beg_seek() == 0)
363 jump_loc(ch_tell());
364 error("Cannot get to beginning of file");
365 return;
366 }
367
368 /*
369 * Start counting lines.
370 */
371 for (nlines = 1; nlines < n; nlines++)
bfe13c81 372 while ((c = ch_forw_get()) != '\n')
966c6ec0 373 if (c == EOI) {
bfe13c81 374 char message[40];
79a08ff0 375 (void)sprintf(message, "File has only %d lines",
966c6ec0 376 nlines - 1);
bfe13c81
KB
377 error(message);
378 return;
379 }
bfe13c81
KB
380 jump_loc(ch_tell());
381}
382
383/*
384 * Jump to a specified percentage into the file.
385 * This is a poor compensation for not being able to
386 * quickly jump to a specific line number.
387 */
bfe13c81
KB
388jump_percent(percent)
389 int percent;
390{
966c6ec0 391 off_t pos, len, ch_length();
bfe13c81
KB
392 register int c;
393
394 /*
395 * Determine the position in the file
396 * (the specified percentage of the file's length).
397 */
398 if ((len = ch_length()) == NULL_POSITION)
399 {
400 error("Don't know length of file");
401 return;
402 }
403 pos = (percent * len) / 100;
404
405 /*
406 * Back up to the beginning of the line.
407 */
408 if (ch_seek(pos) == 0)
409 {
410 while ((c = ch_back_get()) != '\n' && c != EOI)
411 ;
412 if (c == '\n')
413 (void) ch_forw_get();
414 pos = ch_tell();
415 }
416 jump_loc(pos);
417}
418
419/*
420 * Jump to a specified position in the file.
421 */
bfe13c81 422jump_loc(pos)
966c6ec0 423 off_t pos;
bfe13c81
KB
424{
425 register int nline;
966c6ec0 426 off_t tpos;
bfe13c81 427
966c6ec0 428 if ((nline = onscreen(pos)) >= 0) {
bfe13c81
KB
429 /*
430 * The line is currently displayed.
431 * Just scroll there.
432 */
4a7551ea 433 forw(nline, position(BOTTOM_PLUS_ONE), 0);
bfe13c81
KB
434 return;
435 }
436
437 /*
438 * Line is not on screen.
439 * Seek to the desired location.
440 */
966c6ec0 441 if (ch_seek(pos)) {
bfe13c81
KB
442 error("Cannot seek to that position");
443 return;
444 }
445
446 /*
966c6ec0
KB
447 * See if the desired line is BEFORE the currently displayed screen.
448 * If so, then move forward far enough so the line we're on will be
449 * at the bottom of the screen, in order to be able to call back()
450 * to make the screen scroll backwards & put the line at the top of
451 * the screen.
bfe13c81
KB
452 * {{ This seems inefficient, but it's not so bad,
453 * since we can never move forward more than a
454 * screenful before we stop to redraw the screen. }}
455 */
456 tpos = position(TOP);
966c6ec0
KB
457 if (tpos != NULL_POSITION && pos < tpos) {
458 off_t npos = pos;
bfe13c81
KB
459 /*
460 * Note that we can't forw_line() past tpos here,
461 * so there should be no EOI at this stage.
462 */
463 for (nline = 0; npos < tpos && nline < sc_height - 1; nline++)
464 npos = forw_line(npos);
465
966c6ec0 466 if (npos < tpos) {
bfe13c81
KB
467 /*
468 * More than a screenful back.
469 */
470 lastmark();
471 clear();
472 pos_clear();
473 add_back_pos(npos);
474 }
475
476 /*
477 * Note that back() will repaint() if nline > back_scroll.
478 */
4a7551ea 479 back(nline, npos, 0);
bfe13c81
KB
480 return;
481 }
482 /*
483 * Remember where we were; clear and paint the screen.
484 */
966c6ec0
KB
485 lastmark();
486 prepaint(pos);
bfe13c81
KB
487}
488
489/*
490 * The table of marks.
491 * A mark is simply a position in the file.
492 */
493#define NMARKS (27) /* 26 for a-z plus one for quote */
494#define LASTMARK (NMARKS-1) /* For quote */
966c6ec0 495static off_t marks[NMARKS];
bfe13c81
KB
496
497/*
498 * Initialize the mark table to show no marks are set.
499 */
bfe13c81
KB
500init_mark()
501{
502 int i;
503
504 for (i = 0; i < NMARKS; i++)
505 marks[i] = NULL_POSITION;
506}
507
508/*
509 * See if a mark letter is valid (between a and z).
510 */
511 static int
512badmark(c)
513 int c;
514{
515 if (c < 'a' || c > 'z')
516 {
517 error("Choose a letter between 'a' and 'z'");
518 return (1);
519 }
520 return (0);
521}
522
523/*
524 * Set a mark.
525 */
bfe13c81
KB
526setmark(c)
527 int c;
528{
529 if (badmark(c))
530 return;
531 marks[c-'a'] = position(TOP);
532}
533
bfe13c81
KB
534lastmark()
535{
536 marks[LASTMARK] = position(TOP);
537}
538
539/*
540 * Go to a previously set mark.
541 */
bfe13c81
KB
542gomark(c)
543 int c;
544{
966c6ec0 545 off_t pos;
bfe13c81 546
148d5db7 547 if (c == '\'') {
bfe13c81 548 pos = marks[LASTMARK];
148d5db7
KB
549 if (pos == NULL_POSITION)
550 pos = 0;
551 }
552 else {
553 if (badmark(c))
554 return;
bfe13c81 555 pos = marks[c-'a'];
148d5db7
KB
556 if (pos == NULL_POSITION) {
557 error("mark not set");
558 return;
559 }
560 }
561 jump_loc(pos);
bfe13c81
KB
562}
563
564/*
565 * Get the backwards scroll limit.
566 * Must call this function instead of just using the value of
567 * back_scroll, because the default case depends on sc_height and
568 * top_scroll, as well as back_scroll.
569 */
bfe13c81
KB
570get_back_scroll()
571{
572 if (back_scroll >= 0)
573 return (back_scroll);
574 if (top_scroll)
575 return (sc_height - 2);
576 return (sc_height - 1);
577}
578
579/*
580 * Search for the n-th occurence of a specified pattern,
581 * either forward or backward.
582 */
bfe13c81
KB
583search(search_forward, pattern, n, wantmatch)
584 register int search_forward;
585 register char *pattern;
586 register int n;
587 int wantmatch;
588{
966c6ec0 589 off_t pos, linepos;
bfe13c81
KB
590 register char *p;
591 register char *q;
592 int linenum;
593 int linematch;
966c6ec0 594#ifdef RECOMP
bfe13c81
KB
595 char *re_comp();
596 char *errmsg;
597#else
966c6ec0 598#ifdef REGCMP
bfe13c81
KB
599 char *regcmp();
600 static char *cpattern = NULL;
601#else
602 static char lpbuf[100];
603 static char *last_pattern = NULL;
79a08ff0 604 char *strcpy();
bfe13c81
KB
605#endif
606#endif
607
966c6ec0
KB
608 /*
609 * For a caseless search, convert any uppercase in the pattern to
610 * lowercase.
611 */
bfe13c81 612 if (caseless && pattern != NULL)
966c6ec0
KB
613 for (p = pattern; *p; p++)
614 if (isupper(*p))
615 *p = tolower(*p);
616#ifdef RECOMP
bfe13c81
KB
617
618 /*
619 * (re_comp handles a null pattern internally,
620 * so there is no need to check for a null pattern here.)
621 */
622 if ((errmsg = re_comp(pattern)) != NULL)
623 {
624 error(errmsg);
966c6ec0 625 return(0);
bfe13c81
KB
626 }
627#else
966c6ec0 628#ifdef REGCMP
bfe13c81
KB
629 if (pattern == NULL || *pattern == '\0')
630 {
631 /*
632 * A null pattern means use the previous pattern.
633 * The compiled previous pattern is in cpattern, so just use it.
634 */
635 if (cpattern == NULL)
636 {
637 error("No previous regular expression");
966c6ec0 638 return(0);
bfe13c81
KB
639 }
640 } else
641 {
642 /*
643 * Otherwise compile the given pattern.
644 */
645 char *s;
646 if ((s = regcmp(pattern, 0)) == NULL)
647 {
648 error("Invalid pattern");
966c6ec0 649 return(0);
bfe13c81
KB
650 }
651 if (cpattern != NULL)
652 free(cpattern);
653 cpattern = s;
654 }
655#else
656 if (pattern == NULL || *pattern == '\0')
657 {
658 /*
659 * Null pattern means use the previous pattern.
660 */
661 if (last_pattern == NULL)
662 {
663 error("No previous regular expression");
966c6ec0 664 return(0);
bfe13c81
KB
665 }
666 pattern = last_pattern;
667 } else
668 {
79a08ff0 669 (void)strcpy(lpbuf, pattern);
bfe13c81
KB
670 last_pattern = lpbuf;
671 }
672#endif
673#endif
674
675 /*
676 * Figure out where to start the search.
677 */
678
966c6ec0 679 if (position(TOP) == NULL_POSITION) {
bfe13c81 680 /*
966c6ec0
KB
681 * Nothing is currently displayed. Start at the beginning
682 * of the file. (This case is mainly for searches from the
683 * command line.
bfe13c81 684 */
966c6ec0
KB
685 pos = (off_t)0;
686 } else if (!search_forward) {
bfe13c81
KB
687 /*
688 * Backward search: start just before the top line
689 * displayed on the screen.
690 */
691 pos = position(TOP);
966c6ec0 692 } else {
bfe13c81
KB
693 /*
694 * Start at the second screen line displayed on the screen.
695 */
696 pos = position(TOP_PLUS_ONE);
697 }
698
699 if (pos == NULL_POSITION)
700 {
701 /*
702 * Can't find anyplace to start searching from.
703 */
704 error("Nothing to search");
966c6ec0 705 return(0);
bfe13c81
KB
706 }
707
708 linenum = find_linenum(pos);
709 for (;;)
710 {
711 /*
712 * Get lines until we find a matching one or
713 * until we hit end-of-file (or beginning-of-file
714 * if we're going backwards).
715 */
716 if (sigs)
717 /*
718 * A signal aborts the search.
719 */
966c6ec0 720 return(0);
bfe13c81
KB
721
722 if (search_forward)
723 {
724 /*
725 * Read the next line, and save the
726 * starting position of that line in linepos.
727 */
728 linepos = pos;
729 pos = forw_raw_line(pos);
730 if (linenum != 0)
731 linenum++;
732 } else
733 {
734 /*
735 * Read the previous line and save the
736 * starting position of that line in linepos.
737 */
738 pos = back_raw_line(pos);
739 linepos = pos;
740 if (linenum != 0)
741 linenum--;
742 }
743
744 if (pos == NULL_POSITION)
745 {
746 /*
747 * We hit EOF/BOF without a match.
748 */
749 error("Pattern not found");
966c6ec0 750 return(0);
bfe13c81
KB
751 }
752
753 /*
754 * If we're using line numbers, we might as well
755 * remember the information we have now (the position
756 * and line number of the current line).
757 */
758 if (linenums)
759 add_lnum(linenum, pos);
760
966c6ec0
KB
761 /*
762 * If this is a caseless search, convert uppercase in the
763 * input line to lowercase.
764 */
bfe13c81 765 if (caseless)
966c6ec0
KB
766 for (p = q = line; *p; p++, q++)
767 *q = isupper(*p) ? tolower(*p) : *p;
768
769 /*
770 * Remove any backspaces along with the preceeding char.
771 * This allows us to match text which is underlined or
772 * overstruck.
773 */
774 for (p = q = line; *p; p++, q++)
775 if (q > line && *p == '\b')
776 /* Delete BS and preceeding char. */
777 q -= 2;
778 else
779 /* Otherwise, just copy. */
780 *q = *p;
bfe13c81
KB
781
782 /*
783 * Test the next line to see if we have a match.
784 * This is done in a variety of ways, depending
785 * on what pattern matching functions are available.
786 */
966c6ec0 787#ifdef REGCMP
bfe13c81
KB
788 linematch = (regex(cpattern, line) != NULL);
789#else
966c6ec0 790#ifdef RECOMP
bfe13c81
KB
791 linematch = (re_exec(line) == 1);
792#else
793 linematch = match(pattern, line);
794#endif
795#endif
796 /*
797 * We are successful if wantmatch and linematch are
798 * both true (want a match and got it),
799 * or both false (want a non-match and got it).
800 */
801 if (((wantmatch && linematch) || (!wantmatch && !linematch)) &&
802 --n <= 0)
803 /*
804 * Found the line.
805 */
806 break;
807 }
bfe13c81 808 jump_loc(linepos);
966c6ec0 809 return(1);
bfe13c81
KB
810}
811
966c6ec0 812#if !defined(REGCMP) && !defined(RECOMP)
bfe13c81
KB
813/*
814 * We have neither regcmp() nor re_comp().
815 * We use this function to do simple pattern matching.
816 * It supports no metacharacters like *, etc.
817 */
966c6ec0 818static
bfe13c81
KB
819match(pattern, buf)
820 char *pattern, *buf;
821{
822 register char *pp, *lp;
823
824 for ( ; *buf != '\0'; buf++)
825 {
826 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
827 if (*pp == '\0' || *lp == '\0')
828 break;
829 if (*pp == '\0')
830 return (1);
831 }
832 return (0);
833}
834#endif