home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d902 / less.lha / Less / Source / source.lha / prim.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  23KB  |  894 lines

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