1 /****************************************************************************
2 * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /***************************************************************************
31 * Author : Juergen Pfeifer *
33 ***************************************************************************/
35 #include "form.priv.h"
37 MODULE_ID("$Id: fty_regex.c,v 1.24 2010/01/23 21:14:37 tom Exp $")
39 #if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */
45 unsigned long *refCount
;
49 #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
54 RegEx_Init(char *instring
)
67 #define INIT register char *sp = RegEx_Init(instring);
68 #define GETC() (*sp++)
70 #define UNGETC(c) (--sp)
71 #define RETURN(c) return(c)
72 #define ERROR(c) return RegEx_Error(c)
74 #if HAVE_REGEXP_H_FUNCS
82 char *compiled_expression
;
83 unsigned long *refCount
;
87 /* Maximum Length we allow for a compiled regular expression */
88 #define MAX_RX_LEN (2048)
89 #define RX_INCREMENT (256)
93 #if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
96 # define MAYBE_UNUSED GCC_UNUSED
99 /*---------------------------------------------------------------------------
100 | Facility : libnform
101 | Function : static void *Generic_RegularExpression_Type(void * arg)
103 | Description : Allocate structure for regex type argument.
105 | Return Values : Pointer to argument structure or NULL on error
106 +--------------------------------------------------------------------------*/
108 Generic_RegularExpression_Type(void *arg MAYBE_UNUSED
)
110 #if HAVE_REGEX_H_FUNCS
111 char *rx
= (char *)arg
;
112 RegExp_Arg
*preg
= (RegExp_Arg
*)0;
116 preg
= typeMalloc(RegExp_Arg
, 1);
120 T((T_CREATE("RegExp_Arg %p"), (void *)preg
));
121 if (((preg
->pRegExp
= typeMalloc(regex_t
, 1)) != 0)
122 && !regcomp(preg
->pRegExp
, rx
,
123 (REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
)))
125 T((T_CREATE("regex_t %p"), (void *)preg
->pRegExp
));
126 preg
->refCount
= typeMalloc(unsigned long, 1);
128 *(preg
->refCount
) = 1;
135 preg
= (RegExp_Arg
*)0;
139 return ((void *)preg
);
140 #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
141 char *rx
= (char *)arg
;
142 RegExp_Arg
*pArg
= (RegExp_Arg
*)0;
146 pArg
= typeMalloc(RegExp_Arg
, 1);
150 int blen
= RX_INCREMENT
;
152 T((T_CREATE("RegExp_Arg %p"), pArg
));
153 pArg
->compiled_expression
= NULL
;
154 pArg
->refCount
= typeMalloc(unsigned long, 1);
156 *(pArg
->refCount
) = 1;
160 char *buf
= typeMalloc(char, blen
);
164 #if HAVE_REGEXP_H_FUNCS
165 char *last_pos
= compile(rx
, buf
, &buf
[blen
], '\0');
167 #else /* HAVE_REGEXPR_H_FUNCS */
168 char *last_pos
= compile(rx
, buf
, &buf
[blen
]);
174 blen
+= RX_INCREMENT
;
184 pArg
->compiled_expression
= buf
;
189 while (blen
<= MAX_RX_LEN
);
191 if (pArg
&& !pArg
->compiled_expression
)
203 /*---------------------------------------------------------------------------
204 | Facility : libnform
205 | Function : static void *Make_RegularExpression_Type(va_list * ap)
207 | Description : Allocate structure for regex type argument.
209 | Return Values : Pointer to argument structure or NULL on error
210 +--------------------------------------------------------------------------*/
212 Make_RegularExpression_Type(va_list *ap
)
214 char *rx
= va_arg(*ap
, char *);
216 return Generic_RegularExpression_Type((void *)rx
);
219 /*---------------------------------------------------------------------------
220 | Facility : libnform
221 | Function : static void *Copy_RegularExpression_Type(
224 | Description : Copy structure for regex type argument.
226 | Return Values : Pointer to argument structure or NULL on error.
227 +--------------------------------------------------------------------------*/
229 Copy_RegularExpression_Type(const void *argp MAYBE_UNUSED
)
231 #if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS)
232 const RegExp_Arg
*ap
= (const RegExp_Arg
*)argp
;
233 const RegExp_Arg
*result
= (const RegExp_Arg
*)0;
237 *(ap
->refCount
) += 1;
240 return (void *)result
;
246 /*---------------------------------------------------------------------------
247 | Facility : libnform
248 | Function : static void Free_RegularExpression_Type(void * argp)
250 | Description : Free structure for regex type argument.
253 +--------------------------------------------------------------------------*/
255 Free_RegularExpression_Type(void *argp MAYBE_UNUSED
)
257 #if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
258 RegExp_Arg
*ap
= (RegExp_Arg
*)argp
;
262 if (--(*(ap
->refCount
)) == 0)
264 #if HAVE_REGEX_H_FUNCS
268 regfree(ap
->pRegExp
);
270 #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
271 if (ap
->compiled_expression
)
274 free(ap
->compiled_expression
);
283 /*---------------------------------------------------------------------------
284 | Facility : libnform
285 | Function : static bool Check_RegularExpression_Field(
289 | Description : Validate buffer content to be a valid regular expression
291 | Return Values : TRUE - field is valid
292 | FALSE - field is invalid
293 +--------------------------------------------------------------------------*/
295 Check_RegularExpression_Field(FIELD
*field MAYBE_UNUSED
,
296 const void *argp MAYBE_UNUSED
)
300 #if HAVE_REGEX_H_FUNCS
301 const RegExp_Arg
*ap
= (const RegExp_Arg
*)argp
;
303 if (ap
&& ap
->pRegExp
)
304 match
= (regexec(ap
->pRegExp
, field_buffer(field
, 0), 0, NULL
, 0)
307 #elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
308 RegExp_Arg
*ap
= (RegExp_Arg
*)argp
;
310 if (ap
&& ap
->compiled_expression
)
311 match
= (step(field_buffer(field
, 0), ap
->compiled_expression
)
318 static FIELDTYPE typeREGEXP
=
320 _HAS_ARGS
| _RESIDENT
,
321 1, /* this is mutable, so we can't be const */
324 Make_RegularExpression_Type
,
325 Copy_RegularExpression_Type
,
326 Free_RegularExpression_Type
,
327 INIT_FT_FUNC(Check_RegularExpression_Field
),
331 #if NCURSES_INTEROP_FUNCS
332 Generic_RegularExpression_Type
336 NCURSES_EXPORT_VAR(FIELDTYPE
*) TYPE_REGEXP
= &typeREGEXP
;
338 #if NCURSES_INTEROP_FUNCS
339 /* The next routines are to simplify the use of ncurses from
340 programming languages with restictions on interop with C level
341 constructs (e.g. variable access or va_list + ellipsis constructs)
343 NCURSES_EXPORT(FIELDTYPE
*)
344 _nc_TYPE_REGEXP(void)
350 /* fty_regex.c ends here */