1166124Srafan/**************************************************************************** 2174993Srafan * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * 3166124Srafan * * 4166124Srafan * Permission is hereby granted, free of charge, to any person obtaining a * 5166124Srafan * copy of this software and associated documentation files (the * 6166124Srafan * "Software"), to deal in the Software without restriction, including * 7166124Srafan * without limitation the rights to use, copy, modify, merge, publish, * 8166124Srafan * distribute, distribute with modifications, sublicense, and/or sell * 9166124Srafan * copies of the Software, and to permit persons to whom the Software is * 10166124Srafan * furnished to do so, subject to the following conditions: * 11166124Srafan * * 12166124Srafan * The above copyright notice and this permission notice shall be included * 13166124Srafan * in all copies or substantial portions of the Software. * 14166124Srafan * * 15166124Srafan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16166124Srafan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17166124Srafan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18166124Srafan * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19166124Srafan * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20166124Srafan * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21166124Srafan * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22166124Srafan * * 23166124Srafan * Except as contained in this notice, the name(s) of the above copyright * 24166124Srafan * holders shall not be used in advertising or otherwise to promote the * 25166124Srafan * sale, use or other dealings in this Software without prior written * 26166124Srafan * authorization. * 27166124Srafan ****************************************************************************/ 2850276Speter 2950276Speter/*************************************************************************** 3050276Speter* * 31166124Srafan* Author : Juergen Pfeifer * 3250276Speter* * 3350276Speter***************************************************************************/ 3450276Speter 3550276Speter#include "form.priv.h" 3650276Speter 37174993SrafanMODULE_ID("$Id: fty_regex.c,v 1.21 2007/10/13 19:33:50 tom Exp $") 3850276Speter 39166124Srafan#if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */ 4050276Speter#include <regex.h> 4150276Speter 4250276Spetertypedef struct 43166124Srafan { 44166124Srafan regex_t *pRegExp; 45166124Srafan unsigned long *refCount; 46166124Srafan } 47166124SrafanRegExp_Arg; 4850276Speter 4950276Speter#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 5050276Speter#undef RETURN 5150276Speterstatic int reg_errno; 5250276Speter 53166124Srafanstatic char * 54166124SrafanRegEx_Init(char *instring) 5550276Speter{ 56166124Srafan reg_errno = 0; 57166124Srafan return instring; 5850276Speter} 5950276Speter 60166124Srafanstatic char * 61166124SrafanRegEx_Error(int code) 6250276Speter{ 63166124Srafan reg_errno = code; 64166124Srafan return 0; 6550276Speter} 6650276Speter 6750276Speter#define INIT register char *sp = RegEx_Init(instring); 6850276Speter#define GETC() (*sp++) 6950276Speter#define PEEKC() (*sp) 7050276Speter#define UNGETC(c) (--sp) 7150276Speter#define RETURN(c) return(c) 7250276Speter#define ERROR(c) return RegEx_Error(c) 7350276Speter 7450276Speter#if HAVE_REGEXP_H_FUNCS 7550276Speter#include <regexp.h> 7650276Speter#else 7750276Speter#include <regexpr.h> 7850276Speter#endif 7950276Speter 8050276Spetertypedef struct 8150276Speter{ 8250276Speter char *compiled_expression; 8350276Speter unsigned long *refCount; 84166124Srafan} 85166124SrafanRegExp_Arg; 8650276Speter 8750276Speter/* Maximum Length we allow for a compiled regular expression */ 8850276Speter#define MAX_RX_LEN (2048) 8950276Speter#define RX_INCREMENT (256) 9050276Speter 9150276Speter#endif 9250276Speter 9350276Speter/*--------------------------------------------------------------------------- 9450276Speter| Facility : libnform 9550276Speter| Function : static void *Make_RegularExpression_Type(va_list * ap) 9650276Speter| 9750276Speter| Description : Allocate structure for regex type argument. 9850276Speter| 9950276Speter| Return Values : Pointer to argument structure or NULL on error 10050276Speter+--------------------------------------------------------------------------*/ 101166124Srafanstatic void * 102166124SrafanMake_RegularExpression_Type(va_list *ap) 10350276Speter{ 10450276Speter#if HAVE_REGEX_H_FUNCS 105166124Srafan char *rx = va_arg(*ap, char *); 10650276Speter RegExp_Arg *preg; 10750276Speter 108174993Srafan preg = typeMalloc(RegExp_Arg, 1); 109166124Srafan 11050276Speter if (preg) 11150276Speter { 112174993Srafan T((T_CREATE("RegExp_Arg %p"), preg)); 113174993Srafan if (((preg->pRegExp = typeMalloc(regex_t, 1)) != 0) 114166124Srafan && !regcomp(preg->pRegExp, rx, 115166124Srafan (REG_EXTENDED | REG_NOSUB | REG_NEWLINE))) 11650276Speter { 117174993Srafan T((T_CREATE("regex_t %p"), preg->pRegExp)); 118174993Srafan preg->refCount = typeMalloc(unsigned long, 1); 119166124Srafan 12050276Speter *(preg->refCount) = 1; 12150276Speter } 12250276Speter else 12350276Speter { 12450276Speter if (preg->pRegExp) 12550276Speter free(preg->pRegExp); 12650276Speter free(preg); 127166124Srafan preg = (RegExp_Arg *)0; 12850276Speter } 12950276Speter } 130166124Srafan return ((void *)preg); 13150276Speter#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 132166124Srafan char *rx = va_arg(*ap, char *); 13350276Speter RegExp_Arg *pArg; 13450276Speter 135174993Srafan pArg = typeMalloc(RegExp_Arg, 1); 13650276Speter 13750276Speter if (pArg) 13850276Speter { 13950276Speter int blen = RX_INCREMENT; 140166124Srafan 141174993Srafan T((T_CREATE("RegExp_Arg %p"), pArg)); 14250276Speter pArg->compiled_expression = NULL; 143174993Srafan pArg->refCount = typeMalloc(unsigned long, 1); 144166124Srafan 14550276Speter *(pArg->refCount) = 1; 14650276Speter 147166124Srafan do 148166124Srafan { 149174993Srafan char *buf = typeMalloc(char, blen); 150166124Srafan 151166124Srafan if (buf) 152166124Srafan { 15350276Speter#if HAVE_REGEXP_H_FUNCS 154166124Srafan char *last_pos = compile(rx, buf, &buf[blen], '\0'); 155166124Srafan 15650276Speter#else /* HAVE_REGEXPR_H_FUNCS */ 157166124Srafan char *last_pos = compile(rx, buf, &buf[blen]); 15850276Speter#endif 159166124Srafan if (reg_errno) 160166124Srafan { 161166124Srafan free(buf); 162166124Srafan if (reg_errno == 50) 163166124Srafan blen += RX_INCREMENT; 164166124Srafan else 165166124Srafan { 166166124Srafan free(pArg); 167166124Srafan pArg = NULL; 168166124Srafan break; 169166124Srafan } 170166124Srafan } 171166124Srafan else 172166124Srafan { 173166124Srafan pArg->compiled_expression = buf; 174166124Srafan break; 175166124Srafan } 176166124Srafan } 177166124Srafan } 178166124Srafan while (blen <= MAX_RX_LEN); 17950276Speter } 18050276Speter if (pArg && !pArg->compiled_expression) 18150276Speter { 18250276Speter free(pArg); 18350276Speter pArg = NULL; 18450276Speter } 18550276Speter return (void *)pArg; 18650276Speter#else 18750276Speter return 0; 18850276Speter#endif 18950276Speter} 19050276Speter 19150276Speter/*--------------------------------------------------------------------------- 19250276Speter| Facility : libnform 19350276Speter| Function : static void *Copy_RegularExpression_Type( 19450276Speter| const void * argp) 19550276Speter| 19650276Speter| Description : Copy structure for regex type argument. 19750276Speter| 19850276Speter| Return Values : Pointer to argument structure or NULL on error. 19950276Speter+--------------------------------------------------------------------------*/ 200166124Srafanstatic void * 201166124SrafanCopy_RegularExpression_Type(const void *argp) 20250276Speter{ 20350276Speter#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS) 20450276Speter const RegExp_Arg *ap = (const RegExp_Arg *)argp; 20550276Speter const RegExp_Arg *result = (const RegExp_Arg *)0; 20650276Speter 20750276Speter if (ap) 20850276Speter { 20950276Speter *(ap->refCount) += 1; 21050276Speter result = ap; 21150276Speter } 21250276Speter return (void *)result; 21350276Speter#else 21450276Speter return 0; 21550276Speter#endif 21650276Speter} 21750276Speter 21850276Speter/*--------------------------------------------------------------------------- 21950276Speter| Facility : libnform 22050276Speter| Function : static void Free_RegularExpression_Type(void * argp) 22150276Speter| 22250276Speter| Description : Free structure for regex type argument. 22350276Speter| 22450276Speter| Return Values : - 22550276Speter+--------------------------------------------------------------------------*/ 226166124Srafanstatic void 227166124SrafanFree_RegularExpression_Type(void *argp) 22850276Speter{ 22950276Speter#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 23050276Speter RegExp_Arg *ap = (RegExp_Arg *)argp; 231166124Srafan 23250276Speter if (ap) 23350276Speter { 23450276Speter if (--(*(ap->refCount)) == 0) 23550276Speter { 23650276Speter#if HAVE_REGEX_H_FUNCS 23750276Speter if (ap->pRegExp) 23850276Speter { 23950276Speter free(ap->refCount); 24050276Speter regfree(ap->pRegExp); 24150276Speter } 24250276Speter#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 24350276Speter if (ap->compiled_expression) 24450276Speter { 24550276Speter free(ap->refCount); 24650276Speter free(ap->compiled_expression); 24750276Speter } 24850276Speter#endif 24950276Speter free(ap); 25050276Speter } 25150276Speter } 25250276Speter#endif 25350276Speter} 25450276Speter 25550276Speter/*--------------------------------------------------------------------------- 25650276Speter| Facility : libnform 25750276Speter| Function : static bool Check_RegularExpression_Field( 25850276Speter| FIELD * field, 25950276Speter| const void * argp) 26050276Speter| 26150276Speter| Description : Validate buffer content to be a valid regular expression 26250276Speter| 26350276Speter| Return Values : TRUE - field is valid 26450276Speter| FALSE - field is invalid 26550276Speter+--------------------------------------------------------------------------*/ 266166124Srafanstatic bool 267166124SrafanCheck_RegularExpression_Field(FIELD *field, const void *argp) 26850276Speter{ 26950276Speter bool match = FALSE; 270166124Srafan 27150276Speter#if HAVE_REGEX_H_FUNCS 272166124Srafan const RegExp_Arg *ap = (const RegExp_Arg *)argp; 273166124Srafan 27450276Speter if (ap && ap->pRegExp) 275166124Srafan match = (regexec(ap->pRegExp, field_buffer(field, 0), 0, NULL, 0) 276166124Srafan ? FALSE 277166124Srafan : TRUE); 27850276Speter#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 27950276Speter RegExp_Arg *ap = (RegExp_Arg *)argp; 280166124Srafan 28150276Speter if (ap && ap->compiled_expression) 282166124Srafan match = (step(field_buffer(field, 0), ap->compiled_expression) 283166124Srafan ? TRUE 284166124Srafan : FALSE); 28550276Speter#endif 28650276Speter return match; 28750276Speter} 28850276Speter 289166124Srafanstatic FIELDTYPE typeREGEXP = 290166124Srafan{ 29150276Speter _HAS_ARGS | _RESIDENT, 292166124Srafan 1, /* this is mutable, so we can't be const */ 29350276Speter (FIELDTYPE *)0, 29450276Speter (FIELDTYPE *)0, 29550276Speter Make_RegularExpression_Type, 29650276Speter Copy_RegularExpression_Type, 29750276Speter Free_RegularExpression_Type, 29850276Speter Check_RegularExpression_Field, 29950276Speter NULL, 30050276Speter NULL, 30150276Speter NULL 30250276Speter}; 30350276Speter 30476726SpeterNCURSES_EXPORT_VAR(FIELDTYPE*) TYPE_REGEXP = &typeREGEXP; 30550276Speter 30650276Speter/* fty_regex.c ends here */ 307