Line 0
Link Here
|
|
|
1 |
#include <sys/types.h> |
2 |
#include <stdio.h> |
3 |
#include <regex.h> |
4 |
#include <string.h> |
5 |
#include <stdlib.h> |
6 |
#include <errno.h> |
7 |
|
8 |
typedef struct { |
9 |
regex_t re; |
10 |
char *regexp; |
11 |
} mawk_re_t; |
12 |
|
13 |
static mawk_re_t *last_used_regexp = NULL; |
14 |
static int err_code = 0; |
15 |
|
16 |
void prepare_regexp (regexp) |
17 |
char *regexp; |
18 |
{ |
19 |
int bs = 0; |
20 |
char *tail = regexp; |
21 |
char ch; |
22 |
|
23 |
while ((ch = *regexp++) != 0){ |
24 |
if (bs){ |
25 |
switch (ch){ |
26 |
case 'n': *tail++ = '\n'; break; |
27 |
case 't': *tail++ = '\t'; break; |
28 |
case 'f': *tail++ = '\f'; break; |
29 |
case 'b': *tail++ = '\b'; break; |
30 |
case 'r': *tail++ = '\r'; break; |
31 |
case 'a': *tail++ = '\07'; break; |
32 |
case 'v': *tail++ = '\013'; break; |
33 |
default: *tail++ = '\\'; *tail++ = ch; |
34 |
} |
35 |
|
36 |
bs = 0; |
37 |
}else{ |
38 |
if (ch == '\\'){ |
39 |
bs = 1; |
40 |
}else{ |
41 |
*tail++ = ch; |
42 |
} |
43 |
} |
44 |
} |
45 |
|
46 |
*tail = 0; |
47 |
} |
48 |
|
49 |
void * REcompile(regexp) |
50 |
char *regexp; |
51 |
{ |
52 |
mawk_re_t *re = (mawk_re_t*) malloc (sizeof (mawk_re_t)); |
53 |
size_t len = strlen (regexp); |
54 |
char *new_regexp = (char *) malloc (len + 3); |
55 |
/* fprintf (stderr, "REcompile: %s\n", regexp); */ |
56 |
|
57 |
if (!re || !new_regexp) |
58 |
return NULL; |
59 |
|
60 |
new_regexp [0] = '('; |
61 |
memcpy (new_regexp + 1, regexp, len); |
62 |
new_regexp [len+1] = ')'; |
63 |
new_regexp [len+2] = 0; |
64 |
|
65 |
prepare_regexp (new_regexp); |
66 |
|
67 |
last_used_regexp = re; |
68 |
|
69 |
memset (re, 0, sizeof (mawk_re_t)); |
70 |
re -> regexp = strdup (new_regexp); |
71 |
err_code = regcomp (&re->re, new_regexp, REG_EXTENDED | REG_NEWLINE); |
72 |
|
73 |
free (new_regexp); |
74 |
|
75 |
if (err_code) |
76 |
return NULL; |
77 |
|
78 |
return re; |
79 |
} |
80 |
|
81 |
int |
82 |
REtest(str, re) |
83 |
char *str ; |
84 |
mawk_re_t* re ; |
85 |
{ |
86 |
/* fprintf (stderr, "REtest: \"%s\" ~ /%s/", str, re -> regexp); */ |
87 |
|
88 |
last_used_regexp = re; |
89 |
|
90 |
if (regexec (&re->re, str, 0, NULL, 0)){ |
91 |
/* fprintf (stderr, "=1\n"); */ |
92 |
return 0; |
93 |
}else{ |
94 |
/* fprintf (stderr, "=0\n"); */ |
95 |
return 1; |
96 |
} |
97 |
} |
98 |
|
99 |
char *REmatch(str, re, lenp) |
100 |
char *str ; |
101 |
mawk_re_t* re ; |
102 |
unsigned *lenp ; |
103 |
{ |
104 |
regmatch_t match [100]; |
105 |
/* fprintf (stderr, "REmatch: \"%s\" ~ /%s/", str, re -> regexp); */ |
106 |
|
107 |
last_used_regexp = re; |
108 |
|
109 |
if (!regexec (&re->re, str, 100, match, 0)){ |
110 |
*lenp = match [0].rm_eo - match[0].rm_so; |
111 |
/* fprintf (stderr, "=%i/%i\n", match [0].rm_so, *lenp); */ |
112 |
return str + match [0].rm_so; |
113 |
}else{ |
114 |
/* fprintf (stderr, "=0\n"); */ |
115 |
return NULL; |
116 |
} |
117 |
} |
118 |
|
119 |
void REmprint(m, f) |
120 |
void * m ; |
121 |
FILE *f ; |
122 |
{ |
123 |
/* no debugging code available */ |
124 |
abort (); |
125 |
} |
126 |
|
127 |
static char error_buffer [2048]; |
128 |
|
129 |
char *REerror () |
130 |
{ |
131 |
size_t len; |
132 |
if (last_used_regexp){ |
133 |
len = regerror (err_code, &last_used_regexp -> re, |
134 |
error_buffer, sizeof (error_buffer)); |
135 |
return error_buffer; |
136 |
}else{ |
137 |
snprintf (error_buffer, sizeof (error_buffer), "malloc failed: %s", |
138 |
strerror (errno)); |
139 |
} |
140 |
} |