Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / miscellany / less-177 / brac.c
1 /*
2  * Routines to perform bracket matching functions.
3  */
4
5 #include "less.h"
6 #include "position.h"
7
8 /*
9  * Try to match the n-th open bracket 
10  *  which appears in the top displayed line (forwdir),
11  * or the n-th close bracket 
12  *  which appears in the bottom displayed line (!forwdir).
13  * The characters which serve as "open bracket" and 
14  * "close bracket" are given.
15  */
16         public void
17 match_brac(obrac, cbrac, forwdir, n)
18         register int obrac;
19         register int cbrac;
20         int forwdir;
21         int n;
22 {
23         register int c;
24         register int nest;
25         POSITION pos;
26         int (*chget)();
27
28         extern int ch_forw_get(), ch_back_get();
29
30         /*
31          * Seek to the line containing the open bracket.
32          * This is either the top or bottom line on the screen,
33          * depending on the type of bracket.
34          */
35         pos = position((forwdir) ? TOP : BOTTOM);
36         if (pos == NULL_POSITION || ch_seek(pos))
37         {
38                 if (forwdir)
39                         error("Nothing in top line", NULL_PARG);
40                 else
41                         error("Nothing in bottom line", NULL_PARG);
42                 return;
43         }
44
45         /*
46          * Look thru the line to find the open bracket to match.
47          */
48         do
49         {
50                 if ((c = ch_forw_get()) == '\n' || c == EOI)
51                 {
52                         if (forwdir)
53                                 error("No bracket in top line", NULL_PARG);
54                         else
55                                 error("No bracket in bottom line", NULL_PARG);
56                         return;
57                 }
58         } while (c != obrac || --n > 0);
59
60         /*
61          * Position the file just "after" the open bracket
62          * (in the direction in which we will be searching).
63          * If searching forward, we are already after the bracket.
64          * If searching backward, skip back over the open bracket.
65          */
66         if (!forwdir)
67                 (void) ch_back_get();
68
69         /*
70          * Search the file for the matching bracket.
71          */
72         chget = (forwdir) ? ch_forw_get : ch_back_get;
73         nest = 0;
74         while ((c = (*chget)()) != EOI)
75         {
76                 if (c == obrac)
77                         nest++;
78                 else if (c == cbrac && --nest < 0)
79                 {
80                         /*
81                          * Found the matching bracket.
82                          * If searching backward, put it on the top line.
83                          * If searching forward, put it on the bottom line.
84                          */
85                         jump_line_loc(ch_tell(), forwdir ? -1 : 1);
86                         return;
87                 }
88         }
89         error("No matching bracket", NULL_PARG);
90 }