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