xref: /minix3/external/bsd/flex/dist/regex.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1 /*	$NetBSD: regex.c,v 1.1.1.1 2009/10/26 00:26:41 christos Exp $	*/
2 
3 /** regex - regular expression functions related to POSIX regex lib. */
4 
5 /*  This file is part of flex. */
6 
7 /*  Redistribution and use in source and binary forms, with or without */
8 /*  modification, are permitted provided that the following conditions */
9 /*  are met: */
10 
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. */
16 
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. */
20 
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 */
24 /*  PURPOSE. */
25 
26 #include "flexdef.h"
27 
28 
29 static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
30 static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$";
31 
32 regex_t regex_linedir; /**< matches line directives */
33 regex_t regex_blank_line; /**< matches blank lines */
34 
35 
36 /** Initialize the regular expressions.
37  * @return true upon success.
38  */
39 bool flex_init_regex(void)
40 {
41     flex_regcomp(&regex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
42     flex_regcomp(&regex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED);
43 
44     return true;
45 }
46 
47 /** Compiles a regular expression or dies trying.
48  * @param preg  Same as for regcomp().
49  * @param regex Same as for regcomp().
50  * @param cflags Same as for regcomp().
51  */
52 void flex_regcomp(regex_t *preg, const char *regex, int cflags)
53 {
54     int err;
55 
56 	memset (preg, 0, sizeof (regex_t));
57 
58 	if ((err = regcomp (preg, regex, cflags)) != 0) {
59         const int errbuf_sz = 200;
60         char * errbuf=0;
61 
62         errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
63 		regerror (err, preg, errbuf, errbuf_sz);
64 		snprintf (errbuf, errbuf_sz, "regcomp failed: %s\n", errbuf);
65 
66 		flexfatal (errbuf);
67         free(errbuf);
68 	}
69 }
70 
71 /** Extract a copy of the match, or NULL if no match.
72  * @param m A match as returned by regexec().
73  * @param src The source string that was passed to regexec().
74  * @return The allocated string.
75  */
76 char   *regmatch_dup (regmatch_t * m, const char *src)
77 {
78 	char   *str;
79 	int     len;
80 
81 	if (m == NULL || m->rm_so < 0)
82 		return NULL;
83 	len = m->rm_eo - m->rm_so;
84 	str = (char *) flex_alloc ((len + 1) * sizeof (char));
85 	strncpy (str, src + m->rm_so, len);
86 	str[len] = 0;
87 	return str;
88 }
89 
90 /** Copy the match.
91  * @param m A match as returned by regexec().
92  * @param dest The destination buffer.
93  * @param src The source string that was passed to regexec().
94  * @return dest
95  */
96 char   *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
97 {
98 	if (m == NULL || m->rm_so < 0) {
99 		if (dest)
100 			dest[0] = '\0';
101 		return dest;
102 	}
103 
104 	snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
105     return dest;
106 }
107 
108 /** Get the length in characters of the match.
109  * @param m A match as returned by regexec().
110  * @param src The source string that was passed to regexec().
111  * @return The length of the match.
112  */
113 int regmatch_len (regmatch_t * m)
114 {
115 	if (m == NULL || m->rm_so < 0) {
116 		return 0;
117 	}
118 
119 	return m->rm_eo - m->rm_so;
120 }
121 
122 
123 
124 /** Convert a regmatch_t object to an integer using the strtol() function.
125  * @param m A match as returned by regexec().
126  * @param src The source string that was passed to regexec().
127  * @param endptr Same as the second argument to strtol().
128  * @param base   Same as the third argument to strtol().
129  * @return The converted integer or error (Return value is the same as for strtol()).
130  */
131 int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
132 		     int base)
133 {
134 	int     n = 0;
135 
136 #define bufsz 20
137 	char    buf[bufsz];
138 	char   *s;
139 
140 	if (m == NULL || m->rm_so < 0)
141 		return 0;
142 
143 	if (regmatch_len (m) < bufsz)
144 		s = regmatch_cpy (m, buf, src);
145 	else
146 		s = regmatch_dup (m, src);
147 
148 	n = strtol (s, endptr, base);
149 
150 	if (s != buf)
151 		free (s);
152 
153 	return n;
154 }
155 
156 /** Check for empty or non-existent match.
157  * @param m A match as returned by regexec().
158  * @return false if match length is non-zero.
159  * Note that reg_empty returns true even if match did not occur at all.
160  */
161 bool regmatch_empty (regmatch_t * m)
162 {
163 	return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
164 }
165 
166 /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */
167