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