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