157687Sbostic /*- 257687Sbostic * Copyright (c) 1992 The Regents of the University of California. 357687Sbostic * All rights reserved. 457687Sbostic * 557687Sbostic * This code is derived from software contributed to Berkeley by 657687Sbostic * Rodney Ruddock of the University of Guelph. 757687Sbostic * 857687Sbostic * %sccs.include.redist.c% 957687Sbostic */ 1057687Sbostic 1157687Sbostic #ifndef lint 12*57710Sbostic static char sccsid[] = "@(#)get_pattern.c 5.2 (Berkeley) 01/23/93"; 1357687Sbostic #endif /* not lint */ 1457687Sbostic 15*57710Sbostic #include <sys/types.h> 16*57710Sbostic 17*57710Sbostic #include <db.h> 18*57710Sbostic #include <regex.h> 19*57710Sbostic #include <setjmp.h> 20*57710Sbostic #include <stdio.h> 21*57710Sbostic #include <stdlib.h> 22*57710Sbostic #include <string.h> 23*57710Sbostic 2457687Sbostic #include "ed.h" 25*57710Sbostic #include "extern.h" 2657687Sbostic 2757687Sbostic /* 2857687Sbostic * This is for getting RE and replacement patterns for any command 2957687Sbostic * that uses RE's and replacements. 3057687Sbostic */ 31*57710Sbostic char * 32*57710Sbostic get_pattern(delim, inputt, errnum, flag) 33*57710Sbostic int delim, *errnum, flag; 34*57710Sbostic FILE *inputt; 3557687Sbostic { 36*57710Sbostic static int l_max = 510; 37*57710Sbostic int l_cnt = 1; 38*57710Sbostic char *l_pat, *l_pat_tmp; 3957687Sbostic 40*57710Sbostic /* get a "reasonable amount of space for the RE */ 41*57710Sbostic l_pat = calloc(l_max + 2, sizeof(char)); 42*57710Sbostic if (l_pat == NULL) { 43*57710Sbostic *errnum = -3; 44*57710Sbostic strcpy(help_msg, "out of memory error"); 45*57710Sbostic return (NULL); 46*57710Sbostic } 47*57710Sbostic l_pat[0] = delim; 4857687Sbostic 49*57710Sbostic if ((delim == ' ') || (delim == '\n')) { 50*57710Sbostic if (delim == '\n') 51*57710Sbostic ungetc(delim, inputt); 52*57710Sbostic strcpy(help_msg, "illegal delimiter"); 53*57710Sbostic *errnum = -2; 54*57710Sbostic return (l_pat); 55*57710Sbostic } 56*57710Sbostic for (;;) { 57*57710Sbostic ss = getc(inputt); 58*57710Sbostic if (ss == '\\') { 59*57710Sbostic ss = getc(inputt); 60*57710Sbostic if ((ss == delim) || ((flag == 1) && (ss == '\n'))) 61*57710Sbostic l_pat[l_cnt] = ss; 62*57710Sbostic else { 63*57710Sbostic l_pat[l_cnt] = '\\'; 64*57710Sbostic /* ungetc(ss, inputt); */ 65*57710Sbostic l_pat[++l_cnt] = ss; 66*57710Sbostic } 67*57710Sbostic goto leap; 68*57710Sbostic } else 69*57710Sbostic if ((ss == '\n') || (ss == EOF)) { 70*57710Sbostic ungetc(ss, inputt); 71*57710Sbostic strcpy(help_msg, "no closing delimiter found"); 72*57710Sbostic *errnum = -1; 73*57710Sbostic /* This is done for s's backward compat. */ 74*57710Sbostic l_pat[l_cnt] = '\0'; 75*57710Sbostic return (l_pat); 76*57710Sbostic } 77*57710Sbostic if (ss == delim) 78*57710Sbostic break; 7957687Sbostic 80*57710Sbostic l_pat[l_cnt] = ss; 8157687Sbostic 82*57710Sbostic leap: if (l_cnt > l_max) { 83*57710Sbostic /* The RE is really long; get more space for it. */ 84*57710Sbostic l_max = l_max + 256; 85*57710Sbostic l_pat_tmp = l_pat; 86*57710Sbostic l_pat = calloc(l_max + 2, sizeof(char)); 87*57710Sbostic if (l_pat == NULL) { 88*57710Sbostic *errnum = -3; 89*57710Sbostic strcpy(help_msg, "out of memory error"); 90*57710Sbostic return (NULL); 91*57710Sbostic } 92*57710Sbostic bcopy(l_pat_tmp, l_pat, l_cnt); 93*57710Sbostic free(l_pat_tmp); 94*57710Sbostic } 95*57710Sbostic l_cnt++; 96*57710Sbostic } 97*57710Sbostic l_pat[l_cnt] = '\0'; 98*57710Sbostic *errnum = 0; 99*57710Sbostic /* 100*57710Sbostic * Send back the pattern. l_pat[0] has the delimiter in it so the RE 101*57710Sbostic * really starts at l_pat[1]. It's done this way for the special forms 102*57710Sbostic * of 's' (substitute). 103*57710Sbostic */ 104*57710Sbostic return (l_pat); 105*57710Sbostic } 106