1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1995-2012 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                                                                      *
19 ***********************************************************************/
20 #pragma prototyped
21 
22 #include "sed.h"
23 
24 Text retemp;	/* holds a rewritten regex, without delimiter */
25 
26 word
recomp(Text * rebuf,Text * t,int sub)27 recomp(Text *rebuf, Text *t, int sub)
28 {
29 	static word lastre;
30 	int code;
31 	int c;
32 	int n;
33 	if(!(c = *t->w) || c == '\n' || !(n = *(t->w + 1)) || n == '\n')
34 		syntax("unterminated regular expression");
35 	else if (c != n) {
36 		assure(rebuf, sizeof(regex_t));
37 		if (code = regcomp((regex_t*)rebuf->w,(char*)t->w,reflags|REG_DELIMITED|REG_MUSTDELIM|((reflags&REG_LENIENT)?0:REG_ESCAPE)))
38 			badre((regex_t*)rebuf->w,code);
39 		t->w += ((regex_t*)rebuf->w)->re_npat;
40 		if (!sub && *t->w == 'I') {
41 			if (!(reflags&REG_ICASE) && (code = regcomp((regex_t*)rebuf->w,(char*)t->w-((regex_t*)rebuf->w)->re_npat,reflags|REG_ICASE|REG_DELIMITED|REG_MUSTDELIM|((reflags&REG_LENIENT)?0:REG_ESCAPE))))
42 				badre((regex_t*)rebuf->w,code);
43 			t->w++;
44 		}
45 		lastre = rebuf->w - rebuf->s;
46 		rebuf->w += sizeof(regex_t);
47 	} else if(rebuf->w == rebuf->s)
48 		syntax("no previous regular expression");
49 	else {
50 		if (sub) {
51 			assure(rebuf, sizeof(regex_t));
52 			if (code = regdup(readdr(lastre), (regex_t*)rebuf->w))
53 				badre((regex_t*)rebuf->w,code);
54 			lastre = rebuf->w - rebuf->s;
55 			rebuf->w += sizeof(regex_t);
56 		}
57 		t->w += 2;
58 	}
59 	return lastre;
60 }
61 
62 void
reerror(regex_t * re,int code)63 reerror(regex_t* re, int code)
64 {
65 	if(code && code != REG_NOMATCH) {
66 		char buf[UCHAR_MAX+1];
67 		regerror(code, re, buf, sizeof(buf));
68 		error(3, "regular expression execution error: %s", buf);
69 	}
70 }
71 
72 int
reexec(regex_t * re,char * s,size_t n,size_t nmatch,regmatch_t * match,int flags)73 reexec(regex_t* re, char* s, size_t n, size_t nmatch, regmatch_t* match, int flags)
74 {
75 	int code;
76 	if((code = regnexec(re, s, n, nmatch, match, flags)) && code != REG_NOMATCH)
77 		reerror(re, code);
78 	return code;
79 }
80 
81 int
substitute(regex_t * re,Text * data)82 substitute(regex_t *re, Text *data)
83 {
84 	word n;
85 	int c;
86 	regmatch_t matches[100];
87 	if(reexec(re, (char*)data->s, data->w - data->s, elementsof(matches), matches, 0))
88 		return 0;
89 	if(c = regsubexec(re, (char*)data->s, elementsof(matches), matches)) {
90 		reerror(re, c);
91 		return 0;
92 	}
93 	n = re->re_sub->re_len;
94 	assure(data, n+1);
95 	memcpy(data->s, re->re_sub->re_buf, n+1);
96 	data->w = data->s + n;
97 	return 1;
98 }
99