xref: /csrg-svn/contrib/ed/get_pattern.c (revision 57710)
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