xref: /csrg-svn/contrib/ed/get_pattern.c (revision 60663)
157687Sbostic /*-
2*60663Sbostic  * Copyright (c) 1992, 1993
3*60663Sbostic  *	The Regents of the University of California.  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*60663Sbostic static char sccsid[] = "@(#)get_pattern.c	8.1 (Berkeley) 05/31/93";
1357687Sbostic #endif /* not lint */
1457687Sbostic 
1557710Sbostic #include <sys/types.h>
1657710Sbostic 
1757710Sbostic #include <regex.h>
1857710Sbostic #include <setjmp.h>
1957710Sbostic #include <stdio.h>
2057710Sbostic #include <stdlib.h>
2157710Sbostic #include <string.h>
2257710Sbostic 
2358315Sbostic #ifdef DBI
2458315Sbostic #include <db.h>
2558315Sbostic #endif
2658315Sbostic 
2757687Sbostic #include "ed.h"
2857710Sbostic #include "extern.h"
2957687Sbostic 
3057687Sbostic /*
3157687Sbostic  * This is for getting RE and replacement patterns for any command
3257687Sbostic  * that uses RE's and replacements.
3357687Sbostic  */
3457710Sbostic char *
get_pattern(delim,inputt,errnum,flag)3557710Sbostic get_pattern(delim, inputt, errnum, flag)
3657710Sbostic 	int delim, *errnum, flag;
3757710Sbostic 	FILE *inputt;
3857687Sbostic {
3957710Sbostic 	static int l_max = 510;
4057710Sbostic 	int l_cnt = 1;
4157710Sbostic 	char *l_pat, *l_pat_tmp;
4257687Sbostic 
4357710Sbostic 	/* get a "reasonable amount of space for the RE */
4457710Sbostic 	l_pat = calloc(l_max + 2, sizeof(char));
4557710Sbostic 	if (l_pat == NULL) {
4657710Sbostic 		*errnum = -3;
4757710Sbostic 		strcpy(help_msg, "out of memory error");
4857710Sbostic 		return (NULL);
4957710Sbostic 	}
5057710Sbostic 	l_pat[0] = delim;
5157687Sbostic 
5257710Sbostic 	if ((delim == ' ') || (delim == '\n')) {
5357710Sbostic 		if (delim == '\n')
5457710Sbostic 			ungetc(delim, inputt);
5557710Sbostic 		strcpy(help_msg, "illegal delimiter");
5657710Sbostic 		*errnum = -2;
5757710Sbostic 		return (l_pat);
5857710Sbostic 	}
5957710Sbostic 	for (;;) {
6057710Sbostic 		ss = getc(inputt);
6157710Sbostic 		if (ss == '\\') {
6257710Sbostic 			ss = getc(inputt);
6357710Sbostic 			if ((ss == delim) || ((flag == 1) && (ss == '\n')))
6457710Sbostic 				l_pat[l_cnt] = ss;
6557710Sbostic 			else {
6657710Sbostic 				l_pat[l_cnt] = '\\';
6757710Sbostic 				l_pat[++l_cnt] = ss;
6857710Sbostic 			}
6957710Sbostic 			goto leap;
7057710Sbostic 		} else
7157710Sbostic 			if ((ss == '\n') || (ss == EOF)) {
7257710Sbostic 				ungetc(ss, inputt);
7357710Sbostic 				strcpy(help_msg, "no closing delimiter found");
7457710Sbostic 				*errnum = -1;
7557710Sbostic 				/* This is done for s's backward compat. */
7657710Sbostic 				l_pat[l_cnt] = '\0';
7757710Sbostic 				return (l_pat);
7857710Sbostic 			}
7957710Sbostic 		if (ss == delim)
8057710Sbostic 			break;
8157687Sbostic 
8257710Sbostic 		l_pat[l_cnt] = ss;
8357687Sbostic 
8457710Sbostic leap:		if (l_cnt > l_max) {
8557710Sbostic 			/* The RE is really long; get more space for it. */
8657710Sbostic 			l_max = l_max + 256;
8757710Sbostic 			l_pat_tmp = l_pat;
8857710Sbostic 			l_pat = calloc(l_max + 2, sizeof(char));
8957710Sbostic 			if (l_pat == NULL) {
9057710Sbostic 				*errnum = -3;
9157710Sbostic 				strcpy(help_msg, "out of memory error");
9257710Sbostic 				return (NULL);
9357710Sbostic 			}
9459483Sbostic 			memmove(l_pat, l_pat_tmp, l_cnt);
9557710Sbostic 			free(l_pat_tmp);
9657710Sbostic 		}
9757710Sbostic 		l_cnt++;
9857710Sbostic 	}
9957710Sbostic 	l_pat[l_cnt] = '\0';
10057710Sbostic 	*errnum = 0;
10157710Sbostic 	/*
10257710Sbostic 	 * Send back the pattern.  l_pat[0] has the delimiter in it so the RE
10357710Sbostic 	 * really starts at l_pat[1]. It's done this way for the special forms
10457710Sbostic 	 * of 's' (substitute).
10557710Sbostic 	 */
10657710Sbostic 	return (l_pat);
10757710Sbostic }
108