160786Sps/* 2240121Sdelphij * Copyright (C) 1984-2012 Mark Nudelman 360786Sps * 460786Sps * You may distribute under the terms of either the GNU General Public 560786Sps * License or the Less License, as specified in the README file. 660786Sps * 7240121Sdelphij * For more information, see the README file. 860786Sps */ 960786Sps 1060786Sps 1160786Sps/* 1260786Sps * Routines to perform bracket matching functions. 1360786Sps */ 1460786Sps 1560786Sps#include "less.h" 1660786Sps#include "position.h" 1760786Sps 1860786Sps/* 1960786Sps * Try to match the n-th open bracket 2060786Sps * which appears in the top displayed line (forwdir), 2160786Sps * or the n-th close bracket 2260786Sps * which appears in the bottom displayed line (!forwdir). 2360786Sps * The characters which serve as "open bracket" and 2460786Sps * "close bracket" are given. 2560786Sps */ 2660786Sps public void 2760786Spsmatch_brac(obrac, cbrac, forwdir, n) 2860786Sps register int obrac; 2960786Sps register int cbrac; 3060786Sps int forwdir; 3160786Sps int n; 3260786Sps{ 3360786Sps register int c; 3460786Sps register int nest; 3560786Sps POSITION pos; 3660786Sps int (*chget)(); 3760786Sps 3860786Sps extern int ch_forw_get(), ch_back_get(); 3960786Sps 4060786Sps /* 4160786Sps * Seek to the line containing the open bracket. 4260786Sps * This is either the top or bottom line on the screen, 4360786Sps * depending on the type of bracket. 4460786Sps */ 4560786Sps pos = position((forwdir) ? TOP : BOTTOM); 4660786Sps if (pos == NULL_POSITION || ch_seek(pos)) 4760786Sps { 4860786Sps if (forwdir) 4960786Sps error("Nothing in top line", NULL_PARG); 5060786Sps else 5160786Sps error("Nothing in bottom line", NULL_PARG); 5260786Sps return; 5360786Sps } 5460786Sps 5560786Sps /* 5660786Sps * Look thru the line to find the open bracket to match. 5760786Sps */ 5860786Sps do 5960786Sps { 6060786Sps if ((c = ch_forw_get()) == '\n' || c == EOI) 6160786Sps { 6260786Sps if (forwdir) 6360786Sps error("No bracket in top line", NULL_PARG); 6460786Sps else 6560786Sps error("No bracket in bottom line", NULL_PARG); 6660786Sps return; 6760786Sps } 6860786Sps } while (c != obrac || --n > 0); 6960786Sps 7060786Sps /* 7160786Sps * Position the file just "after" the open bracket 7260786Sps * (in the direction in which we will be searching). 7360786Sps * If searching forward, we are already after the bracket. 7460786Sps * If searching backward, skip back over the open bracket. 7560786Sps */ 7660786Sps if (!forwdir) 7760786Sps (void) ch_back_get(); 7860786Sps 7960786Sps /* 8060786Sps * Search the file for the matching bracket. 8160786Sps */ 8260786Sps chget = (forwdir) ? ch_forw_get : ch_back_get; 8360786Sps nest = 0; 8460786Sps while ((c = (*chget)()) != EOI) 8560786Sps { 8660786Sps if (c == obrac) 8760786Sps nest++; 8860786Sps else if (c == cbrac && --nest < 0) 8960786Sps { 9060786Sps /* 9160786Sps * Found the matching bracket. 9260786Sps * If searching backward, put it on the top line. 9360786Sps * If searching forward, put it on the bottom line. 9460786Sps */ 9560786Sps jump_line_loc(ch_tell(), forwdir ? -1 : 1); 9660786Sps return; 9760786Sps } 9860786Sps } 9960786Sps error("No matching bracket", NULL_PARG); 10060786Sps} 101