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®_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®_ICASE) && (code = regcomp((regex_t*)rebuf->w,(char*)t->w-((regex_t*)rebuf->w)->re_npat,reflags|REG_ICASE|REG_DELIMITED|REG_MUSTDELIM|((reflags®_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