source: trunk/ncurses/form/fty_regex.c@ 2622

Last change on this file since 2622 was 2621, checked in by bird, 20 years ago

GNU ncurses 5.5

File size: 6.7 KB
Line 
1
2/*
3 * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
4 * You may freely copy it for use as a template for your own field types.
5 * If you develop a field type that might be of general use, please send
6 * it back to the ncurses maintainers for inclusion in the next version.
7 */
8/***************************************************************************
9* *
10* Author : Juergen Pfeifer *
11* *
12***************************************************************************/
13
14#include "form.priv.h"
15
16MODULE_ID("$Id: fty_regex.c,v 1.18 2004/05/29 19:19:09 tom Exp $")
17
18#if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */
19#include <regex.h>
20
21typedef struct
22 {
23 regex_t *pRegExp;
24 unsigned long *refCount;
25 }
26RegExp_Arg;
27
28#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
29#undef RETURN
30static int reg_errno;
31
32static char *
33RegEx_Init(char *instring)
34{
35 reg_errno = 0;
36 return instring;
37}
38
39static char *
40RegEx_Error(int code)
41{
42 reg_errno = code;
43 return 0;
44}
45
46#define INIT register char *sp = RegEx_Init(instring);
47#define GETC() (*sp++)
48#define PEEKC() (*sp)
49#define UNGETC(c) (--sp)
50#define RETURN(c) return(c)
51#define ERROR(c) return RegEx_Error(c)
52
53#if HAVE_REGEXP_H_FUNCS
54#include <regexp.h>
55#else
56#include <regexpr.h>
57#endif
58
59typedef struct
60{
61 char *compiled_expression;
62 unsigned long *refCount;
63}
64RegExp_Arg;
65
66/* Maximum Length we allow for a compiled regular expression */
67#define MAX_RX_LEN (2048)
68#define RX_INCREMENT (256)
69
70#endif
71
72/*---------------------------------------------------------------------------
73| Facility : libnform
74| Function : static void *Make_RegularExpression_Type(va_list * ap)
75|
76| Description : Allocate structure for regex type argument.
77|
78| Return Values : Pointer to argument structure or NULL on error
79+--------------------------------------------------------------------------*/
80static void *
81Make_RegularExpression_Type(va_list *ap)
82{
83#if HAVE_REGEX_H_FUNCS
84 char *rx = va_arg(*ap, char *);
85 RegExp_Arg *preg;
86
87 preg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg));
88
89 if (preg)
90 {
91 if (((preg->pRegExp = (regex_t *) malloc(sizeof(regex_t))) != 0)
92 && !regcomp(preg->pRegExp, rx,
93 (REG_EXTENDED | REG_NOSUB | REG_NEWLINE)))
94 {
95 preg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
96
97 *(preg->refCount) = 1;
98 }
99 else
100 {
101 if (preg->pRegExp)
102 free(preg->pRegExp);
103 free(preg);
104 preg = (RegExp_Arg *)0;
105 }
106 }
107 return ((void *)preg);
108#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
109 char *rx = va_arg(*ap, char *);
110 RegExp_Arg *pArg;
111
112 pArg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg));
113
114 if (pArg)
115 {
116 int blen = RX_INCREMENT;
117
118 pArg->compiled_expression = NULL;
119 pArg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
120
121 *(pArg->refCount) = 1;
122
123 do
124 {
125 char *buf = (char *)malloc(blen);
126
127 if (buf)
128 {
129#if HAVE_REGEXP_H_FUNCS
130 char *last_pos = compile(rx, buf, &buf[blen], '\0');
131
132#else /* HAVE_REGEXPR_H_FUNCS */
133 char *last_pos = compile(rx, buf, &buf[blen]);
134#endif
135 if (reg_errno)
136 {
137 free(buf);
138 if (reg_errno == 50)
139 blen += RX_INCREMENT;
140 else
141 {
142 free(pArg);
143 pArg = NULL;
144 break;
145 }
146 }
147 else
148 {
149 pArg->compiled_expression = buf;
150 break;
151 }
152 }
153 }
154 while (blen <= MAX_RX_LEN);
155 }
156 if (pArg && !pArg->compiled_expression)
157 {
158 free(pArg);
159 pArg = NULL;
160 }
161 return (void *)pArg;
162#else
163 return 0;
164#endif
165}
166
167/*---------------------------------------------------------------------------
168| Facility : libnform
169| Function : static void *Copy_RegularExpression_Type(
170| const void * argp)
171|
172| Description : Copy structure for regex type argument.
173|
174| Return Values : Pointer to argument structure or NULL on error.
175+--------------------------------------------------------------------------*/
176static void *
177Copy_RegularExpression_Type(const void *argp)
178{
179#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS)
180 const RegExp_Arg *ap = (const RegExp_Arg *)argp;
181 const RegExp_Arg *result = (const RegExp_Arg *)0;
182
183 if (ap)
184 {
185 *(ap->refCount) += 1;
186 result = ap;
187 }
188 return (void *)result;
189#else
190 return 0;
191#endif
192}
193
194/*---------------------------------------------------------------------------
195| Facility : libnform
196| Function : static void Free_RegularExpression_Type(void * argp)
197|
198| Description : Free structure for regex type argument.
199|
200| Return Values : -
201+--------------------------------------------------------------------------*/
202static void
203Free_RegularExpression_Type(void *argp)
204{
205#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
206 RegExp_Arg *ap = (RegExp_Arg *)argp;
207
208 if (ap)
209 {
210 if (--(*(ap->refCount)) == 0)
211 {
212#if HAVE_REGEX_H_FUNCS
213 if (ap->pRegExp)
214 {
215 free(ap->refCount);
216 regfree(ap->pRegExp);
217 }
218#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
219 if (ap->compiled_expression)
220 {
221 free(ap->refCount);
222 free(ap->compiled_expression);
223 }
224#endif
225 free(ap);
226 }
227 }
228#endif
229}
230
231/*---------------------------------------------------------------------------
232| Facility : libnform
233| Function : static bool Check_RegularExpression_Field(
234| FIELD * field,
235| const void * argp)
236|
237| Description : Validate buffer content to be a valid regular expression
238|
239| Return Values : TRUE - field is valid
240| FALSE - field is invalid
241+--------------------------------------------------------------------------*/
242static bool
243Check_RegularExpression_Field(FIELD *field, const void *argp)
244{
245 bool match = FALSE;
246
247#if HAVE_REGEX_H_FUNCS
248 const RegExp_Arg *ap = (const RegExp_Arg *)argp;
249
250 if (ap && ap->pRegExp)
251 match = (regexec(ap->pRegExp, field_buffer(field, 0), 0, NULL, 0)
252 ? FALSE
253 : TRUE);
254#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
255 RegExp_Arg *ap = (RegExp_Arg *)argp;
256
257 if (ap && ap->compiled_expression)
258 match = (step(field_buffer(field, 0), ap->compiled_expression)
259 ? TRUE
260 : FALSE);
261#endif
262 return match;
263}
264
265static FIELDTYPE typeREGEXP =
266{
267 _HAS_ARGS | _RESIDENT,
268 1, /* this is mutable, so we can't be const */
269 (FIELDTYPE *)0,
270 (FIELDTYPE *)0,
271 Make_RegularExpression_Type,
272 Copy_RegularExpression_Type,
273 Free_RegularExpression_Type,
274 Check_RegularExpression_Field,
275 NULL,
276 NULL,
277 NULL
278};
279
280NCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_REGEXP = &typeREGEXP;
281
282/* fty_regex.c ends here */
Note: See TracBrowser for help on using the repository browser.