1*c30b89acSMasatake YAMATO /*
2*c30b89acSMasatake YAMATO * Copyright (c) 2000-2003, Darren Hiebert
3*c30b89acSMasatake YAMATO *
4*c30b89acSMasatake YAMATO * This source code is released for free distribution under the terms of the
5*c30b89acSMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
6*c30b89acSMasatake YAMATO *
7*c30b89acSMasatake YAMATO * This module contains functions for applying regular expression matching.
8*c30b89acSMasatake YAMATO *
9*c30b89acSMasatake YAMATO * The code for utilizing the Gnu regex package with regards to processing the
10*c30b89acSMasatake YAMATO * regex option and checking for regex matches was adapted from routines in
11*c30b89acSMasatake YAMATO * Gnu etags.
12*c30b89acSMasatake YAMATO */
13*c30b89acSMasatake YAMATO
14*c30b89acSMasatake YAMATO /*
15*c30b89acSMasatake YAMATO * INCLUDE FILES
16*c30b89acSMasatake YAMATO */
17*c30b89acSMasatake YAMATO #include "general.h" /* must always come first */
18*c30b89acSMasatake YAMATO
19*c30b89acSMasatake YAMATO #include <regex.h>
20*c30b89acSMasatake YAMATO #include "lregex_p.h"
21*c30b89acSMasatake YAMATO
22*c30b89acSMasatake YAMATO /*
23*c30b89acSMasatake YAMATO * FUNCTION DECLARATIONS
24*c30b89acSMasatake YAMATO */
25*c30b89acSMasatake YAMATO static int match (struct regexBackend *backend,
26*c30b89acSMasatake YAMATO void *code, const char *input, size_t size,
27*c30b89acSMasatake YAMATO regmatch_t pmatch[BACK_REFERENCE_COUNT]);
28*c30b89acSMasatake YAMATO static regexCompiledCode compile (struct regexBackend *backend,
29*c30b89acSMasatake YAMATO const char *const regexp,
30*c30b89acSMasatake YAMATO int flags);
31*c30b89acSMasatake YAMATO static void delete_code (void *code);
32*c30b89acSMasatake YAMATO static void set_icase_flag (int *flags);
33*c30b89acSMasatake YAMATO
34*c30b89acSMasatake YAMATO /*
35*c30b89acSMasatake YAMATO * DATA DEFINITIONS
36*c30b89acSMasatake YAMATO */
37*c30b89acSMasatake YAMATO static struct regexBackend defaultRegexBackend = {
38*c30b89acSMasatake YAMATO .fdefs = NULL,
39*c30b89acSMasatake YAMATO .fdef_count = 0,
40*c30b89acSMasatake YAMATO .set_icase_flag = set_icase_flag,
41*c30b89acSMasatake YAMATO .compile = compile,
42*c30b89acSMasatake YAMATO .match = match,
43*c30b89acSMasatake YAMATO .delete_code = delete_code,
44*c30b89acSMasatake YAMATO };
45*c30b89acSMasatake YAMATO
46*c30b89acSMasatake YAMATO /*
47*c30b89acSMasatake YAMATO * FUNCTOIN DEFINITIONS
48*c30b89acSMasatake YAMATO */
basic_regex_flag_short(char c,void * data)49*c30b89acSMasatake YAMATO extern void basic_regex_flag_short (char c, void* data)
50*c30b89acSMasatake YAMATO {
51*c30b89acSMasatake YAMATO struct flagDefsDescriptor *desc = data;
52*c30b89acSMasatake YAMATO
53*c30b89acSMasatake YAMATO if (desc->backend)
54*c30b89acSMasatake YAMATO error (FATAL, "regex backed is specified twice: %c", c);
55*c30b89acSMasatake YAMATO
56*c30b89acSMasatake YAMATO desc->backend = &defaultRegexBackend;
57*c30b89acSMasatake YAMATO desc->flags = (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;
58*c30b89acSMasatake YAMATO }
59*c30b89acSMasatake YAMATO
basic_regex_flag_long(const char * const s,const char * const unused CTAGS_ATTR_UNUSED,void * data)60*c30b89acSMasatake YAMATO extern void basic_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)
61*c30b89acSMasatake YAMATO {
62*c30b89acSMasatake YAMATO struct flagDefsDescriptor *desc = data;
63*c30b89acSMasatake YAMATO
64*c30b89acSMasatake YAMATO if (desc->backend)
65*c30b89acSMasatake YAMATO error (FATAL, "regex backed is specified twice: %s", s);
66*c30b89acSMasatake YAMATO
67*c30b89acSMasatake YAMATO basic_regex_flag_short ('b', data);
68*c30b89acSMasatake YAMATO }
69*c30b89acSMasatake YAMATO
extend_regex_flag_short(char c,void * data)70*c30b89acSMasatake YAMATO extern void extend_regex_flag_short (char c, void* data)
71*c30b89acSMasatake YAMATO {
72*c30b89acSMasatake YAMATO struct flagDefsDescriptor *desc = data;
73*c30b89acSMasatake YAMATO
74*c30b89acSMasatake YAMATO if (desc->backend)
75*c30b89acSMasatake YAMATO error (FATAL, "regex backed is specified twice: %c", c);
76*c30b89acSMasatake YAMATO
77*c30b89acSMasatake YAMATO desc->backend = &defaultRegexBackend;
78*c30b89acSMasatake YAMATO desc->flags = REG_EXTENDED;
79*c30b89acSMasatake YAMATO desc->flags |= (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;
80*c30b89acSMasatake YAMATO }
81*c30b89acSMasatake YAMATO
extend_regex_flag_long(const char * const s,const char * const unused CTAGS_ATTR_UNUSED,void * data)82*c30b89acSMasatake YAMATO extern void extend_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)
83*c30b89acSMasatake YAMATO {
84*c30b89acSMasatake YAMATO struct flagDefsDescriptor *desc = data;
85*c30b89acSMasatake YAMATO
86*c30b89acSMasatake YAMATO if (desc->backend)
87*c30b89acSMasatake YAMATO error (FATAL, "regex backed is specified twice: %s", s);
88*c30b89acSMasatake YAMATO
89*c30b89acSMasatake YAMATO extend_regex_flag_short('e', data);
90*c30b89acSMasatake YAMATO }
91*c30b89acSMasatake YAMATO
delete_code(void * code)92*c30b89acSMasatake YAMATO static void delete_code (void *code)
93*c30b89acSMasatake YAMATO {
94*c30b89acSMasatake YAMATO regex_t *regex_code = code;
95*c30b89acSMasatake YAMATO regfree (regex_code);
96*c30b89acSMasatake YAMATO eFree (regex_code);
97*c30b89acSMasatake YAMATO }
98*c30b89acSMasatake YAMATO
compile(struct regexBackend * backend,const char * const regexp,int flags)99*c30b89acSMasatake YAMATO static regexCompiledCode compile (struct regexBackend *backend,
100*c30b89acSMasatake YAMATO const char *const regexp,
101*c30b89acSMasatake YAMATO int flags)
102*c30b89acSMasatake YAMATO {
103*c30b89acSMasatake YAMATO regex_t *regex_code = xMalloc (1, regex_t);
104*c30b89acSMasatake YAMATO int errcode = regcomp (regex_code, regexp, flags);
105*c30b89acSMasatake YAMATO if (errcode != 0)
106*c30b89acSMasatake YAMATO {
107*c30b89acSMasatake YAMATO char errmsg[256];
108*c30b89acSMasatake YAMATO regerror (errcode, regex_code, errmsg, 256);
109*c30b89acSMasatake YAMATO error (WARNING, "regcomp: %s", errmsg);
110*c30b89acSMasatake YAMATO regfree (regex_code);
111*c30b89acSMasatake YAMATO eFree (regex_code);
112*c30b89acSMasatake YAMATO return (regexCompiledCode) { .backend = NULL, .code = NULL };
113*c30b89acSMasatake YAMATO }
114*c30b89acSMasatake YAMATO return (regexCompiledCode) { .backend = &defaultRegexBackend, .code = regex_code };
115*c30b89acSMasatake YAMATO }
116*c30b89acSMasatake YAMATO
match(struct regexBackend * backend,void * code,const char * input,size_t size CTAGS_ATTR_UNUSED,regmatch_t pmatch[BACK_REFERENCE_COUNT])117*c30b89acSMasatake YAMATO static int match (struct regexBackend *backend,
118*c30b89acSMasatake YAMATO void *code, const char *input, size_t size CTAGS_ATTR_UNUSED,
119*c30b89acSMasatake YAMATO regmatch_t pmatch[BACK_REFERENCE_COUNT])
120*c30b89acSMasatake YAMATO {
121*c30b89acSMasatake YAMATO return regexec ((regex_t *)code, input, BACK_REFERENCE_COUNT, pmatch, 0);
122*c30b89acSMasatake YAMATO }
123*c30b89acSMasatake YAMATO
set_icase_flag(int * flags)124*c30b89acSMasatake YAMATO static void set_icase_flag (int *flags)
125*c30b89acSMasatake YAMATO {
126*c30b89acSMasatake YAMATO *flags |= REG_ICASE;
127*c30b89acSMasatake YAMATO }
128