brac.c revision 60786
1219019Sgabor/* 2219019Sgabor * Copyright (C) 1984-2000 Mark Nudelman 3219019Sgabor * 4219019Sgabor * You may distribute under the terms of either the GNU General Public 5219019Sgabor * License or the Less License, as specified in the README file. 6219019Sgabor * 7219019Sgabor * For more information about less, or for information on how to 8219019Sgabor * contact the author, see the README file. 9219019Sgabor */ 10219019Sgabor 11219019Sgabor 12219019Sgabor/* 13219019Sgabor * Routines to perform bracket matching functions. 14219019Sgabor */ 15219019Sgabor 16219019Sgabor#include "less.h" 17219019Sgabor#include "position.h" 18219019Sgabor 19219019Sgabor/* 20219019Sgabor * Try to match the n-th open bracket 21219019Sgabor * which appears in the top displayed line (forwdir), 22219019Sgabor * or the n-th close bracket 23219019Sgabor * which appears in the bottom displayed line (!forwdir). 24219019Sgabor * The characters which serve as "open bracket" and 25219019Sgabor * "close bracket" are given. 26219019Sgabor */ 27219019Sgabor public void 28219019Sgabormatch_brac(obrac, cbrac, forwdir, n) 29219019Sgabor register int obrac; 30219019Sgabor register int cbrac; 31219019Sgabor int forwdir; 32219019Sgabor int n; 33219019Sgabor{ 34219019Sgabor register int c; 35219019Sgabor register int nest; 36219019Sgabor POSITION pos; 37219019Sgabor int (*chget)(); 38219019Sgabor 39219019Sgabor extern int ch_forw_get(), ch_back_get(); 40219019Sgabor 41219019Sgabor /* 42219019Sgabor * Seek to the line containing the open bracket. 43219019Sgabor * This is either the top or bottom line on the screen, 44219019Sgabor * depending on the type of bracket. 45219019Sgabor */ 46219019Sgabor pos = position((forwdir) ? TOP : BOTTOM); 47219019Sgabor if (pos == NULL_POSITION || ch_seek(pos)) 48219019Sgabor { 49219019Sgabor if (forwdir) 50219019Sgabor error("Nothing in top line", NULL_PARG); 51219019Sgabor else 52219019Sgabor error("Nothing in bottom line", NULL_PARG); 53219019Sgabor return; 54219019Sgabor } 55219019Sgabor 56219019Sgabor /* 57219019Sgabor * Look thru the line to find the open bracket to match. 58219019Sgabor */ 59219019Sgabor do 60219019Sgabor { 61219019Sgabor if ((c = ch_forw_get()) == '\n' || c == EOI) 62219019Sgabor { 63219019Sgabor if (forwdir) 64219019Sgabor error("No bracket in top line", NULL_PARG); 65219019Sgabor else 66219019Sgabor error("No bracket in bottom line", NULL_PARG); 67219019Sgabor return; 68219019Sgabor } 69219019Sgabor } while (c != obrac || --n > 0); 70219019Sgabor 71219019Sgabor /* 72219019Sgabor * Position the file just "after" the open bracket 73219019Sgabor * (in the direction in which we will be searching). 74219019Sgabor * If searching forward, we are already after the bracket. 75219019Sgabor * If searching backward, skip back over the open bracket. 76219019Sgabor */ 77219019Sgabor if (!forwdir) 78219019Sgabor (void) ch_back_get(); 79219019Sgabor 80219019Sgabor /* 81219019Sgabor * Search the file for the matching bracket. 82219019Sgabor */ 83219019Sgabor chget = (forwdir) ? ch_forw_get : ch_back_get; 84219019Sgabor nest = 0; 85219019Sgabor while ((c = (*chget)()) != EOI) 86219019Sgabor { 87219019Sgabor if (c == obrac) 88219019Sgabor nest++; 89219019Sgabor else if (c == cbrac && --nest < 0) 90219019Sgabor { 91219019Sgabor /* 92219019Sgabor * Found the matching bracket. 93219019Sgabor * If searching backward, put it on the top line. 94219019Sgabor * If searching forward, put it on the bottom line. 95219019Sgabor */ 96219019Sgabor jump_line_loc(ch_tell(), forwdir ? -1 : 1); 97219019Sgabor return; 98219019Sgabor } 99219019Sgabor } 100219019Sgabor error("No matching bracket", NULL_PARG); 101219019Sgabor} 102219019Sgabor