OSDN Git Service

Add in a bunch of junk. Busybox now compiles (except for mkfs.minix and
[uclinux-h8/uClibc.git] / include / regexp.h
1 /*
2  * regexp.h -- old-style regexp compile and step (emulated with POSIX regex)
3  * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Library Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Library Public License for more details.
14  */
15
16 /*
17  * Think really hard before you intentionally include this file.
18  * You should really be using the POSIX regex interface instead.
19  * This emulation file is intended solely for compiling old code.
20  *
21  * A program that uses this file must define six macros: INIT,
22  * GETC, PEEKC, UNGETC, RETURN, and ERROR.  This interface is
23  * so arcane that VMS hackers point at it in ridicule.
24  */
25
26 #ifndef _REGEXP_H
27 #define _REGEXP_H
28
29 #include <sys/types.h>                  /* regex.h needs size_t */
30 #include <regex.h>                      /* POSIX.2 regexp routines */
31 #include <stdlib.h>                     /* for malloc, realloc and free */
32
33 /*
34  * These three advertised external variables record state information
35  * for compile and step.  They are so gross, I'm choking as I write this.
36  */
37 char *loc1;                             /* the beginning of a match */
38 char *loc2;                             /* the end of a match */
39 int circf;                              /* current pattern begins with '^' */
40
41 /*
42  * These are the other variables mentioned in the regexp.h manpage.
43  * Since we don't emulate them (whatever they do), we want errors if
44  * they are referenced.  Therefore they are commented out here.
45  */
46 #if 0
47 char *locs;
48 int sed;
49 int nbra;
50 #endif
51
52 /*
53  * We need to stuff a regex_t into an arbitrary buffer so align it.
54  * GCC make this easy.  For the others we have to guess.
55  */
56 #ifdef __GNUC__
57 #define __REGEX_T_ALIGN (__alignof__(regex_t))
58 #else /* !__GNUC__ */
59 #define __REGEX_T_ALIGN 8
60 #endif /* !__GNUC__ */
61
62 #define __regex_t_align(p)                                              \
63         ((regex_t *) ((((unsigned long) p) + __REGEX_T_ALIGN - 1)       \
64                 / __REGEX_T_ALIGN * __REGEX_T_ALIGN))
65
66 /*
67  * We just slurp the whole pattern into a string and then compile
68  * it `normally'.  With this implementation we never use the PEEKC
69  * macro.  Please feel free to die laughing when we translate
70  * error symbols into hard-coded numbers.
71  */
72 char *
73 compile(char *instring, char *expbuf, char *endbuf, int eof)
74 {
75         int __c;
76         int __len;
77         char *__buf;
78         int __buflen;
79         int __error;
80         regex_t *__preg;
81         INIT;
82
83         __buflen = 128;
84         __buf = malloc(__buflen);
85         if (!__buf) {
86                 ERROR(50);
87                 return 0;
88         }
89         __len = 0;
90         circf = 0;
91         for (;;) {
92                 __c = GETC();
93                 if (__c == eof)
94                         break;
95                 if (__c == '\0' || __c == '\n') {
96                         UNGETC(__c);
97                         break;
98                 }
99                 if (__len + 2 > __buflen) {
100                         __buflen *= 2;
101                         __buf = realloc(__buf, __buflen);
102                         if (!__buf) {
103                                 ERROR(50);
104                                 return 0;
105                         }
106                 }
107                 if (__len == 0 && !circf && __c == '^')
108                         circf = 1;
109                 else
110                         __buf[__len++] = __c;
111         }
112         if (__len == 0 && !circf) {
113                 free(__buf);
114                 ERROR(41);
115                 return 0;
116         }
117         __buf[__len] = '\0';
118         if (endbuf <= expbuf + sizeof(regex_t)) {
119                 free(__buf);
120                 ERROR(50);
121                 return 0;
122         }
123         __preg = __regex_t_align(expbuf);
124         __preg->buffer = (char *) (__preg + 1);
125         __preg->allocated = endbuf - (char *) __preg->buffer;
126         __error = regcomp(__preg, __buf, REG_NEWLINE);
127         free(__buf);
128         switch (__error) {
129         case 0:
130                 break;
131         case REG_BADRPT:
132                 __error = 36; /* poor fit */
133                 break;
134         case REG_BADBR:
135                 __error = 16;
136                 break;
137         case REG_EBRACE:
138                 __error = 44; /* poor fit */
139                 break;
140         case REG_EBRACK:
141                 __error = 49;
142                 break;
143         case REG_ERANGE:
144                 __error = 36; /* poor fit */
145                 break;
146         case REG_ECTYPE:
147                 __error = 36; /* poor fit */
148                 break;
149         case REG_EPAREN:
150                 __error = 42;
151                 break;
152         case REG_ESUBREG:
153                 __error = 36; /* poor fit */
154                 break;
155         case REG_EEND:
156                 __error = 36; /* poor fit */
157                 break;
158         case REG_EESCAPE:
159                 __error = 36;
160                 break;
161         case REG_BADPAT:
162                 __error = 36; /* poor fit */
163                 break;
164         case REG_ESIZE:
165                 __error = 50;
166                 break;
167         case REG_ESPACE:
168                 __error = 50;
169                 break;
170         default:
171                 __error = 36; /* as good as any */
172                 break;
173         }
174         if (__error) {
175                 ERROR(__error);
176                 return 0;
177         }
178 #ifdef _RX_H
179         RETURN((__preg->buffer + __preg->rx.allocated - __preg->rx.reserved));
180 #else
181         RETURN((__preg->buffer + __preg->used));
182 #endif
183 }
184
185 /*
186  * Note how we carefully emulate the gross `circf' hack.  Otherwise,
187  * this just looks like an ordinary matching call that records the
188  * starting and ending match positions.
189  */
190 int
191 step(char *string, char *expbuf)
192 {
193         int __result;
194         regmatch_t __pmatch[1];
195
196         __result = regexec(__regex_t_align(expbuf), string, 1, __pmatch, 0);
197         if (circf && __pmatch[0].rm_so != 0)
198                 __result = REG_NOMATCH;
199         if (__result == 0) {
200                 loc1 = string + __pmatch[0].rm_so;
201                 loc2 = string + __pmatch[0].rm_eo;
202         }
203         return __result == 0;
204 }
205
206 /*
207  * For advance we are only supposed to match at the beginning of the
208  * string.  You have to read the man page really carefully to find this
209  * one.  We'll match them kludge-for-kludge.
210  */
211 int
212 advance(char *string, char *expbuf)
213 {
214         int __old_circf;
215         int __result;
216
217         __old_circf = circf;
218         circf = 1;
219         __result = step(string, expbuf);
220         circf = __old_circf;
221         return __result;
222 }
223
224 #endif /* _REGEXP_H */