1a5f0fb15SPaul Saab /* 2*c77c4889SXin LI * Copyright (C) 1984-2024 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 796e55cc7SXin LI * For more information, see the README file. 8a5f0fb15SPaul Saab */ 9a5f0fb15SPaul Saab 10a5f0fb15SPaul Saab 11a5f0fb15SPaul Saab /* 12a5f0fb15SPaul Saab * Routines to perform bracket matching functions. 13a5f0fb15SPaul Saab */ 14a5f0fb15SPaul Saab 15a5f0fb15SPaul Saab #include "less.h" 16a5f0fb15SPaul Saab #include "position.h" 17a5f0fb15SPaul Saab 18a5f0fb15SPaul Saab /* 19a5f0fb15SPaul Saab * Try to match the n-th open bracket 20a5f0fb15SPaul Saab * which appears in the top displayed line (forwdir), 21a5f0fb15SPaul Saab * or the n-th close bracket 22a5f0fb15SPaul Saab * which appears in the bottom displayed line (!forwdir). 23a5f0fb15SPaul Saab * The characters which serve as "open bracket" and 24a5f0fb15SPaul Saab * "close bracket" are given. 25a5f0fb15SPaul Saab */ 26d713e089SXin LI public void match_brac(char obrac, char cbrac, int forwdir, int n) 27a5f0fb15SPaul Saab { 281ea31627SRobert Watson int c; 291ea31627SRobert Watson int nest; 30a5f0fb15SPaul Saab POSITION pos; 31f6b74a7dSXin LI int (*chget)(); 32a5f0fb15SPaul Saab 33f6b74a7dSXin LI extern int ch_forw_get(), ch_back_get(); 34a5f0fb15SPaul Saab 35a5f0fb15SPaul Saab /* 36a5f0fb15SPaul Saab * Seek to the line containing the open bracket. 37a5f0fb15SPaul Saab * This is either the top or bottom line on the screen, 38a5f0fb15SPaul Saab * depending on the type of bracket. 39a5f0fb15SPaul Saab */ 40a5f0fb15SPaul Saab pos = position((forwdir) ? TOP : BOTTOM); 41a5f0fb15SPaul Saab if (pos == NULL_POSITION || ch_seek(pos)) 42a5f0fb15SPaul Saab { 43a5f0fb15SPaul Saab if (forwdir) 44a5f0fb15SPaul Saab error("Nothing in top line", NULL_PARG); 45a5f0fb15SPaul Saab else 46a5f0fb15SPaul Saab error("Nothing in bottom line", NULL_PARG); 47a5f0fb15SPaul Saab return; 48a5f0fb15SPaul Saab } 49a5f0fb15SPaul Saab 50a5f0fb15SPaul Saab /* 51a5f0fb15SPaul Saab * Look thru the line to find the open bracket to match. 52a5f0fb15SPaul Saab */ 53a5f0fb15SPaul Saab do 54a5f0fb15SPaul Saab { 55a5f0fb15SPaul Saab if ((c = ch_forw_get()) == '\n' || c == EOI) 56a5f0fb15SPaul Saab { 57a5f0fb15SPaul Saab if (forwdir) 58a5f0fb15SPaul Saab error("No bracket in top line", NULL_PARG); 59a5f0fb15SPaul Saab else 60a5f0fb15SPaul Saab error("No bracket in bottom line", NULL_PARG); 61a5f0fb15SPaul Saab return; 62a5f0fb15SPaul Saab } 63a5f0fb15SPaul Saab } while (c != obrac || --n > 0); 64a5f0fb15SPaul Saab 65a5f0fb15SPaul Saab /* 66a5f0fb15SPaul Saab * Position the file just "after" the open bracket 67a5f0fb15SPaul Saab * (in the direction in which we will be searching). 68a5f0fb15SPaul Saab * If searching forward, we are already after the bracket. 69a5f0fb15SPaul Saab * If searching backward, skip back over the open bracket. 70a5f0fb15SPaul Saab */ 71a5f0fb15SPaul Saab if (!forwdir) 72a5f0fb15SPaul Saab (void) ch_back_get(); 73a5f0fb15SPaul Saab 74a5f0fb15SPaul Saab /* 75a5f0fb15SPaul Saab * Search the file for the matching bracket. 76a5f0fb15SPaul Saab */ 77a5f0fb15SPaul Saab chget = (forwdir) ? ch_forw_get : ch_back_get; 78a5f0fb15SPaul Saab nest = 0; 79a5f0fb15SPaul Saab while ((c = (*chget)()) != EOI) 80a5f0fb15SPaul Saab { 81a5f0fb15SPaul Saab if (c == obrac) 8295270f73SXin LI { 8395270f73SXin LI if (nest == INT_MAX) 8495270f73SXin LI break; 85a5f0fb15SPaul Saab nest++; 8695270f73SXin LI } 87a5f0fb15SPaul Saab else if (c == cbrac && --nest < 0) 88a5f0fb15SPaul Saab { 89a5f0fb15SPaul Saab /* 90a5f0fb15SPaul Saab * Found the matching bracket. 91a5f0fb15SPaul Saab * If searching backward, put it on the top line. 92a5f0fb15SPaul Saab * If searching forward, put it on the bottom line. 93a5f0fb15SPaul Saab */ 94a5f0fb15SPaul Saab jump_line_loc(ch_tell(), forwdir ? -1 : 1); 95a5f0fb15SPaul Saab return; 96a5f0fb15SPaul Saab } 97a5f0fb15SPaul Saab } 98a5f0fb15SPaul Saab error("No matching bracket", NULL_PARG); 99a5f0fb15SPaul Saab } 100