Deleted Added
full compact
regex.c (228072) regex.c (250125)
1/** regex - regular expression functions related to POSIX regex lib. */
2
3/* This file is part of flex. */
4
5/* Redistribution and use in source and binary forms, with or without */
6/* modification, are permitted provided that the following conditions */
7/* are met: */
8
9/* 1. Redistributions of source code must retain the above copyright */
10/* notice, this list of conditions and the following disclaimer. */
11/* 2. Redistributions in binary form must reproduce the above copyright */
12/* notice, this list of conditions and the following disclaimer in the */
13/* documentation and/or other materials provided with the distribution. */
14
15/* Neither the name of the University nor the names of its contributors */
16/* may be used to endorse or promote products derived from this software */
17/* without specific prior written permission. */
18
19/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
20/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
21/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
22/* PURPOSE. */
23
24#include "flexdef.h"
25
26
27static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
28static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$";
29
30regex_t regex_linedir; /**< matches line directives */
31regex_t regex_blank_line; /**< matches blank lines */
32
33
34/** Initialize the regular expressions.
35 * @return true upon success.
36 */
37bool flex_init_regex(void)
38{
39 flex_regcomp(&regex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
40 flex_regcomp(&regex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED);
41
42 return true;
43}
44
45/** Compiles a regular expression or dies trying.
46 * @param preg Same as for regcomp().
47 * @param regex Same as for regcomp().
48 * @param cflags Same as for regcomp().
49 */
50void flex_regcomp(regex_t *preg, const char *regex, int cflags)
51{
52 int err;
53
54 memset (preg, 0, sizeof (regex_t));
55
56 if ((err = regcomp (preg, regex, cflags)) != 0) {
57 const int errbuf_sz = 200;
1/** regex - regular expression functions related to POSIX regex lib. */
2
3/* This file is part of flex. */
4
5/* Redistribution and use in source and binary forms, with or without */
6/* modification, are permitted provided that the following conditions */
7/* are met: */
8
9/* 1. Redistributions of source code must retain the above copyright */
10/* notice, this list of conditions and the following disclaimer. */
11/* 2. Redistributions in binary form must reproduce the above copyright */
12/* notice, this list of conditions and the following disclaimer in the */
13/* documentation and/or other materials provided with the distribution. */
14
15/* Neither the name of the University nor the names of its contributors */
16/* may be used to endorse or promote products derived from this software */
17/* without specific prior written permission. */
18
19/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
20/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
21/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
22/* PURPOSE. */
23
24#include "flexdef.h"
25
26
27static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
28static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$";
29
30regex_t regex_linedir; /**< matches line directives */
31regex_t regex_blank_line; /**< matches blank lines */
32
33
34/** Initialize the regular expressions.
35 * @return true upon success.
36 */
37bool flex_init_regex(void)
38{
39 flex_regcomp(&regex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
40 flex_regcomp(&regex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED);
41
42 return true;
43}
44
45/** Compiles a regular expression or dies trying.
46 * @param preg Same as for regcomp().
47 * @param regex Same as for regcomp().
48 * @param cflags Same as for regcomp().
49 */
50void flex_regcomp(regex_t *preg, const char *regex, int cflags)
51{
52 int err;
53
54 memset (preg, 0, sizeof (regex_t));
55
56 if ((err = regcomp (preg, regex, cflags)) != 0) {
57 const int errbuf_sz = 200;
58 char * errbuf=0;
58 char *errbuf, *rxerr;
59
59
60 errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
61 regerror (err, preg, errbuf, errbuf_sz);
62 snprintf (errbuf, errbuf_sz, "regcomp failed: %s\n", errbuf);
60 errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
61 if (!errbuf)
62 flexfatal(_("Unable to allocate buffer to report regcomp"));
63 rxerr = (char*)flex_alloc(errbuf_sz *sizeof(char));
64 if (!rxerr)
65 flexfatal(_("Unable to allocate buffer for regerror"));
66 regerror (err, preg, rxerr, errbuf_sz);
67 snprintf (errbuf, errbuf_sz, "regcomp for \"%s\" failed: %s", regex, rxerr);
63
64 flexfatal (errbuf);
65 free(errbuf);
68
69 flexfatal (errbuf);
70 free(errbuf);
71 free(rxerr);
66 }
67}
68
69/** Extract a copy of the match, or NULL if no match.
70 * @param m A match as returned by regexec().
71 * @param src The source string that was passed to regexec().
72 * @return The allocated string.
73 */
74char *regmatch_dup (regmatch_t * m, const char *src)
75{
76 char *str;
77 int len;
78
79 if (m == NULL || m->rm_so < 0)
80 return NULL;
81 len = m->rm_eo - m->rm_so;
82 str = (char *) flex_alloc ((len + 1) * sizeof (char));
72 }
73}
74
75/** Extract a copy of the match, or NULL if no match.
76 * @param m A match as returned by regexec().
77 * @param src The source string that was passed to regexec().
78 * @return The allocated string.
79 */
80char *regmatch_dup (regmatch_t * m, const char *src)
81{
82 char *str;
83 int len;
84
85 if (m == NULL || m->rm_so < 0)
86 return NULL;
87 len = m->rm_eo - m->rm_so;
88 str = (char *) flex_alloc ((len + 1) * sizeof (char));
89 if (!str)
90 flexfatal(_("Unable to allocate a copy of the match"));
83 strncpy (str, src + m->rm_so, len);
84 str[len] = 0;
85 return str;
86}
87
88/** Copy the match.
89 * @param m A match as returned by regexec().
90 * @param dest The destination buffer.
91 * @param src The source string that was passed to regexec().
92 * @return dest
93 */
94char *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
95{
96 if (m == NULL || m->rm_so < 0) {
97 if (dest)
98 dest[0] = '\0';
99 return dest;
100 }
101
102 snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
103 return dest;
104}
105
106/** Get the length in characters of the match.
107 * @param m A match as returned by regexec().
108 * @param src The source string that was passed to regexec().
109 * @return The length of the match.
110 */
111int regmatch_len (regmatch_t * m)
112{
113 if (m == NULL || m->rm_so < 0) {
114 return 0;
115 }
116
117 return m->rm_eo - m->rm_so;
118}
119
120
121
122/** Convert a regmatch_t object to an integer using the strtol() function.
123 * @param m A match as returned by regexec().
124 * @param src The source string that was passed to regexec().
125 * @param endptr Same as the second argument to strtol().
126 * @param base Same as the third argument to strtol().
127 * @return The converted integer or error (Return value is the same as for strtol()).
128 */
129int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
130 int base)
131{
132 int n = 0;
133
134#define bufsz 20
135 char buf[bufsz];
136 char *s;
137
138 if (m == NULL || m->rm_so < 0)
139 return 0;
140
141 if (regmatch_len (m) < bufsz)
142 s = regmatch_cpy (m, buf, src);
143 else
144 s = regmatch_dup (m, src);
145
146 n = strtol (s, endptr, base);
147
148 if (s != buf)
149 free (s);
150
151 return n;
152}
153
154/** Check for empty or non-existent match.
155 * @param m A match as returned by regexec().
156 * @return false if match length is non-zero.
157 * Note that reg_empty returns true even if match did not occur at all.
158 */
159bool regmatch_empty (regmatch_t * m)
160{
161 return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
162}
163
164/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */
91 strncpy (str, src + m->rm_so, len);
92 str[len] = 0;
93 return str;
94}
95
96/** Copy the match.
97 * @param m A match as returned by regexec().
98 * @param dest The destination buffer.
99 * @param src The source string that was passed to regexec().
100 * @return dest
101 */
102char *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
103{
104 if (m == NULL || m->rm_so < 0) {
105 if (dest)
106 dest[0] = '\0';
107 return dest;
108 }
109
110 snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
111 return dest;
112}
113
114/** Get the length in characters of the match.
115 * @param m A match as returned by regexec().
116 * @param src The source string that was passed to regexec().
117 * @return The length of the match.
118 */
119int regmatch_len (regmatch_t * m)
120{
121 if (m == NULL || m->rm_so < 0) {
122 return 0;
123 }
124
125 return m->rm_eo - m->rm_so;
126}
127
128
129
130/** Convert a regmatch_t object to an integer using the strtol() function.
131 * @param m A match as returned by regexec().
132 * @param src The source string that was passed to regexec().
133 * @param endptr Same as the second argument to strtol().
134 * @param base Same as the third argument to strtol().
135 * @return The converted integer or error (Return value is the same as for strtol()).
136 */
137int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
138 int base)
139{
140 int n = 0;
141
142#define bufsz 20
143 char buf[bufsz];
144 char *s;
145
146 if (m == NULL || m->rm_so < 0)
147 return 0;
148
149 if (regmatch_len (m) < bufsz)
150 s = regmatch_cpy (m, buf, src);
151 else
152 s = regmatch_dup (m, src);
153
154 n = strtol (s, endptr, base);
155
156 if (s != buf)
157 free (s);
158
159 return n;
160}
161
162/** Check for empty or non-existent match.
163 * @param m A match as returned by regexec().
164 * @return false if match length is non-zero.
165 * Note that reg_empty returns true even if match did not occur at all.
166 */
167bool regmatch_empty (regmatch_t * m)
168{
169 return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
170}
171
172/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */