1 /* $OpenBSD: brac.c,v 1.2 2001/01/29 01:58:00 niklas Exp $ */ 2 3 /* 4 * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice in the documentation and/or other materials provided with 14 * the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30 /* 31 * Routines to perform bracket matching functions. 32 */ 33 34 #include "less.h" 35 #include "position.h" 36 37 /* 38 * Try to match the n-th open bracket 39 * which appears in the top displayed line (forwdir), 40 * or the n-th close bracket 41 * which appears in the bottom displayed line (!forwdir). 42 * The characters which serve as "open bracket" and 43 * "close bracket" are given. 44 */ 45 public void 46 match_brac(obrac, cbrac, forwdir, n) 47 register int obrac; 48 register int cbrac; 49 int forwdir; 50 int n; 51 { 52 register int c; 53 register int nest; 54 POSITION pos; 55 int (*chget)(); 56 57 extern int ch_forw_get(), ch_back_get(); 58 59 /* 60 * Seek to the line containing the open bracket. 61 * This is either the top or bottom line on the screen, 62 * depending on the type of bracket. 63 */ 64 pos = position((forwdir) ? TOP : BOTTOM); 65 if (pos == NULL_POSITION || ch_seek(pos)) 66 { 67 if (forwdir) 68 error("Nothing in top line", NULL_PARG); 69 else 70 error("Nothing in bottom line", NULL_PARG); 71 return; 72 } 73 74 /* 75 * Look thru the line to find the open bracket to match. 76 */ 77 do 78 { 79 if ((c = ch_forw_get()) == '\n' || c == EOI) 80 { 81 if (forwdir) 82 error("No bracket in top line", NULL_PARG); 83 else 84 error("No bracket in bottom line", NULL_PARG); 85 return; 86 } 87 } while (c != obrac || --n > 0); 88 89 /* 90 * Position the file just "after" the open bracket 91 * (in the direction in which we will be searching). 92 * If searching forward, we are already after the bracket. 93 * If searching backward, skip back over the open bracket. 94 */ 95 if (!forwdir) 96 (void) ch_back_get(); 97 98 /* 99 * Search the file for the matching bracket. 100 */ 101 chget = (forwdir) ? ch_forw_get : ch_back_get; 102 nest = 0; 103 while ((c = (*chget)()) != EOI) 104 { 105 if (c == obrac) 106 nest++; 107 else if (c == cbrac && --nest < 0) 108 { 109 /* 110 * Found the matching bracket. 111 * If searching backward, put it on the top line. 112 * If searching forward, put it on the bottom line. 113 */ 114 jump_line_loc(ch_tell(), forwdir ? -1 : 1); 115 return; 116 } 117 } 118 error("No matching bracket", NULL_PARG); 119 } 120