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