1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. 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[] = "@(#)get_pattern.c 8.1 (Berkeley) 05/31/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 * This is for getting RE and replacement patterns for any command 32 * that uses RE's and replacements. 33 */ 34 char * 35 get_pattern(delim, inputt, errnum, flag) 36 int delim, *errnum, flag; 37 FILE *inputt; 38 { 39 static int l_max = 510; 40 int l_cnt = 1; 41 char *l_pat, *l_pat_tmp; 42 43 /* get a "reasonable amount of space for the RE */ 44 l_pat = calloc(l_max + 2, sizeof(char)); 45 if (l_pat == NULL) { 46 *errnum = -3; 47 strcpy(help_msg, "out of memory error"); 48 return (NULL); 49 } 50 l_pat[0] = delim; 51 52 if ((delim == ' ') || (delim == '\n')) { 53 if (delim == '\n') 54 ungetc(delim, inputt); 55 strcpy(help_msg, "illegal delimiter"); 56 *errnum = -2; 57 return (l_pat); 58 } 59 for (;;) { 60 ss = getc(inputt); 61 if (ss == '\\') { 62 ss = getc(inputt); 63 if ((ss == delim) || ((flag == 1) && (ss == '\n'))) 64 l_pat[l_cnt] = ss; 65 else { 66 l_pat[l_cnt] = '\\'; 67 l_pat[++l_cnt] = ss; 68 } 69 goto leap; 70 } else 71 if ((ss == '\n') || (ss == EOF)) { 72 ungetc(ss, inputt); 73 strcpy(help_msg, "no closing delimiter found"); 74 *errnum = -1; 75 /* This is done for s's backward compat. */ 76 l_pat[l_cnt] = '\0'; 77 return (l_pat); 78 } 79 if (ss == delim) 80 break; 81 82 l_pat[l_cnt] = ss; 83 84 leap: if (l_cnt > l_max) { 85 /* The RE is really long; get more space for it. */ 86 l_max = l_max + 256; 87 l_pat_tmp = l_pat; 88 l_pat = calloc(l_max + 2, sizeof(char)); 89 if (l_pat == NULL) { 90 *errnum = -3; 91 strcpy(help_msg, "out of memory error"); 92 return (NULL); 93 } 94 memmove(l_pat, l_pat_tmp, l_cnt); 95 free(l_pat_tmp); 96 } 97 l_cnt++; 98 } 99 l_pat[l_cnt] = '\0'; 100 *errnum = 0; 101 /* 102 * Send back the pattern. l_pat[0] has the delimiter in it so the RE 103 * really starts at l_pat[1]. It's done this way for the special forms 104 * of 's' (substitute). 105 */ 106 return (l_pat); 107 } 108