1 /* $NetBSD: brac.c,v 1.4 2013/09/04 19:44:21 tron Exp $ */ 2 3 /* 4 * Copyright (C) 1984-2012 Mark Nudelman 5 * 6 * You may distribute under the terms of either the GNU General Public 7 * License or the Less License, as specified in the README file. 8 * 9 * For more information, see the README file. 10 */ 11 12 13 /* 14 * Routines to perform bracket matching functions. 15 */ 16 17 #include "less.h" 18 #include "position.h" 19 20 /* 21 * Try to match the n-th open bracket 22 * which appears in the top displayed line (forwdir), 23 * or the n-th close bracket 24 * which appears in the bottom displayed line (!forwdir). 25 * The characters which serve as "open bracket" and 26 * "close bracket" are given. 27 */ 28 public void 29 match_brac(obrac, cbrac, forwdir, n) 30 register int obrac; 31 register int cbrac; 32 int forwdir; 33 int n; 34 { 35 register int c; 36 register int nest; 37 POSITION pos; 38 int (*chget) __P((void)); 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 nest++; 88 else if (c == cbrac && --nest < 0) 89 { 90 /* 91 * Found the matching bracket. 92 * If searching backward, put it on the top line. 93 * If searching forward, put it on the bottom line. 94 */ 95 jump_line_loc(ch_tell(), forwdir ? -1 : 1); 96 return; 97 } 98 } 99 error("No matching bracket", NULL_PARG); 100 } 101