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 16 MODULE_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 21 typedef 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 29 static int reg_errno; 30 31 static char *RegEx_Init(char *instring) 32 { 33 reg_errno = 0; 34 return instring; 35 } 36 37 static 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 56 typedef 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 +--------------------------------------------------------------------------*/ 76 static 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 +--------------------------------------------------------------------------*/ 163 static 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 +--------------------------------------------------------------------------*/ 188 static 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 +--------------------------------------------------------------------------*/ 226 static 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 241 static 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 255 FIELDTYPE* TYPE_REGEXP = &typeREGEXP; 256 257 /* fty_regex.c ends here */ 258