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