1 /* 2 * Copyright (C) 1984-2022 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(obrac, cbrac, forwdir, n) 28 int obrac; 29 int cbrac; 30 int forwdir; 31 int n; 32 { 33 int c; 34 int nest; 35 POSITION pos; 36 int (*chget)(); 37 38 extern int ch_forw_get(), ch_back_get(); 39 40 /* 41 * Seek to the line containing the open bracket. 42 * This is either the top or bottom line on the screen, 43 * depending on the type of bracket. 44 */ 45 pos = position((forwdir) ? TOP : BOTTOM); 46 if (pos == NULL_POSITION || ch_seek(pos)) 47 { 48 if (forwdir) 49 error("Nothing in top line", NULL_PARG); 50 else 51 error("Nothing in bottom line", NULL_PARG); 52 return; 53 } 54 55 /* 56 * Look thru the line to find the open bracket to match. 57 */ 58 do 59 { 60 if ((c = ch_forw_get()) == '\n' || c == EOI) 61 { 62 if (forwdir) 63 error("No bracket in top line", NULL_PARG); 64 else 65 error("No bracket in bottom line", NULL_PARG); 66 return; 67 } 68 } while (c != obrac || --n > 0); 69 70 /* 71 * Position the file just "after" the open bracket 72 * (in the direction in which we will be searching). 73 * If searching forward, we are already after the bracket. 74 * If searching backward, skip back over the open bracket. 75 */ 76 if (!forwdir) 77 (void) ch_back_get(); 78 79 /* 80 * Search the file for the matching bracket. 81 */ 82 chget = (forwdir) ? ch_forw_get : ch_back_get; 83 nest = 0; 84 while ((c = (*chget)()) != EOI) 85 { 86 if (c == obrac) 87 { 88 if (nest == INT_MAX) 89 break; 90 nest++; 91 } 92 else if (c == cbrac && --nest < 0) 93 { 94 /* 95 * Found the matching bracket. 96 * If searching backward, put it on the top line. 97 * If searching forward, put it on the bottom line. 98 */ 99 jump_line_loc(ch_tell(), forwdir ? -1 : 1); 100 return; 101 } 102 } 103 error("No matching bracket", NULL_PARG); 104 } 105