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