xref: /original-bsd/contrib/ed/get_pattern.c (revision da6ea800)
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