1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rodney Ruddock of the University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)search.c 5.2 (Berkeley) 01/23/93"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 17 #include <db.h> 18 #include <regex.h> 19 #include <setjmp.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "ed.h" 25 #include "extern.h" 26 27 /* 28 * searches forward through the buffer (wrapping if necessary) for a 29 * line that contains a match to the RE. 30 */ 31 32 LINE * 33 search(inputt, errnum) 34 FILE *inputt; 35 int *errnum; 36 { 37 LINE *l_temp; 38 int l_err; 39 char *l_patt; 40 41 l_temp = current->below; 42 /* Get the RE. */ 43 l_patt = get_pattern(ss, inputt, errnum, 0); 44 if (sigint_flag) 45 SIGINT_ACTION; 46 if (*errnum < -1) 47 return (NULL); 48 *errnum = 0; 49 if ((RE_flag == 0) && (l_patt[1] == '\0')) { 50 *errnum = -1; 51 ungetc(ss, inputt); 52 return (NULL); 53 } else 54 if (l_patt[1] || (RE_patt == NULL)) { 55 free(RE_patt); 56 RE_patt = l_patt; 57 } 58 RE_sol = (RE_patt[1] == '^') ? 1 : 0; 59 60 /* Compile it up. */ 61 if ((l_patt[1]) && 62 (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) { 63 regerror(l_err, &RE_comp, help_msg, 128); 64 *errnum = -1; 65 RE_flag = 0; 66 ungetc(ss, inputt); 67 return (NULL); 68 } 69 RE_flag = 1; 70 if (sigint_flag) 71 SIGINT_ACTION; 72 73 /* Find a line that has the RE in it. */ 74 for (;;) { /* (l_temp != current) */ 75 if (l_temp == NULL) { 76 if (top != NULL) 77 l_temp = top; 78 else 79 break; 80 } 81 get_line(l_temp->handle, l_temp->len); 82 if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) { 83 l_temp = l_temp->below; 84 if (l_temp == (current->below)) 85 break; 86 } else { 87 *errnum = 0; 88 return (l_temp); 89 } 90 if (sigint_flag) 91 SIGINT_ACTION; 92 } 93 strcpy(help_msg, "RE not found"); 94 *errnum = -1; 95 return (NULL); 96 } 97 98 /* 99 * Searches backward through the buffer (wrapping if necessary) to find 100 * a line that contains a match to the RE. 101 */ 102 LINE * 103 search_r(inputt, errnum) 104 FILE *inputt; 105 int *errnum; 106 { 107 LINE *l_temp; 108 int l_err; 109 char *l_patt; 110 111 l_temp = current->above; 112 113 /* Get the RE. */ 114 l_patt = get_pattern(ss, inputt, errnum, 0); 115 if (sigint_flag) 116 SIGINT_ACTION; 117 if (*errnum < -1) 118 return (NULL); 119 *errnum = 0; 120 if ((RE_flag == 0) && (l_patt[1] == '\0')) { 121 *errnum = -1; 122 ungetc(ss, inputt); 123 return (NULL); 124 } else 125 if (l_patt[1] || (RE_patt == NULL)) { 126 free(RE_patt); 127 RE_patt = l_patt; 128 } 129 RE_sol = (RE_patt[1] == '^') ? 1 : 0; 130 131 /* Compile up the RE. */ 132 if ((l_patt[1]) && 133 (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) { 134 regerror(l_err, &RE_comp, help_msg, 128); 135 *errnum = -1; 136 RE_flag = 0; 137 ungetc(ss, inputt); 138 return (NULL); 139 } 140 RE_flag = 1; 141 if (sigint_flag) 142 SIGINT_ACTION; 143 144 /* Search for a line that has the RE in it. */ 145 for (;;) { /* (l_temp != (current->above)) */ 146 if (l_temp == NULL) { 147 if (bottom != NULL) 148 l_temp = bottom; 149 else 150 break; 151 } 152 get_line(l_temp->handle, l_temp->len); 153 if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) { 154 l_temp = l_temp->above; 155 if (l_temp == (current->above)) 156 break; 157 } else { 158 *errnum = 0; 159 return (l_temp); 160 } 161 if (sigint_flag) 162 SIGINT_ACTION; 163 } 164 strcpy(help_msg, "RE not found"); 165 *errnum = -1; 166 return (NULL); 167 } 168