]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/less/brac.c
Merge lld trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / less / brac.c
1 /*
2  * Copyright (C) 1984-2015  Mark Nudelman
3  *
4  * You may distribute under the terms of either the GNU General Public
5  * License or the Less License, as specified in the README file.
6  *
7  * For more information, see the README file.
8  */
9
10
11 /*
12  * Routines to perform bracket matching functions.
13  */
14
15 #include "less.h"
16 #include "position.h"
17
18 /*
19  * Try to match the n-th open bracket 
20  *  which appears in the top displayed line (forwdir),
21  * or the n-th close bracket 
22  *  which appears in the bottom displayed line (!forwdir).
23  * The characters which serve as "open bracket" and 
24  * "close bracket" are given.
25  */
26         public void
27 match_brac(int obrac, int cbrac, int forwdir, int n)
28 {
29         int c;
30         int nest;
31         POSITION pos;
32         int (*chget)(void);
33
34         extern int ch_forw_get(void), ch_back_get(void);
35
36         /*
37          * Seek to the line containing the open bracket.
38          * This is either the top or bottom line on the screen,
39          * depending on the type of bracket.
40          */
41         pos = position((forwdir) ? TOP : BOTTOM);
42         if (pos == NULL_POSITION || ch_seek(pos))
43         {
44                 if (forwdir)
45                         error("Nothing in top line", NULL_PARG);
46                 else
47                         error("Nothing in bottom line", NULL_PARG);
48                 return;
49         }
50
51         /*
52          * Look thru the line to find the open bracket to match.
53          */
54         do
55         {
56                 if ((c = ch_forw_get()) == '\n' || c == EOI)
57                 {
58                         if (forwdir)
59                                 error("No bracket in top line", NULL_PARG);
60                         else
61                                 error("No bracket in bottom line", NULL_PARG);
62                         return;
63                 }
64         } while (c != obrac || --n > 0);
65
66         /*
67          * Position the file just "after" the open bracket
68          * (in the direction in which we will be searching).
69          * If searching forward, we are already after the bracket.
70          * If searching backward, skip back over the open bracket.
71          */
72         if (!forwdir)
73                 (void) ch_back_get();
74
75         /*
76          * Search the file for the matching bracket.
77          */
78         chget = (forwdir) ? ch_forw_get : ch_back_get;
79         nest = 0;
80         while ((c = (*chget)()) != EOI)
81         {
82                 if (c == obrac)
83                         nest++;
84                 else if (c == cbrac && --nest < 0)
85                 {
86                         /*
87                          * Found the matching bracket.
88                          * If searching backward, put it on the top line.
89                          * If searching forward, put it on the bottom line.
90                          */
91                         jump_line_loc(ch_tell(), forwdir ? -1 : 1);
92                         return;
93                 }
94         }
95         error("No matching bracket", NULL_PARG);
96 }