]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
flex: don't trust YY_USER_INIT
[bison.git] / src / scan-skel.l
CommitLineData
be2a1a68 1/* Scan Bison Skeletons. -*- C -*-
353d3eb6 2
fc51acdd 3 Copyright (C) 2001-2014 Free Software Foundation, Inc.
1239777d
AD
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
f16b0819
PE
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
1239777d 11
f16b0819
PE
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
9b3add5b 16
1239777d 17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9b3add5b 19
8d90395d 20%option nodefault noyywrap noinput nounput never-interactive debug
aed7fd9b 21%option prefix="skel_" outfile="lex.yy.c"
9b3add5b 22
aed7fd9b 23%{
4f6e011e
PE
24/* Work around a bug in flex 2.5.31. See Debian bug 333231
25 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */
26#undef skel_wrap
27#define skel_wrap() 1
28
f9bfc42a 29#define FLEX_PREFIX(Id) skel_ ## Id
0305d25e 30#include <src/flex-scanner.h>
353d3eb6 31
cb48f191 32#include <dirname.h>
353d3eb6
PE
33#include <error.h>
34#include <quotearg.h>
35
0305d25e
AD
36#include <src/complain.h>
37#include <src/getargs.h>
38#include <src/files.h>
39#include <src/scan-skel.h>
dc9701e8 40
08af01c2
JD
41#define YY_DECL static int skel_lex (void)
42YY_DECL;
06f01bc4 43
92f39ba6
TR
44typedef void (*at_directive)(int, char**, char **, int*);
45static void at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun);
46static void at_basename (int argc, char *argv[], char**, int*);
47static void at_complain (int argc, char *argv[], char**, int*);
896517cd 48static void at_output (int argc, char *argv[], char **name, int *lineno);
3eb82471
JD
49static void fail_for_at_directive_too_many_args (char const *at_directive_name);
50static void fail_for_at_directive_too_few_args (char const *at_directive_name);
08af01c2 51static void fail_for_invalid_at (char const *at);
aed7fd9b 52%}
08af01c2 53
3eb82471 54%x SC_AT_DIRECTIVE_ARGS
08af01c2
JD
55%x SC_AT_DIRECTIVE_SKIP_WS
56
9b3add5b 57%%
e9683cfd
PE
58
59%{
84f6a6ca 60 int out_lineno PACIFY_CC (= 0);
92f39ba6 61 char *out_name = NULL;
3eb82471 62
0505df0c
TR
63 /* Currently, only the @complain directive takes multiple arguments, and
64 never more than 7, with argv[0] being the directive name and argv[1]
65 being the type of complaint to dispatch. */
66#define ARGC_MAX 9
b9c3c10c
AD
67 int argc = 0;
68 char *argv[ARGC_MAX];
92f39ba6 69 at_directive at_ptr = NULL;
e9683cfd
PE
70%}
71
7dc4a694
JD
72"@@" fputc ('@', yyout);
73"@{" fputc ('[', yyout);
74"@}" fputc (']', yyout);
45eebca4 75"@'" continue; /* Used by b4_cat in ../data/bison.m4. */
4d24ffb7 76@\n continue;
e9683cfd 77
3fc65ead 78"@oline@" fprintf (yyout, "%d", out_lineno + 1);
92f39ba6 79"@ofile@" fputs (quotearg_style (c_quoting_style, out_name), yyout);
bd9d212b 80
fc5618b3
AD
81"@basename(" at_init (&argc, argv, &at_ptr, &at_basename);
82"@complain(" at_init (&argc, argv, &at_ptr, &at_complain);
83"@output(" at_init (&argc, argv, &at_ptr, &at_output);
e9683cfd 84
3fc16193 85 /* This pattern must not match more than the previous @ patterns. */
630a0218 86@[^@{}\'(\n]* fail_for_invalid_at (yytext);
fc5618b3
AD
87\n out_lineno++; ECHO;
88[^@\n]+ ECHO;
e9683cfd 89
dbfcf7a8 90<INITIAL><<EOF>> {
92f39ba6 91 if (out_name)
7ec5ab2e 92 {
92f39ba6 93 free (out_name);
7ec5ab2e
PE
94 xfclose (yyout);
95 }
96 return EOF;
97}
08af01c2 98
4d24ffb7
AD
99<SC_AT_DIRECTIVE_ARGS>
100{
101 [^@]+ STRING_GROW;
08af01c2 102
4d24ffb7
AD
103 "@@" obstack_1grow (&obstack_for_string, '@');
104 "@{" obstack_1grow (&obstack_for_string, '[');
105 "@}" obstack_1grow (&obstack_for_string, ']');
45eebca4 106 "@'" continue; /* For starting an argument that begins with whitespace. */
4d24ffb7 107 @\n continue;
08af01c2
JD
108
109 @[,)] {
b9c3c10c
AD
110 if (argc >= ARGC_MAX)
111 fail_for_at_directive_too_many_args (argv[0]);
08af01c2 112
b9c3c10c 113 argv[argc++] = obstack_finish0 (&obstack_for_string);
08af01c2
JD
114
115 /* Like M4, skip whitespace after a comma. */
116 if (yytext[1] == ',')
117 BEGIN SC_AT_DIRECTIVE_SKIP_WS;
118 else
119 {
fc5618b3
AD
120 aver (at_ptr);
121 at_ptr (argc, argv, &out_name, &out_lineno);
b9c3c10c
AD
122 obstack_free (&obstack_for_string, argv[0]);
123 argc = 0;
08af01c2
JD
124 BEGIN INITIAL;
125 }
126 }
127
4d24ffb7 128 @.? fail_for_invalid_at (yytext);
08af01c2
JD
129}
130
4d24ffb7
AD
131<SC_AT_DIRECTIVE_SKIP_WS>
132{
133 [ \t\r\n] continue;
b9c3c10c 134 . yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS;
08af01c2
JD
135}
136
4d24ffb7
AD
137<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
138{
bb8e56ff 139 <<EOF>> complain (NULL, fatal, _("unclosed %s directive in skeleton"), argv[0]);
08af01c2
JD
140}
141
9b3add5b 142%%
536545f3 143
92f39ba6
TR
144static void
145at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun)
146{
147 *at_ptr = fun;
148 yytext[yyleng-1] = '\0';
149 obstack_grow (&obstack_for_string, yytext, yyleng);
150 argv[(*argc)++] = obstack_finish (&obstack_for_string);
151 BEGIN SC_AT_DIRECTIVE_ARGS;
152}
153
2cdb2a7b
PE
154/*------------------------.
155| Scan a Bison skeleton. |
156`------------------------*/
536545f3 157
536545f3 158void
2cdb2a7b 159scan_skel (FILE *in)
536545f3 160{
08af01c2
JD
161 static bool initialized = false;
162 if (!initialized)
163 {
164 initialized = true;
165 obstack_init (&obstack_for_string);
166 }
2cdb2a7b 167 skel_in = in;
c5e3e510 168 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 169 skel_lex ();
536545f3 170}
bd9d212b 171
3fc65ead
JD
172void
173skel_scanner_free (void)
174{
175 obstack_free (&obstack_for_string, 0);
3eb82471
JD
176 /* Reclaim Flex's buffers. */
177 yylex_destroy ();
3fc65ead
JD
178}
179
b9c3c10c
AD
180static inline warnings
181flag (const char *arg)
182{
0505df0c 183 /* compare with values issued from b4_error */
896517cd 184 if (STREQ (arg, "complain"))
0505df0c 185 return complaint;
630a0218
AD
186 else if (STREQ (arg, "deprecated"))
187 return Wdeprecated;
0505df0c
TR
188 else if (STREQ (arg, "fatal"))
189 return fatal;
c6c8de16 190 else if (STREQ (arg, "note"))
ea9e670d 191 return silent | complaint | no_caret;
896517cd
TR
192 else if (STREQ (arg, "warn"))
193 return Wother;
0505df0c 194 else
ab96bb24 195 abort ();
b9c3c10c
AD
196}
197
f39ab286 198static void
92f39ba6 199at_basename (int argc, char *argv[], char **out_namep, int *out_linenop)
3fc65ead 200{
92f39ba6
TR
201 (void) out_namep;
202 (void) out_linenop;
896517cd
TR
203 if (2 < argc)
204 fail_for_at_directive_too_many_args (argv[0]);
205 fputs (last_component (argv[1]), yyout);
206}
207
208static void
92f39ba6 209at_complain (int argc, char *argv[], char **out_namep, int *out_linenop)
896517cd
TR
210{
211 static unsigned indent;
212 warnings w = flag (argv[1]);
213 location loc;
214 location *locp = NULL;
215
92f39ba6
TR
216 (void) out_namep;
217 (void) out_linenop;
218
896517cd 219 if (argc < 4)
92f39ba6 220 fail_for_at_directive_too_few_args (argv[0]);
896517cd 221 if (argv[2] && argv[2][0])
3fc65ead 222 {
896517cd
TR
223 boundary_set_from_string (&loc.start, argv[2]);
224 boundary_set_from_string (&loc.end, argv[3]);
225 locp = &loc;
3fc65ead 226 }
896517cd
TR
227 if (w & silent)
228 indent += SUB_INDENT;
3fc65ead 229 else
896517cd 230 indent = 0;
f60321dc 231 complain_args (locp, w, &indent, argc - 4, argv + 4);
896517cd
TR
232 if (w & silent)
233 indent -= SUB_INDENT;
3fc65ead
JD
234}
235
236static void
92f39ba6 237at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
896517cd
TR
238{
239 if (2 < argc)
240 fail_for_at_directive_too_many_args (argv[0]);
92f39ba6 241 if (*out_namep)
896517cd 242 {
92f39ba6 243 free (*out_namep);
896517cd
TR
244 xfclose (yyout);
245 }
92f39ba6 246 *out_namep = xstrdup (argv[1]);
ea99d6e6 247 output_file_name_check (out_namep, true);
184b42c8
AD
248 /* If there were errors, do not generate the output. */
249 yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");
896517cd
TR
250 *out_linenop = 1;
251}
252
56f0d1d1 253static void
3eb82471 254fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead 255{
bb8e56ff 256 complain (NULL, fatal, _("too few arguments for %s directive in skeleton"),
b9c3c10c 257 at_directive_name);
3fc65ead
JD
258}
259
08af01c2 260static void
3eb82471 261fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 262{
bb8e56ff 263 complain (NULL, fatal, _("too many arguments for %s directive in skeleton"),
6fb8b256 264 at_directive_name);
08af01c2
JD
265}
266
267static void
268fail_for_invalid_at (char const *at)
269{
bb8e56ff 270 complain (NULL, fatal, "invalid @ in skeleton: %s", at);
08af01c2 271}