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