1 /** regex - regular expression functions related to POSIX regex lib. */
3 /* This file is part of flex. */
5 /* Redistribution and use in source and binary forms, with or without */
6 /* modification, are permitted provided that the following conditions */
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. */
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. */
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 */
27 static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
28 static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$";
30 regex_t regex_linedir; /**< matches line directives */
31 regex_t regex_blank_line; /**< matches blank lines */
34 /** Initialize the regular expressions.
35 * @return true upon success.
37 bool flex_init_regex(void)
39 flex_regcomp(®ex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
40 flex_regcomp(®ex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED);
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().
50 void flex_regcomp(regex_t *preg, const char *regex, int cflags)
54 memset (preg, 0, sizeof (regex_t));
56 if ((err = regcomp (preg, regex, cflags)) != 0) {
57 const int errbuf_sz = 200;
60 errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
62 flexfatal(_("Unable to allocate buffer to report regcomp"));
63 rxerr = (char*)flex_alloc(errbuf_sz *sizeof(char));
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);
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.
80 char *regmatch_dup (regmatch_t * m, const char *src)
85 if (m == NULL || m->rm_so < 0)
87 len = m->rm_eo - m->rm_so;
88 str = (char *) flex_alloc ((len + 1) * sizeof (char));
90 flexfatal(_("Unable to allocate a copy of the match"));
91 strncpy (str, src + m->rm_so, len);
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().
102 char *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
104 if (m == NULL || m->rm_so < 0) {
110 snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
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.
119 int regmatch_len (regmatch_t * m)
121 if (m == NULL || m->rm_so < 0) {
125 return m->rm_eo - m->rm_so;
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()).
137 int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
146 if (m == NULL || m->rm_so < 0)
149 if (regmatch_len (m) < bufsz)
150 s = regmatch_cpy (m, buf, src);
152 s = regmatch_dup (m, src);
154 n = strtol (s, endptr, base);
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.
167 bool regmatch_empty (regmatch_t * m)
169 return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
172 /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */