Deleted Added
full compact
jaillex.l (214117) jaillex.l (223190)
1%{
2/*-
1%{
2/*-
3 * Copyright (c) 2010 James Gritton
3 * Copyright (c) 2011 James Gritton
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: projects/jailconf/usr.sbin/jail/jaillex.l 214117 2010-10-20 20:42:33Z jamie $");
29__FBSDID("$FreeBSD: projects/jailconf/usr.sbin/jail/jaillex.l 223190 2011-06-17 16:21:03Z jamie $");
30
31#include <err.h>
32#include <stddef.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include "jailp.h"
37#include "y.tab.h"
38
39#define YY_NO_UNPUT
40
41extern int yynerrs;
42
43static ssize_t text2lval(size_t triml, size_t trimr, int tovar);
44
45static int instr;
46static int lineno = 1;
47%}
48
49%start _ DQ
50
51%%
52
53 /* Whitespace or equivalent */
54<_>[ \t]+ instr = 0;
55<_>#.* ;
56<_>\/\/.* ;
57<_>\/\*([^*]|(\*+([^*\/])))*\*+\/ {
58 const char *s;
59
60 for (s = yytext; s < yytext + yyleng; s++)
61 if (*s == '\n')
62 lineno++;
63 instr = 0;
64 }
65<_>\n {
66 lineno++;
67 instr = 0;
68 }
69
70 /* Reserved tokens */
71<_>\+= {
72 instr = 0;
73 return PLEQ;
74 }
75<_>[,;={}] {
76 instr = 0;
77 return yytext[0];
78 }
79
80 /* Atomic (unquoted) strings */
81<_,DQ>[A-Za-z0-9_!%&()\-.:<>?@\[\]^`|~]+ |
82<_,DQ>\\(.|\n|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}) |
83<_,DQ>[$*+/\\] {
84 (void)text2lval(0, 0, 0);
85 return instr ? STR1 : (instr = 1, STR);
86 }
87
88 /* Single and double quoted strings */
89<_>'([^\'\\]|\\(.|\n))*' {
90 (void)text2lval(1, 1, 0);
91 return instr ? STR1 : (instr = 1, STR);
92 }
93<_>\"([^"\\]|\\(.|\n))*\" |
94<DQ>[^\"$\\]([^"\\]|\\(.|\n))*\" {
95 size_t skip;
96 ssize_t atvar;
97
98 skip = yytext[0] == '"' ? 1 : 0;
99 atvar = text2lval(skip, 1, 1);
100 if (atvar < 0)
101 BEGIN _;
102 else {
103 /*
104 * The string has a variable inside it.
105 * Go into DQ mode to get the variable
106 * and then the rest of the string.
107 */
108 BEGIN DQ;
109 yyless(atvar);
110 }
111 return instr ? STR1 : (instr = 1, STR);
112 }
113<DQ>\" BEGIN _;
114
115 /* Variables, single-word or bracketed */
116<_,DQ>$[A-Za-z_][A-Za-z_0-9]* {
117 (void)text2lval(1, 0, 0);
118 return instr ? VAR1 : (instr = 1, VAR);
119 }
120<_>$\{([^\n{}]|\\(.|\n))*\} |
121<DQ>$\{([^\n\"{}]|\\(.|\n))*\} {
122 (void)text2lval(2, 1, 0);
123 return instr ? VAR1 : (instr = 1, VAR);
124 }
125
126 /* Partially formed bits worth complaining about */
127<_>\/\*([^*]|(\*+([^*\/])))*\** {
128 warnx("%s line %d: unterminated comment",
129 cfname, lineno);
130 yynerrs++;
131 }
132<_>'([^\n'\\]|\\.)* |
133<_>\"([^\n\"\\]|\\.)* {
134 warnx("%s line %d: unterminated string",
135 cfname, lineno);
136 yynerrs++;
137 }
138<_>$\{([^\n{}]|\\.)* |
139<DQ>$\{([^\n\"{}]|\\.)* {
140 warnx("%s line %d: unterminated variable",
141 cfname, lineno);
142 yynerrs++;
143 }
144
145 /* A hack because "<0>" rules aren't allowed */
146<_>. return yytext[0];
147.|\n {
148 BEGIN _;
149 yyless(0);
150 }
151
152%%
153
154void
155yyerror(const char *s)
156{
157 if (!yytext)
158 warnx("%s line %d: %s", cfname, lineno, s);
159 else if (!yytext[0])
160 warnx("%s: unexpected EOF", cfname);
161 else
162 warnx("%s line %d: %s: %s", cfname, lineno, yytext, s);
163}
164
165/*
166 * Copy string from yytext to yylval, handling backslash escapes,
167 * and optionally stopping at the beginning of a variable.
168 */
169static ssize_t
170text2lval(size_t triml, size_t trimr, int tovar)
171{
172 char *d;
173 const char *s, *se;
174
175 yylval.cs = d = emalloc(yyleng - trimr - triml + 1);
176 se = yytext + (yyleng - trimr);
177 for (s = yytext + triml; s < se; s++, d++) {
178 if (*s != '\\') {
179 if (tovar && *s == '$') {
180 *d = '\0';
181 return s - yytext;
182 }
183 if (*s == '\n')
184 lineno++;
185 *d = *s;
186 continue;
187 }
188 s++;
189 if (*s >= '0' && *s <= '7') {
190 *d = *s - '0';
191 if (s + 1 < se && s[1] >= '0' && s[1] <= '7') {
192 *d = 010 * *d + (*++s - '0');
193 if (s + 1 < se && s[1] >= '0' && s[1] <= '7')
194 *d = 010 * *d + (*++s - '0');
195 }
196 continue;
197 }
198 switch (*s) {
199 case 'a': *d = '\a'; break;
200 case 'b': *d = '\b'; break;
201 case 'f': *d = '\f'; break;
202 case 'n': *d = '\n'; break;
203 case 'r': *d = '\r'; break;
204 case 't': *d = '\t'; break;
205 case 'v': *d = '\v'; break;
206 case '\n': d--; lineno++; break;
207 default: *d = *s; break;
208 case 'x':
209 *d = 0;
210 if (s + 1 >= se)
211 break;
212 if (s[1] >= '0' && s[1] <= '9')
213 *d = *++s - '0';
214 else if (s[1] >= 'A' && s[1] <= 'F')
215 *d = *++s + (0xA - 'A');
216 else if (s[1] >= 'a' && s[1] <= 'a')
217 *d = *++s + (0xa - 'a');
218 else
219 break;
220 if (s + 1 >= se)
221 break;
222 if (s[1] >= '0' && s[1] <= '9')
223 *d = *d * 0x10 + (*++s - '0');
224 else if (s[1] >= 'A' && s[1] <= 'F')
225 *d = *d * 0x10 + (*++s + (0xA - 'A'));
226 else if (s[1] >= 'a' && s[1] <= 'a')
227 *d = *d * 0x10 + (*++s + (0xa - 'a'));
228 }
229 }
230 *d = '\0';
231 return -1;
232}
30
31#include <err.h>
32#include <stddef.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include "jailp.h"
37#include "y.tab.h"
38
39#define YY_NO_UNPUT
40
41extern int yynerrs;
42
43static ssize_t text2lval(size_t triml, size_t trimr, int tovar);
44
45static int instr;
46static int lineno = 1;
47%}
48
49%start _ DQ
50
51%%
52
53 /* Whitespace or equivalent */
54<_>[ \t]+ instr = 0;
55<_>#.* ;
56<_>\/\/.* ;
57<_>\/\*([^*]|(\*+([^*\/])))*\*+\/ {
58 const char *s;
59
60 for (s = yytext; s < yytext + yyleng; s++)
61 if (*s == '\n')
62 lineno++;
63 instr = 0;
64 }
65<_>\n {
66 lineno++;
67 instr = 0;
68 }
69
70 /* Reserved tokens */
71<_>\+= {
72 instr = 0;
73 return PLEQ;
74 }
75<_>[,;={}] {
76 instr = 0;
77 return yytext[0];
78 }
79
80 /* Atomic (unquoted) strings */
81<_,DQ>[A-Za-z0-9_!%&()\-.:<>?@\[\]^`|~]+ |
82<_,DQ>\\(.|\n|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}) |
83<_,DQ>[$*+/\\] {
84 (void)text2lval(0, 0, 0);
85 return instr ? STR1 : (instr = 1, STR);
86 }
87
88 /* Single and double quoted strings */
89<_>'([^\'\\]|\\(.|\n))*' {
90 (void)text2lval(1, 1, 0);
91 return instr ? STR1 : (instr = 1, STR);
92 }
93<_>\"([^"\\]|\\(.|\n))*\" |
94<DQ>[^\"$\\]([^"\\]|\\(.|\n))*\" {
95 size_t skip;
96 ssize_t atvar;
97
98 skip = yytext[0] == '"' ? 1 : 0;
99 atvar = text2lval(skip, 1, 1);
100 if (atvar < 0)
101 BEGIN _;
102 else {
103 /*
104 * The string has a variable inside it.
105 * Go into DQ mode to get the variable
106 * and then the rest of the string.
107 */
108 BEGIN DQ;
109 yyless(atvar);
110 }
111 return instr ? STR1 : (instr = 1, STR);
112 }
113<DQ>\" BEGIN _;
114
115 /* Variables, single-word or bracketed */
116<_,DQ>$[A-Za-z_][A-Za-z_0-9]* {
117 (void)text2lval(1, 0, 0);
118 return instr ? VAR1 : (instr = 1, VAR);
119 }
120<_>$\{([^\n{}]|\\(.|\n))*\} |
121<DQ>$\{([^\n\"{}]|\\(.|\n))*\} {
122 (void)text2lval(2, 1, 0);
123 return instr ? VAR1 : (instr = 1, VAR);
124 }
125
126 /* Partially formed bits worth complaining about */
127<_>\/\*([^*]|(\*+([^*\/])))*\** {
128 warnx("%s line %d: unterminated comment",
129 cfname, lineno);
130 yynerrs++;
131 }
132<_>'([^\n'\\]|\\.)* |
133<_>\"([^\n\"\\]|\\.)* {
134 warnx("%s line %d: unterminated string",
135 cfname, lineno);
136 yynerrs++;
137 }
138<_>$\{([^\n{}]|\\.)* |
139<DQ>$\{([^\n\"{}]|\\.)* {
140 warnx("%s line %d: unterminated variable",
141 cfname, lineno);
142 yynerrs++;
143 }
144
145 /* A hack because "<0>" rules aren't allowed */
146<_>. return yytext[0];
147.|\n {
148 BEGIN _;
149 yyless(0);
150 }
151
152%%
153
154void
155yyerror(const char *s)
156{
157 if (!yytext)
158 warnx("%s line %d: %s", cfname, lineno, s);
159 else if (!yytext[0])
160 warnx("%s: unexpected EOF", cfname);
161 else
162 warnx("%s line %d: %s: %s", cfname, lineno, yytext, s);
163}
164
165/*
166 * Copy string from yytext to yylval, handling backslash escapes,
167 * and optionally stopping at the beginning of a variable.
168 */
169static ssize_t
170text2lval(size_t triml, size_t trimr, int tovar)
171{
172 char *d;
173 const char *s, *se;
174
175 yylval.cs = d = emalloc(yyleng - trimr - triml + 1);
176 se = yytext + (yyleng - trimr);
177 for (s = yytext + triml; s < se; s++, d++) {
178 if (*s != '\\') {
179 if (tovar && *s == '$') {
180 *d = '\0';
181 return s - yytext;
182 }
183 if (*s == '\n')
184 lineno++;
185 *d = *s;
186 continue;
187 }
188 s++;
189 if (*s >= '0' && *s <= '7') {
190 *d = *s - '0';
191 if (s + 1 < se && s[1] >= '0' && s[1] <= '7') {
192 *d = 010 * *d + (*++s - '0');
193 if (s + 1 < se && s[1] >= '0' && s[1] <= '7')
194 *d = 010 * *d + (*++s - '0');
195 }
196 continue;
197 }
198 switch (*s) {
199 case 'a': *d = '\a'; break;
200 case 'b': *d = '\b'; break;
201 case 'f': *d = '\f'; break;
202 case 'n': *d = '\n'; break;
203 case 'r': *d = '\r'; break;
204 case 't': *d = '\t'; break;
205 case 'v': *d = '\v'; break;
206 case '\n': d--; lineno++; break;
207 default: *d = *s; break;
208 case 'x':
209 *d = 0;
210 if (s + 1 >= se)
211 break;
212 if (s[1] >= '0' && s[1] <= '9')
213 *d = *++s - '0';
214 else if (s[1] >= 'A' && s[1] <= 'F')
215 *d = *++s + (0xA - 'A');
216 else if (s[1] >= 'a' && s[1] <= 'a')
217 *d = *++s + (0xa - 'a');
218 else
219 break;
220 if (s + 1 >= se)
221 break;
222 if (s[1] >= '0' && s[1] <= '9')
223 *d = *d * 0x10 + (*++s - '0');
224 else if (s[1] >= 'A' && s[1] <= 'F')
225 *d = *d * 0x10 + (*++s + (0xA - 'A'));
226 else if (s[1] >= 'a' && s[1] <= 'a')
227 *d = *d * 0x10 + (*++s + (0xa - 'a'));
228 }
229 }
230 *d = '\0';
231 return -1;
232}