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 } 97