fty_regex.c revision 50276
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, juergen.pfeifer@gmx.net * 11* * 12***************************************************************************/ 13 14#include "form.priv.h" 15 16MODULE_ID("$Id: fty_regex.c,v 1.14 1999/05/16 17:23:38 juergen 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} RegExp_Arg; 26 27#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 28#undef RETURN 29static int reg_errno; 30 31static char *RegEx_Init(char *instring) 32{ 33 reg_errno = 0; 34 return instring; 35} 36 37static char *RegEx_Error(int code) 38{ 39 reg_errno = code; 40 return 0; 41} 42 43#define INIT register char *sp = RegEx_Init(instring); 44#define GETC() (*sp++) 45#define PEEKC() (*sp) 46#define UNGETC(c) (--sp) 47#define RETURN(c) return(c) 48#define ERROR(c) return RegEx_Error(c) 49 50#if HAVE_REGEXP_H_FUNCS 51#include <regexp.h> 52#else 53#include <regexpr.h> 54#endif 55 56typedef struct 57{ 58 char *compiled_expression; 59 unsigned long *refCount; 60} RegExp_Arg; 61 62/* Maximum Length we allow for a compiled regular expression */ 63#define MAX_RX_LEN (2048) 64#define RX_INCREMENT (256) 65 66#endif 67 68/*--------------------------------------------------------------------------- 69| Facility : libnform 70| Function : static void *Make_RegularExpression_Type(va_list * ap) 71| 72| Description : Allocate structure for regex type argument. 73| 74| Return Values : Pointer to argument structure or NULL on error 75+--------------------------------------------------------------------------*/ 76static void *Make_RegularExpression_Type(va_list * ap) 77{ 78#if HAVE_REGEX_H_FUNCS 79 char *rx = va_arg(*ap,char *); 80 RegExp_Arg *preg; 81 82 preg = (RegExp_Arg*)malloc(sizeof(RegExp_Arg)); 83 if (preg) 84 { 85 if (((preg->pRegExp = (regex_t*)malloc(sizeof(regex_t))) != (regex_t*)0) 86 && !regcomp(preg->pRegExp,rx, 87 (REG_EXTENDED | REG_NOSUB | REG_NEWLINE) )) 88 { 89 preg->refCount = (unsigned long *)malloc(sizeof(unsigned long)); 90 *(preg->refCount) = 1; 91 } 92 else 93 { 94 if (preg->pRegExp) 95 free(preg->pRegExp); 96 free(preg); 97 preg = (RegExp_Arg*)0; 98 } 99 } 100 return((void *)preg); 101#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 102 char *rx = va_arg(*ap,char *); 103 RegExp_Arg *pArg; 104 105 pArg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg)); 106 107 if (pArg) 108 { 109 int blen = RX_INCREMENT; 110 pArg->compiled_expression = NULL; 111 pArg->refCount = (unsigned long *)malloc(sizeof(unsigned long)); 112 *(pArg->refCount) = 1; 113 114 do { 115 char *buf = (char *)malloc(blen); 116 if (buf) 117 { 118#if HAVE_REGEXP_H_FUNCS 119 char *last_pos = compile (rx, buf, &buf[blen], '\0'); 120#else /* HAVE_REGEXPR_H_FUNCS */ 121 char *last_pos = compile (rx, buf, &buf[blen]); 122#endif 123 if (reg_errno) 124 { 125 free(buf); 126 if (reg_errno==50) 127 blen += RX_INCREMENT; 128 else 129 { 130 free(pArg); 131 pArg = NULL; 132 break; 133 } 134 } 135 else 136 { 137 pArg->compiled_expression = buf; 138 break; 139 } 140 } 141 } while( blen <= MAX_RX_LEN ); 142 } 143 if (pArg && !pArg->compiled_expression) 144 { 145 free(pArg); 146 pArg = NULL; 147 } 148 return (void *)pArg; 149#else 150 return 0; 151#endif 152} 153 154/*--------------------------------------------------------------------------- 155| Facility : libnform 156| Function : static void *Copy_RegularExpression_Type( 157| const void * argp) 158| 159| Description : Copy structure for regex type argument. 160| 161| Return Values : Pointer to argument structure or NULL on error. 162+--------------------------------------------------------------------------*/ 163static void *Copy_RegularExpression_Type(const void * argp) 164{ 165#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS) 166 const RegExp_Arg *ap = (const RegExp_Arg *)argp; 167 const RegExp_Arg *result = (const RegExp_Arg *)0; 168 169 if (ap) 170 { 171 *(ap->refCount) += 1; 172 result = ap; 173 } 174 return (void *)result; 175#else 176 return 0; 177#endif 178} 179 180/*--------------------------------------------------------------------------- 181| Facility : libnform 182| Function : static void Free_RegularExpression_Type(void * argp) 183| 184| Description : Free structure for regex type argument. 185| 186| Return Values : - 187+--------------------------------------------------------------------------*/ 188static void Free_RegularExpression_Type(void * argp) 189{ 190#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 191 RegExp_Arg *ap = (RegExp_Arg *)argp; 192 if (ap) 193 { 194 if (--(*(ap->refCount)) == 0) 195 { 196#if HAVE_REGEX_H_FUNCS 197 if (ap->pRegExp) 198 { 199 free(ap->refCount); 200 regfree(ap->pRegExp); 201 } 202#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 203 if (ap->compiled_expression) 204 { 205 free(ap->refCount); 206 free(ap->compiled_expression); 207 } 208#endif 209 free(ap); 210 } 211 } 212#endif 213} 214 215/*--------------------------------------------------------------------------- 216| Facility : libnform 217| Function : static bool Check_RegularExpression_Field( 218| FIELD * field, 219| const void * argp) 220| 221| Description : Validate buffer content to be a valid regular expression 222| 223| Return Values : TRUE - field is valid 224| FALSE - field is invalid 225+--------------------------------------------------------------------------*/ 226static bool Check_RegularExpression_Field(FIELD * field, const void * argp) 227{ 228 bool match = FALSE; 229#if HAVE_REGEX_H_FUNCS 230 const RegExp_Arg *ap = (const RegExp_Arg*)argp; 231 if (ap && ap->pRegExp) 232 match = (regexec(ap->pRegExp,field_buffer(field,0),0,NULL,0) ? FALSE:TRUE); 233#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS 234 RegExp_Arg *ap = (RegExp_Arg *)argp; 235 if (ap && ap->compiled_expression) 236 match = (step(field_buffer(field,0),ap->compiled_expression) ? TRUE:FALSE); 237#endif 238 return match; 239} 240 241static FIELDTYPE typeREGEXP = { 242 _HAS_ARGS | _RESIDENT, 243 1, /* this is mutable, so we can't be const */ 244 (FIELDTYPE *)0, 245 (FIELDTYPE *)0, 246 Make_RegularExpression_Type, 247 Copy_RegularExpression_Type, 248 Free_RegularExpression_Type, 249 Check_RegularExpression_Field, 250 NULL, 251 NULL, 252 NULL 253}; 254 255FIELDTYPE* TYPE_REGEXP = &typeREGEXP; 256 257/* fty_regex.c ends here */ 258