1 /* $NetBSD: regex.c,v 1.3 2014/10/30 18:44:05 christos Exp $ */
3 /** regex - regular expression functions related to POSIX regex lib. */
5 /* This file is part of flex. */
7 /* Redistribution and use in source and binary forms, with or without */
8 /* modification, are permitted provided that the following conditions */
11 /* 1. Redistributions of source code must retain the above copyright */
12 /* notice, this list of conditions and the following disclaimer. */
13 /* 2. Redistributions in binary form must reproduce the above copyright */
14 /* notice, this list of conditions and the following disclaimer in the */
15 /* documentation and/or other materials provided with the distribution. */
17 /* Neither the name of the University nor the names of its contributors */
18 /* may be used to endorse or promote products derived from this software */
19 /* without specific prior written permission. */
21 /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
22 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
23 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
26 __RCSID("$NetBSD: regex.c,v 1.3 2014/10/30 18:44:05 christos Exp $");
28 static const char* REGEXP_LINEDIR
= "^#line ([[:digit:]]+) \"(.*)\"";
29 static const char* REGEXP_BLANK_LINE
= "^[[:space:]]*$";
31 regex_t regex_linedir
; /**< matches line directives */
32 regex_t regex_blank_line
; /**< matches blank lines */
35 /** Initialize the regular expressions.
36 * @return true upon success.
38 bool flex_init_regex(void)
40 flex_regcomp(®ex_linedir
, REGEXP_LINEDIR
, REG_EXTENDED
);
41 flex_regcomp(®ex_blank_line
, REGEXP_BLANK_LINE
, REG_EXTENDED
);
46 /** Compiles a regular expression or dies trying.
47 * @param preg Same as for regcomp().
48 * @param regex Same as for regcomp().
49 * @param cflags Same as for regcomp().
51 void flex_regcomp(regex_t
*preg
, const char *regex
, int cflags
)
55 memset (preg
, 0, sizeof (regex_t
));
57 if ((err
= regcomp (preg
, regex
, cflags
)) != 0) {
58 const int errbuf_sz
= 200;
61 errbuf
= (char*)flex_alloc(errbuf_sz
*sizeof(char));
63 flexfatal(_("Unable to allocate buffer to report regcomp"));
64 rxerr
= (char*)flex_alloc(errbuf_sz
*sizeof(char));
66 flexfatal(_("Unable to allocate buffer for regerror"));
67 regerror (err
, preg
, rxerr
, errbuf_sz
);
68 snprintf (errbuf
, errbuf_sz
, "regcomp for \"%s\" failed: %s", regex
, rxerr
);
76 /** Extract a copy of the match, or NULL if no match.
77 * @param m A match as returned by regexec().
78 * @param src The source string that was passed to regexec().
79 * @return The allocated string.
81 char *regmatch_dup (regmatch_t
* m
, const char *src
)
86 if (m
== NULL
|| m
->rm_so
< 0)
88 len
= m
->rm_eo
- m
->rm_so
;
89 str
= (char *) flex_alloc ((len
+ 1) * sizeof (char));
91 flexfatal(_("Unable to allocate a copy of the match"));
92 strncpy (str
, src
+ m
->rm_so
, len
);
98 * @param m A match as returned by regexec().
99 * @param dest The destination buffer.
100 * @param src The source string that was passed to regexec().
103 char *regmatch_cpy (regmatch_t
* m
, char *dest
, const char *src
)
105 if (m
== NULL
|| m
->rm_so
< 0) {
111 snprintf (dest
, regmatch_len(m
), "%s", src
+ m
->rm_so
);
115 /** Get the length in characters of the match.
116 * @param m A match as returned by regexec().
117 * @param src The source string that was passed to regexec().
118 * @return The length of the match.
120 int regmatch_len (regmatch_t
* m
)
122 if (m
== NULL
|| m
->rm_so
< 0) {
126 return m
->rm_eo
- m
->rm_so
;
131 /** Convert a regmatch_t object to an integer using the strtol() function.
132 * @param m A match as returned by regexec().
133 * @param src The source string that was passed to regexec().
134 * @param endptr Same as the second argument to strtol().
135 * @param base Same as the third argument to strtol().
136 * @return The converted integer or error (Return value is the same as for strtol()).
138 int regmatch_strtol (regmatch_t
* m
, const char *src
, char **endptr
,
147 if (m
== NULL
|| m
->rm_so
< 0)
150 if (regmatch_len (m
) < bufsz
)
151 s
= regmatch_cpy (m
, buf
, src
);
153 s
= regmatch_dup (m
, src
);
155 n
= strtol (s
, endptr
, base
);
163 /** Check for empty or non-existent match.
164 * @param m A match as returned by regexec().
165 * @return false if match length is non-zero.
166 * Note that reg_empty returns true even if match did not occur at all.
168 bool regmatch_empty (regmatch_t
* m
)
170 return (m
== NULL
|| m
->rm_so
< 0 || m
->rm_so
== m
->rm_eo
);
173 /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */