2 * regexp.h -- old-style regexp compile and step (emulated with POSIX regex)
3 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
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)
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.
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.
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.
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 */
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.
37 char *loc1; /* the beginning of a match */
38 char *loc2; /* the end of a match */
39 int circf; /* current pattern begins with '^' */
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.
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.
57 #define __REGEX_T_ALIGN (__alignof__(regex_t))
59 #define __REGEX_T_ALIGN 8
60 #endif /* !__GNUC__ */
62 #define __regex_t_align(p) \
63 ((regex_t *) ((((unsigned long) p) + __REGEX_T_ALIGN - 1) \
64 / __REGEX_T_ALIGN * __REGEX_T_ALIGN))
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.
73 compile(char *instring, char *expbuf, char *endbuf, int eof)
84 __buf = malloc(__buflen);
95 if (__c == '\0' || __c == '\n') {
99 if (__len + 2 > __buflen) {
101 __buf = realloc(__buf, __buflen);
107 if (__len == 0 && !circf && __c == '^')
110 __buf[__len++] = __c;
112 if (__len == 0 && !circf) {
118 if (endbuf <= expbuf + sizeof(regex_t)) {
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);
132 __error = 36; /* poor fit */
138 __error = 44; /* poor fit */
144 __error = 36; /* poor fit */
147 __error = 36; /* poor fit */
153 __error = 36; /* poor fit */
156 __error = 36; /* poor fit */
162 __error = 36; /* poor fit */
171 __error = 36; /* as good as any */
179 RETURN((__preg->buffer + __preg->rx.allocated - __preg->rx.reserved));
181 RETURN((__preg->buffer + __preg->used));
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.
191 step(char *string, char *expbuf)
194 regmatch_t __pmatch[1];
196 __result = regexec(__regex_t_align(expbuf), string, 1, __pmatch, 0);
197 if (circf && __pmatch[0].rm_so != 0)
198 __result = REG_NOMATCH;
200 loc1 = string + __pmatch[0].rm_so;
201 loc2 = string + __pmatch[0].rm_eo;
203 return __result == 0;
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.
212 advance(char *string, char *expbuf)
219 __result = step(string, expbuf);
224 #endif /* _REGEXP_H */