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