aslsupport.l revision 1.20 1 1.1 christos /******************************************************************************
2 1.1 christos *
3 1.1 christos * Module Name: aslsupport.l - Flex/lex scanner C support routines.
4 1.1 christos * NOTE: Included into aslcompile.l, not compiled by itself.
5 1.1 christos *
6 1.1 christos *****************************************************************************/
7 1.1 christos
8 1.19 christos /******************************************************************************
9 1.19 christos *
10 1.19 christos * 1. Copyright Notice
11 1.19 christos *
12 1.20 christos * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
13 1.1 christos * All rights reserved.
14 1.1 christos *
15 1.19 christos * 2. License
16 1.19 christos *
17 1.19 christos * 2.1. This is your license from Intel Corp. under its intellectual property
18 1.19 christos * rights. You may have additional license terms from the party that provided
19 1.19 christos * you this software, covering your right to use that party's intellectual
20 1.19 christos * property rights.
21 1.19 christos *
22 1.19 christos * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 1.19 christos * copy of the source code appearing in this file ("Covered Code") an
24 1.19 christos * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 1.19 christos * base code distributed originally by Intel ("Original Intel Code") to copy,
26 1.19 christos * make derivatives, distribute, use and display any portion of the Covered
27 1.19 christos * Code in any form, with the right to sublicense such rights; and
28 1.19 christos *
29 1.19 christos * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 1.19 christos * license (with the right to sublicense), under only those claims of Intel
31 1.19 christos * patents that are infringed by the Original Intel Code, to make, use, sell,
32 1.19 christos * offer to sell, and import the Covered Code and derivative works thereof
33 1.19 christos * solely to the minimum extent necessary to exercise the above copyright
34 1.19 christos * license, and in no event shall the patent license extend to any additions
35 1.19 christos * to or modifications of the Original Intel Code. No other license or right
36 1.19 christos * is granted directly or by implication, estoppel or otherwise;
37 1.19 christos *
38 1.19 christos * The above copyright and patent license is granted only if the following
39 1.19 christos * conditions are met:
40 1.19 christos *
41 1.19 christos * 3. Conditions
42 1.19 christos *
43 1.19 christos * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 1.19 christos * Redistribution of source code of any substantial portion of the Covered
45 1.19 christos * Code or modification with rights to further distribute source must include
46 1.19 christos * the above Copyright Notice, the above License, this list of Conditions,
47 1.19 christos * and the following Disclaimer and Export Compliance provision. In addition,
48 1.19 christos * Licensee must cause all Covered Code to which Licensee contributes to
49 1.19 christos * contain a file documenting the changes Licensee made to create that Covered
50 1.19 christos * Code and the date of any change. Licensee must include in that file the
51 1.19 christos * documentation of any changes made by any predecessor Licensee. Licensee
52 1.19 christos * must include a prominent statement that the modification is derived,
53 1.19 christos * directly or indirectly, from Original Intel Code.
54 1.19 christos *
55 1.19 christos * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 1.19 christos * Redistribution of source code of any substantial portion of the Covered
57 1.19 christos * Code or modification without rights to further distribute source must
58 1.19 christos * include the following Disclaimer and Export Compliance provision in the
59 1.19 christos * documentation and/or other materials provided with distribution. In
60 1.19 christos * addition, Licensee may not authorize further sublicense of source of any
61 1.19 christos * portion of the Covered Code, and must include terms to the effect that the
62 1.19 christos * license from Licensee to its licensee is limited to the intellectual
63 1.19 christos * property embodied in the software Licensee provides to its licensee, and
64 1.19 christos * not to intellectual property embodied in modifications its licensee may
65 1.19 christos * make.
66 1.19 christos *
67 1.19 christos * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 1.19 christos * substantial portion of the Covered Code or modification must reproduce the
69 1.19 christos * above Copyright Notice, and the following Disclaimer and Export Compliance
70 1.19 christos * provision in the documentation and/or other materials provided with the
71 1.19 christos * distribution.
72 1.19 christos *
73 1.19 christos * 3.4. Intel retains all right, title, and interest in and to the Original
74 1.19 christos * Intel Code.
75 1.19 christos *
76 1.19 christos * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 1.19 christos * Intel shall be used in advertising or otherwise to promote the sale, use or
78 1.19 christos * other dealings in products derived from or relating to the Covered Code
79 1.19 christos * without prior written authorization from Intel.
80 1.19 christos *
81 1.19 christos * 4. Disclaimer and Export Compliance
82 1.19 christos *
83 1.19 christos * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 1.19 christos * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 1.19 christos * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 1.19 christos * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 1.19 christos * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 1.19 christos * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 1.19 christos * PARTICULAR PURPOSE.
90 1.19 christos *
91 1.19 christos * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 1.19 christos * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 1.19 christos * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 1.19 christos * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 1.19 christos * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 1.19 christos * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 1.19 christos * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 1.19 christos * LIMITED REMEDY.
99 1.19 christos *
100 1.19 christos * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 1.19 christos * software or system incorporating such software without first obtaining any
102 1.19 christos * required license or other approval from the U. S. Department of Commerce or
103 1.19 christos * any other agency or department of the United States Government. In the
104 1.19 christos * event Licensee exports any such software from the United States or
105 1.19 christos * re-exports any such software from a foreign destination, Licensee shall
106 1.19 christos * ensure that the distribution and export/re-export of the software is in
107 1.19 christos * compliance with all laws, regulations, orders, or other restrictions of the
108 1.19 christos * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 1.19 christos * any of its subsidiaries will export/re-export any technical data, process,
110 1.19 christos * software, or service, directly or indirectly, to any country for which the
111 1.19 christos * United States government or any agency thereof requires an export license,
112 1.19 christos * other governmental approval, or letter of assurance, without first obtaining
113 1.19 christos * such license, approval or letter.
114 1.19 christos *
115 1.19 christos *****************************************************************************
116 1.19 christos *
117 1.19 christos * Alternatively, you may choose to be licensed under the terms of the
118 1.19 christos * following license:
119 1.19 christos *
120 1.1 christos * Redistribution and use in source and binary forms, with or without
121 1.1 christos * modification, are permitted provided that the following conditions
122 1.1 christos * are met:
123 1.1 christos * 1. Redistributions of source code must retain the above copyright
124 1.1 christos * notice, this list of conditions, and the following disclaimer,
125 1.1 christos * without modification.
126 1.1 christos * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127 1.1 christos * substantially similar to the "NO WARRANTY" disclaimer below
128 1.1 christos * ("Disclaimer") and any redistribution must be conditioned upon
129 1.1 christos * including a substantially similar Disclaimer requirement for further
130 1.1 christos * binary redistribution.
131 1.1 christos * 3. Neither the names of the above-listed copyright holders nor the names
132 1.1 christos * of any contributors may be used to endorse or promote products derived
133 1.1 christos * from this software without specific prior written permission.
134 1.1 christos *
135 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137 1.16 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139 1.19 christos * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140 1.19 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141 1.19 christos * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142 1.19 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143 1.19 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144 1.19 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145 1.19 christos * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 1.19 christos *
147 1.19 christos * Alternatively, you may choose to be licensed under the terms of the
148 1.19 christos * GNU General Public License ("GPL") version 2 as published by the Free
149 1.19 christos * Software Foundation.
150 1.19 christos *
151 1.19 christos *****************************************************************************/
152 1.1 christos
153 1.1 christos /* Configuration */
154 1.1 christos
155 1.1 christos #define ASL_SPACES_PER_TAB 4
156 1.1 christos
157 1.1 christos #define ASL_NORMAL_CHAR 0
158 1.1 christos #define ASL_ESCAPE_SEQUENCE 1
159 1.1 christos #define ASL_OCTAL_CONSTANT 2
160 1.1 christos #define ASL_HEX_CONSTANT 3
161 1.1 christos
162 1.1 christos
163 1.8 christos void
164 1.8 christos yyerror (char const *s)
165 1.1 christos {
166 1.1 christos
167 1.8 christos AcpiOsPrintf ("YYERROR: %s\n", s);
168 1.8 christos }
169 1.1 christos
170 1.1 christos
171 1.4 christos /*******************************************************************************
172 1.4 christos *
173 1.4 christos * FUNCTION: AslParserCleanup
174 1.4 christos *
175 1.4 christos * Used to delete the current buffer
176 1.4 christos *
177 1.4 christos ******************************************************************************/
178 1.4 christos
179 1.3 christos void
180 1.3 christos AslParserCleanup (
181 1.3 christos void)
182 1.3 christos {
183 1.3 christos
184 1.3 christos yy_delete_buffer (YY_CURRENT_BUFFER);
185 1.3 christos }
186 1.3 christos
187 1.3 christos
188 1.1 christos /*******************************************************************************
189 1.1 christos *
190 1.1 christos * FUNCTION: AslDoLineDirective
191 1.1 christos *
192 1.1 christos * PARAMETERS: None. Uses input() to access current source code line
193 1.1 christos *
194 1.1 christos * RETURN: Updates global line number and filename
195 1.1 christos *
196 1.1 christos * DESCRIPTION: Handle #line directives emitted by the preprocessor.
197 1.1 christos *
198 1.18 christos * The #line directive is emitted by the preprocessor, and is used to
199 1.1 christos * pass through line numbers from the original source code file to the
200 1.1 christos * preprocessor output file (.i). This allows any compiler-generated
201 1.1 christos * error messages to be displayed with the correct line number.
202 1.1 christos *
203 1.1 christos ******************************************************************************/
204 1.1 christos
205 1.1 christos static void
206 1.1 christos AslDoLineDirective (
207 1.1 christos void)
208 1.1 christos {
209 1.1 christos int c;
210 1.1 christos char *Token;
211 1.1 christos UINT32 LineNumber;
212 1.1 christos char *Filename;
213 1.1 christos UINT32 i;
214 1.1 christos
215 1.12 christos AslGbl_HasIncludeFiles = TRUE;
216 1.1 christos
217 1.1 christos /* Eat the entire line that contains the #line directive */
218 1.1 christos
219 1.12 christos AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
220 1.1 christos
221 1.1 christos while ((c = input()) != '\n' && c != EOF)
222 1.1 christos {
223 1.14 christos *AslGbl_LineBufPtr = (char) c;
224 1.12 christos AslGbl_LineBufPtr++;
225 1.1 christos }
226 1.12 christos *AslGbl_LineBufPtr = 0;
227 1.1 christos
228 1.1 christos /* First argument is the actual line number */
229 1.1 christos
230 1.12 christos Token = strtok (AslGbl_CurrentLineBuffer, " ");
231 1.1 christos if (!Token)
232 1.1 christos {
233 1.1 christos goto ResetAndExit;
234 1.1 christos }
235 1.1 christos
236 1.1 christos /* First argument is the line number */
237 1.1 christos
238 1.1 christos LineNumber = (UINT32) UtDoConstant (Token);
239 1.1 christos
240 1.1 christos /* Emit the appropriate number of newlines */
241 1.1 christos
242 1.12 christos AslGbl_CurrentColumn = 0;
243 1.12 christos if (LineNumber > AslGbl_CurrentLineNumber)
244 1.1 christos {
245 1.12 christos for (i = 0; i < (LineNumber - AslGbl_CurrentLineNumber); i++)
246 1.1 christos {
247 1.1 christos FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
248 1.12 christos AslGbl_CurrentColumn++;
249 1.1 christos }
250 1.1 christos }
251 1.1 christos
252 1.1 christos FlSetLineNumber (LineNumber);
253 1.1 christos
254 1.1 christos /* Second argument is the optional filename (in double quotes) */
255 1.1 christos
256 1.1 christos Token = strtok (NULL, " \"");
257 1.1 christos if (Token)
258 1.1 christos {
259 1.12 christos Filename = UtLocalCacheCalloc (strlen (Token) + 1);
260 1.1 christos strcpy (Filename, Token);
261 1.1 christos FlSetFilename (Filename);
262 1.1 christos }
263 1.1 christos
264 1.1 christos /* Third argument is not supported at this time */
265 1.1 christos
266 1.1 christos ResetAndExit:
267 1.1 christos
268 1.1 christos /* Reset globals for a new line */
269 1.1 christos
270 1.12 christos AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
271 1.12 christos AslGbl_CurrentColumn = 0;
272 1.12 christos AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
273 1.1 christos }
274 1.1 christos
275 1.1 christos
276 1.1 christos /*******************************************************************************
277 1.1 christos *
278 1.1 christos * FUNCTION: AslPopInputFileStack
279 1.1 christos *
280 1.1 christos * PARAMETERS: None
281 1.1 christos *
282 1.1 christos * RETURN: 0 if a node was popped, -1 otherwise
283 1.1 christos *
284 1.1 christos * DESCRIPTION: Pop the top of the input file stack and point the parser to
285 1.1 christos * the saved parse buffer contained in the fnode. Also, set the
286 1.1 christos * global line counters to the saved values. This function is
287 1.1 christos * called when an include file reaches EOF.
288 1.1 christos *
289 1.1 christos ******************************************************************************/
290 1.1 christos
291 1.1 christos int
292 1.1 christos AslPopInputFileStack (
293 1.1 christos void)
294 1.1 christos {
295 1.1 christos ASL_FILE_NODE *Fnode;
296 1.1 christos
297 1.1 christos
298 1.12 christos AslGbl_PreviousIncludeFilename = AslGbl_Files[ASL_FILE_INPUT].Filename;
299 1.12 christos Fnode = AslGbl_IncludeFileStack;
300 1.4 christos DbgPrint (ASL_PARSE_OUTPUT,
301 1.6 christos "\nPop InputFile Stack, Fnode %p\n", Fnode);
302 1.6 christos
303 1.6 christos DbgPrint (ASL_PARSE_OUTPUT,
304 1.12 christos "Include: Closing \"%s\"\n\n", AslGbl_Files[ASL_FILE_INPUT].Filename);
305 1.1 christos
306 1.1 christos if (!Fnode)
307 1.1 christos {
308 1.1 christos return (-1);
309 1.1 christos }
310 1.1 christos
311 1.1 christos /* Close the current include file */
312 1.1 christos
313 1.1 christos fclose (yyin);
314 1.1 christos
315 1.1 christos /* Update the top-of-stack */
316 1.1 christos
317 1.12 christos AslGbl_IncludeFileStack = Fnode->Next;
318 1.1 christos
319 1.1 christos /* Reset global line counter and filename */
320 1.1 christos
321 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
322 1.12 christos AslGbl_CurrentLineNumber = Fnode->CurrentLineNumber;
323 1.1 christos
324 1.1 christos /* Point the parser to the popped file */
325 1.1 christos
326 1.1 christos yy_delete_buffer (YY_CURRENT_BUFFER);
327 1.1 christos yy_switch_to_buffer (Fnode->State);
328 1.1 christos
329 1.1 christos /* All done with this node */
330 1.1 christos
331 1.1 christos ACPI_FREE (Fnode);
332 1.1 christos return (0);
333 1.1 christos }
334 1.1 christos
335 1.1 christos
336 1.1 christos /*******************************************************************************
337 1.1 christos *
338 1.1 christos * FUNCTION: AslPushInputFileStack
339 1.1 christos *
340 1.1 christos * PARAMETERS: InputFile - Open file pointer
341 1.1 christos * Filename - Name of the file
342 1.1 christos *
343 1.1 christos * RETURN: None
344 1.1 christos *
345 1.1 christos * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
346 1.1 christos * to this file. Called when an include file is successfully
347 1.1 christos * opened.
348 1.1 christos *
349 1.1 christos ******************************************************************************/
350 1.1 christos
351 1.1 christos void
352 1.1 christos AslPushInputFileStack (
353 1.1 christos FILE *InputFile,
354 1.1 christos char *Filename)
355 1.1 christos {
356 1.1 christos ASL_FILE_NODE *Fnode;
357 1.1 christos YY_BUFFER_STATE State;
358 1.1 christos
359 1.1 christos
360 1.1 christos /* Save the current state in an Fnode */
361 1.1 christos
362 1.1 christos Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
363 1.1 christos
364 1.4 christos Fnode->File = yyin;
365 1.12 christos Fnode->Next = AslGbl_IncludeFileStack;
366 1.4 christos Fnode->State = YY_CURRENT_BUFFER;
367 1.12 christos Fnode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
368 1.12 christos Fnode->CurrentLineNumber = AslGbl_CurrentLineNumber;
369 1.1 christos
370 1.1 christos /* Push it on the stack */
371 1.1 christos
372 1.12 christos AslGbl_IncludeFileStack = Fnode;
373 1.1 christos
374 1.1 christos /* Point the parser to this file */
375 1.1 christos
376 1.1 christos State = yy_create_buffer (InputFile, YY_BUF_SIZE);
377 1.1 christos yy_switch_to_buffer (State);
378 1.1 christos
379 1.4 christos DbgPrint (ASL_PARSE_OUTPUT,
380 1.4 christos "\nPush InputFile Stack, returning %p\n\n", InputFile);
381 1.1 christos
382 1.1 christos /* Reset the global line count and filename */
383 1.1 christos
384 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename =
385 1.10 christos UtLocalCacheCalloc (strlen (Filename) + 1);
386 1.3 christos
387 1.12 christos strcpy (AslGbl_Files[ASL_FILE_INPUT].Filename, Filename);
388 1.3 christos
389 1.12 christos AslGbl_CurrentLineNumber = 1;
390 1.1 christos yyin = InputFile;
391 1.8 christos
392 1.8 christos /* converter: reset the comment state to STANDARD_COMMENT */
393 1.8 christos
394 1.12 christos AslGbl_CommentState.CommentType = STANDARD_COMMENT;
395 1.1 christos }
396 1.1 christos
397 1.1 christos
398 1.1 christos /*******************************************************************************
399 1.1 christos *
400 1.1 christos * FUNCTION: AslResetCurrentLineBuffer
401 1.1 christos *
402 1.1 christos * PARAMETERS: None
403 1.1 christos *
404 1.1 christos * RETURN: None
405 1.1 christos *
406 1.1 christos * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
407 1.1 christos *
408 1.1 christos ******************************************************************************/
409 1.1 christos
410 1.1 christos void
411 1.1 christos AslResetCurrentLineBuffer (
412 1.1 christos void)
413 1.1 christos {
414 1.1 christos
415 1.12 christos if (AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
416 1.1 christos {
417 1.12 christos FlWriteFile (ASL_FILE_SOURCE_OUTPUT, AslGbl_CurrentLineBuffer,
418 1.12 christos AslGbl_LineBufPtr - AslGbl_CurrentLineBuffer);
419 1.1 christos }
420 1.1 christos
421 1.12 christos AslGbl_CurrentLineOffset += AslGbl_CurrentColumn;
422 1.12 christos AslGbl_CurrentColumn = 0;
423 1.1 christos
424 1.12 christos AslGbl_CurrentLineNumber++;
425 1.12 christos AslGbl_LogicalLineNumber++;
426 1.12 christos AslGbl_LineBufPtr = AslGbl_CurrentLineBuffer;
427 1.1 christos }
428 1.1 christos
429 1.1 christos
430 1.1 christos /*******************************************************************************
431 1.1 christos *
432 1.1 christos * FUNCTION: AslInsertLineBuffer
433 1.1 christos *
434 1.4 christos * PARAMETERS: SourceChar - One char from the input ASL source file
435 1.1 christos *
436 1.1 christos * RETURN: None
437 1.1 christos *
438 1.1 christos * DESCRIPTION: Put one character of the source file into the temp line buffer
439 1.1 christos *
440 1.1 christos ******************************************************************************/
441 1.1 christos
442 1.1 christos void
443 1.1 christos AslInsertLineBuffer (
444 1.1 christos int SourceChar)
445 1.1 christos {
446 1.1 christos UINT32 i;
447 1.1 christos UINT32 Count = 1;
448 1.1 christos
449 1.1 christos
450 1.1 christos if (SourceChar == EOF)
451 1.1 christos {
452 1.1 christos return;
453 1.1 christos }
454 1.1 christos
455 1.12 christos AslGbl_InputByteCount++;
456 1.1 christos
457 1.1 christos /* Handle tabs. Convert to spaces */
458 1.1 christos
459 1.1 christos if (SourceChar == '\t')
460 1.1 christos {
461 1.1 christos SourceChar = ' ';
462 1.1 christos Count = ASL_SPACES_PER_TAB -
463 1.12 christos (AslGbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
464 1.1 christos }
465 1.1 christos
466 1.1 christos for (i = 0; i < Count; i++)
467 1.1 christos {
468 1.12 christos AslGbl_CurrentColumn++;
469 1.1 christos
470 1.1 christos /* Insert the character into the line buffer */
471 1.1 christos
472 1.12 christos *AslGbl_LineBufPtr = (UINT8) SourceChar;
473 1.12 christos AslGbl_LineBufPtr++;
474 1.1 christos
475 1.12 christos if (AslGbl_LineBufPtr >
476 1.12 christos (AslGbl_CurrentLineBuffer + (AslGbl_LineBufferSize - 1)))
477 1.1 christos {
478 1.1 christos #if 0
479 1.1 christos /*
480 1.1 christos * Warning if we have split a long source line.
481 1.1 christos * <Probably overkill>
482 1.1 christos */
483 1.12 christos snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "Max %u", Gbl_LineBufferSize);
484 1.1 christos AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
485 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
486 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
487 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
488 1.1 christos #endif
489 1.1 christos
490 1.1 christos AslResetCurrentLineBuffer ();
491 1.1 christos }
492 1.1 christos else if (SourceChar == '\n')
493 1.1 christos {
494 1.1 christos /* End of line */
495 1.1 christos
496 1.1 christos AslResetCurrentLineBuffer ();
497 1.1 christos }
498 1.8 christos
499 1.11 christos if (AcpiGbl_CaptureComments)
500 1.8 christos {
501 1.14 christos CvProcessCommentState ((char) SourceChar);
502 1.8 christos }
503 1.1 christos }
504 1.1 christos }
505 1.1 christos
506 1.1 christos
507 1.1 christos /*******************************************************************************
508 1.1 christos *
509 1.1 christos * FUNCTION: count
510 1.1 christos *
511 1.4 christos * PARAMETERS: yytext - Contains the matched keyword.
512 1.4 christos * Type - Keyword/Character type:
513 1.4 christos * 0 = anything except a keyword
514 1.4 christos * 1 = pseudo-keywords
515 1.4 christos * 2 = non-executable ASL keywords
516 1.4 christos * 3 = executable ASL keywords
517 1.1 christos *
518 1.1 christos * RETURN: None
519 1.1 christos *
520 1.1 christos * DESCRIPTION: Count keywords and put them into the line buffer
521 1.1 christos *
522 1.1 christos ******************************************************************************/
523 1.1 christos
524 1.1 christos static void
525 1.1 christos count (
526 1.1 christos int Type)
527 1.1 christos {
528 1.11 christos char *p;
529 1.1 christos
530 1.1 christos
531 1.1 christos switch (Type)
532 1.1 christos {
533 1.1 christos case 2:
534 1.1 christos
535 1.13 christos ++AslGbl_TotalKeywords;
536 1.13 christos ++AslGbl_TotalNamedObjects;
537 1.13 christos ++AslGbl_FilesList->TotalKeywords;
538 1.13 christos ++AslGbl_FilesList->TotalNamedObjects;
539 1.1 christos break;
540 1.1 christos
541 1.1 christos case 3:
542 1.1 christos
543 1.13 christos ++AslGbl_TotalKeywords;
544 1.13 christos ++AslGbl_TotalExecutableOpcodes;
545 1.13 christos ++AslGbl_FilesList->TotalKeywords;
546 1.13 christos ++AslGbl_FilesList->TotalExecutableOpcodes;
547 1.1 christos break;
548 1.1 christos
549 1.1 christos default:
550 1.1 christos
551 1.1 christos break;
552 1.1 christos }
553 1.1 christos
554 1.11 christos for (p = yytext; *p != '\0'; p++)
555 1.1 christos {
556 1.11 christos AslInsertLineBuffer (*p);
557 1.12 christos *AslGbl_LineBufPtr = 0;
558 1.1 christos }
559 1.1 christos }
560 1.1 christos
561 1.1 christos
562 1.1 christos /*******************************************************************************
563 1.1 christos *
564 1.1 christos * FUNCTION: AslDoComment
565 1.1 christos *
566 1.1 christos * PARAMETERS: none
567 1.1 christos *
568 1.1 christos * RETURN: none
569 1.1 christos *
570 1.1 christos * DESCRIPTION: Process a standard comment.
571 1.1 christos *
572 1.1 christos ******************************************************************************/
573 1.1 christos
574 1.8 christos static BOOLEAN
575 1.1 christos AslDoComment (
576 1.1 christos void)
577 1.1 christos {
578 1.8 christos int c;
579 1.8 christos int c1 = 0;
580 1.12 christos char *StringBuffer = AslGbl_MsgBuffer;
581 1.12 christos char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
582 1.12 christos ASL_COMMENT_STATE CurrentState = AslGbl_CommentState; /* to reference later on */
583 1.1 christos
584 1.1 christos
585 1.1 christos AslInsertLineBuffer ('/');
586 1.1 christos AslInsertLineBuffer ('*');
587 1.11 christos if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
588 1.8 christos {
589 1.8 christos *StringBuffer = '/';
590 1.8 christos ++StringBuffer;
591 1.8 christos *StringBuffer = '*';
592 1.8 christos ++StringBuffer;
593 1.8 christos }
594 1.1 christos
595 1.1 christos loop:
596 1.1 christos
597 1.1 christos /* Eat chars until end-of-comment */
598 1.1 christos
599 1.4 christos while (((c = input ()) != '*') && (c != EOF))
600 1.1 christos {
601 1.1 christos AslInsertLineBuffer (c);
602 1.11 christos if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
603 1.8 christos {
604 1.14 christos *StringBuffer = (char) c;
605 1.8 christos ++StringBuffer;
606 1.8 christos }
607 1.1 christos c1 = c;
608 1.1 christos }
609 1.1 christos
610 1.1 christos if (c == EOF)
611 1.1 christos {
612 1.1 christos goto EarlyEOF;
613 1.1 christos }
614 1.1 christos
615 1.1 christos /*
616 1.1 christos * Check for nested comment -- can help catch cases where a previous
617 1.13 christos * comment was accidentally left unterminated
618 1.1 christos */
619 1.1 christos if ((c1 == '/') && (c == '*'))
620 1.1 christos {
621 1.1 christos AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
622 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
623 1.12 christos AslGbl_InputByteCount, AslGbl_CurrentColumn,
624 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
625 1.1 christos }
626 1.1 christos
627 1.1 christos /* Comment is closed only if the NEXT character is a slash */
628 1.1 christos
629 1.1 christos AslInsertLineBuffer (c);
630 1.11 christos if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
631 1.8 christos {
632 1.14 christos *StringBuffer = (char) c;
633 1.8 christos ++StringBuffer;
634 1.8 christos }
635 1.1 christos
636 1.4 christos if (((c1 = input ()) != '/') && (c1 != EOF))
637 1.1 christos {
638 1.8 christos unput (c1);
639 1.1 christos goto loop;
640 1.1 christos }
641 1.1 christos
642 1.1 christos if (c1 == EOF)
643 1.1 christos {
644 1.1 christos goto EarlyEOF;
645 1.1 christos }
646 1.8 christos if (StringBuffer > EndBuffer)
647 1.8 christos {
648 1.8 christos goto BufferOverflow;
649 1.8 christos }
650 1.1 christos
651 1.1 christos AslInsertLineBuffer (c1);
652 1.8 christos CvProcessComment (CurrentState, StringBuffer, c1);
653 1.1 christos return (TRUE);
654 1.1 christos
655 1.1 christos
656 1.1 christos EarlyEOF:
657 1.1 christos /*
658 1.1 christos * Premature End-Of-File
659 1.1 christos */
660 1.1 christos AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
661 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
662 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
663 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
664 1.1 christos return (FALSE);
665 1.8 christos
666 1.8 christos
667 1.8 christos BufferOverflow:
668 1.8 christos
669 1.8 christos /* Comment was too long */
670 1.8 christos
671 1.8 christos AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
672 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
673 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
674 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
675 1.8 christos return (FALSE);
676 1.8 christos
677 1.1 christos }
678 1.1 christos
679 1.1 christos
680 1.1 christos /*******************************************************************************
681 1.1 christos *
682 1.1 christos * FUNCTION: AslDoCommentType2
683 1.1 christos *
684 1.1 christos * PARAMETERS: none
685 1.1 christos *
686 1.1 christos * RETURN: none
687 1.1 christos *
688 1.8 christos * DESCRIPTION: Process a new "//" comment. Inline comments will be converted
689 1.8 christos * to "/ *" standard comments.
690 1.1 christos *
691 1.1 christos ******************************************************************************/
692 1.1 christos
693 1.8 christos static BOOLEAN
694 1.1 christos AslDoCommentType2 (
695 1.1 christos void)
696 1.1 christos {
697 1.8 christos int c;
698 1.12 christos char *StringBuffer = AslGbl_MsgBuffer;
699 1.12 christos char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
700 1.12 christos ASL_COMMENT_STATE CurrentState = AslGbl_CommentState;
701 1.1 christos
702 1.1 christos
703 1.1 christos AslInsertLineBuffer ('/');
704 1.8 christos
705 1.11 christos if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
706 1.8 christos {
707 1.9 christos AslInsertLineBuffer ('*');
708 1.8 christos *StringBuffer = '/';
709 1.8 christos ++StringBuffer;
710 1.8 christos *StringBuffer = '*';
711 1.8 christos ++StringBuffer;
712 1.8 christos }
713 1.9 christos else
714 1.9 christos {
715 1.9 christos AslInsertLineBuffer ('/');
716 1.9 christos }
717 1.1 christos
718 1.4 christos while (((c = input ()) != '\n') && (c != EOF))
719 1.1 christos {
720 1.1 christos AslInsertLineBuffer (c);
721 1.11 christos if (AcpiGbl_CaptureComments && CurrentState.CaptureComments)
722 1.8 christos {
723 1.14 christos *StringBuffer = (char) c;
724 1.8 christos ++StringBuffer;
725 1.8 christos }
726 1.1 christos }
727 1.1 christos
728 1.1 christos if (c == EOF)
729 1.1 christos {
730 1.1 christos /* End of file is OK, change to newline. Let parser detect EOF later */
731 1.1 christos
732 1.1 christos c = '\n';
733 1.1 christos }
734 1.1 christos
735 1.8 christos if (StringBuffer > EndBuffer)
736 1.8 christos {
737 1.8 christos goto BufferOverflow;
738 1.8 christos }
739 1.1 christos AslInsertLineBuffer (c);
740 1.8 christos
741 1.8 christos CvProcessCommentType2 (CurrentState, StringBuffer);
742 1.1 christos return (TRUE);
743 1.8 christos
744 1.8 christos
745 1.8 christos BufferOverflow:
746 1.8 christos
747 1.8 christos /* Comment was too long */
748 1.8 christos
749 1.8 christos AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
750 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
751 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
752 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
753 1.8 christos return (FALSE);
754 1.8 christos
755 1.1 christos }
756 1.1 christos
757 1.1 christos
758 1.1 christos /*******************************************************************************
759 1.1 christos *
760 1.1 christos * FUNCTION: AslDoStringLiteral
761 1.1 christos *
762 1.1 christos * PARAMETERS: none
763 1.1 christos *
764 1.1 christos * RETURN: none
765 1.1 christos *
766 1.1 christos * DESCRIPTION: Process a string literal (surrounded by quotes)
767 1.1 christos *
768 1.1 christos ******************************************************************************/
769 1.1 christos
770 1.1 christos static char
771 1.1 christos AslDoStringLiteral (
772 1.1 christos void)
773 1.1 christos {
774 1.12 christos char *StringBuffer = AslGbl_MsgBuffer;
775 1.12 christos char *EndBuffer = AslGbl_MsgBuffer + ASL_MSG_BUFFER_SIZE;
776 1.1 christos char *CleanString;
777 1.1 christos int StringChar;
778 1.1 christos UINT32 State = ASL_NORMAL_CHAR;
779 1.1 christos UINT32 i = 0;
780 1.1 christos UINT8 Digit;
781 1.1 christos char ConvertBuffer[4];
782 1.1 christos
783 1.1 christos
784 1.1 christos /*
785 1.1 christos * Eat chars until end-of-literal.
786 1.1 christos * NOTE: Put back the original surrounding quotes into the
787 1.1 christos * source line buffer.
788 1.1 christos */
789 1.1 christos AslInsertLineBuffer ('\"');
790 1.1 christos while ((StringChar = input()) != EOF)
791 1.1 christos {
792 1.1 christos AslInsertLineBuffer (StringChar);
793 1.1 christos
794 1.1 christos DoCharacter:
795 1.1 christos switch (State)
796 1.1 christos {
797 1.1 christos case ASL_NORMAL_CHAR:
798 1.1 christos
799 1.1 christos switch (StringChar)
800 1.1 christos {
801 1.1 christos case '\\':
802 1.1 christos /*
803 1.1 christos * Special handling for backslash-escape sequence. We will
804 1.1 christos * toss the backslash and translate the escape char(s).
805 1.1 christos */
806 1.1 christos State = ASL_ESCAPE_SEQUENCE;
807 1.1 christos continue;
808 1.1 christos
809 1.1 christos case '\"':
810 1.1 christos
811 1.1 christos /* String terminator */
812 1.1 christos
813 1.1 christos goto CompletedString;
814 1.1 christos
815 1.1 christos default:
816 1.1 christos
817 1.1 christos break;
818 1.1 christos }
819 1.1 christos break;
820 1.1 christos
821 1.1 christos
822 1.1 christos case ASL_ESCAPE_SEQUENCE:
823 1.1 christos
824 1.1 christos State = ASL_NORMAL_CHAR;
825 1.1 christos switch (StringChar)
826 1.1 christos {
827 1.1 christos case 'a':
828 1.1 christos
829 1.1 christos StringChar = 0x07; /* BELL */
830 1.1 christos break;
831 1.1 christos
832 1.1 christos case 'b':
833 1.1 christos
834 1.1 christos StringChar = 0x08; /* BACKSPACE */
835 1.1 christos break;
836 1.1 christos
837 1.1 christos case 'f':
838 1.1 christos
839 1.1 christos StringChar = 0x0C; /* FORMFEED */
840 1.1 christos break;
841 1.1 christos
842 1.1 christos case 'n':
843 1.1 christos
844 1.1 christos StringChar = 0x0A; /* LINEFEED */
845 1.1 christos break;
846 1.1 christos
847 1.1 christos case 'r':
848 1.1 christos
849 1.1 christos StringChar = 0x0D; /* CARRIAGE RETURN*/
850 1.1 christos break;
851 1.1 christos
852 1.1 christos case 't':
853 1.1 christos
854 1.1 christos StringChar = 0x09; /* HORIZONTAL TAB */
855 1.1 christos break;
856 1.1 christos
857 1.1 christos case 'v':
858 1.1 christos
859 1.1 christos StringChar = 0x0B; /* VERTICAL TAB */
860 1.1 christos break;
861 1.1 christos
862 1.1 christos case 'x':
863 1.1 christos
864 1.1 christos State = ASL_HEX_CONSTANT;
865 1.1 christos i = 0;
866 1.1 christos continue;
867 1.1 christos
868 1.1 christos case '\'': /* Single Quote */
869 1.1 christos case '\"': /* Double Quote */
870 1.1 christos case '\\': /* Backslash */
871 1.1 christos
872 1.1 christos break;
873 1.1 christos
874 1.1 christos default:
875 1.1 christos
876 1.1 christos /* Check for an octal digit (0-7) */
877 1.1 christos
878 1.1 christos if (ACPI_IS_OCTAL_DIGIT (StringChar))
879 1.1 christos {
880 1.1 christos State = ASL_OCTAL_CONSTANT;
881 1.14 christos ConvertBuffer[0] = (char) StringChar;
882 1.1 christos i = 1;
883 1.1 christos continue;
884 1.1 christos }
885 1.1 christos
886 1.1 christos /* Unknown escape sequence issue warning, but use the character */
887 1.1 christos
888 1.1 christos AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
889 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
890 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
891 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
892 1.1 christos break;
893 1.1 christos }
894 1.1 christos break;
895 1.1 christos
896 1.1 christos
897 1.1 christos case ASL_OCTAL_CONSTANT:
898 1.1 christos
899 1.1 christos /* Up to three octal digits allowed */
900 1.1 christos
901 1.1 christos if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
902 1.1 christos (i > 2))
903 1.1 christos {
904 1.1 christos /*
905 1.1 christos * Reached end of the constant. Convert the assembled ASCII
906 1.1 christos * string and resume processing of the next character
907 1.1 christos */
908 1.1 christos ConvertBuffer[i] = 0;
909 1.5 christos Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);
910 1.1 christos
911 1.1 christos /* Check for NULL or non-ascii character (ignore if so) */
912 1.1 christos
913 1.1 christos if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
914 1.1 christos {
915 1.1 christos AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
916 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
917 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
918 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
919 1.1 christos }
920 1.1 christos else
921 1.1 christos {
922 1.1 christos *StringBuffer = (char) Digit;
923 1.1 christos StringBuffer++;
924 1.1 christos if (StringBuffer >= EndBuffer)
925 1.1 christos {
926 1.1 christos goto BufferOverflow;
927 1.1 christos }
928 1.1 christos }
929 1.1 christos
930 1.1 christos State = ASL_NORMAL_CHAR;
931 1.1 christos goto DoCharacter;
932 1.1 christos break;
933 1.1 christos }
934 1.1 christos
935 1.1 christos /* Append another digit of the constant */
936 1.1 christos
937 1.14 christos ConvertBuffer[i] = (char) StringChar;
938 1.1 christos i++;
939 1.1 christos continue;
940 1.1 christos
941 1.1 christos case ASL_HEX_CONSTANT:
942 1.1 christos
943 1.1 christos /* Up to two hex digits allowed */
944 1.1 christos
945 1.5 christos if (!isxdigit (StringChar) ||
946 1.1 christos (i > 1))
947 1.1 christos {
948 1.1 christos /*
949 1.1 christos * Reached end of the constant. Convert the assembled ASCII
950 1.1 christos * string and resume processing of the next character
951 1.1 christos */
952 1.1 christos ConvertBuffer[i] = 0;
953 1.5 christos Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);
954 1.1 christos
955 1.1 christos /* Check for NULL or non-ascii character (ignore if so) */
956 1.1 christos
957 1.1 christos if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
958 1.1 christos {
959 1.1 christos AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
960 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
961 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
962 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
963 1.1 christos }
964 1.1 christos else
965 1.1 christos {
966 1.1 christos *StringBuffer = (char) Digit;
967 1.1 christos StringBuffer++;
968 1.1 christos if (StringBuffer >= EndBuffer)
969 1.1 christos {
970 1.1 christos goto BufferOverflow;
971 1.1 christos }
972 1.1 christos }
973 1.1 christos
974 1.1 christos State = ASL_NORMAL_CHAR;
975 1.1 christos goto DoCharacter;
976 1.1 christos break;
977 1.1 christos }
978 1.1 christos
979 1.1 christos /* Append another digit of the constant */
980 1.1 christos
981 1.14 christos ConvertBuffer[i] = (char) StringChar;
982 1.1 christos i++;
983 1.1 christos continue;
984 1.1 christos
985 1.1 christos default:
986 1.1 christos
987 1.1 christos break;
988 1.1 christos }
989 1.1 christos
990 1.1 christos /* Save the finished character */
991 1.1 christos
992 1.14 christos *StringBuffer = (char) StringChar;
993 1.1 christos StringBuffer++;
994 1.1 christos if (StringBuffer >= EndBuffer)
995 1.1 christos {
996 1.1 christos goto BufferOverflow;
997 1.1 christos }
998 1.1 christos }
999 1.1 christos
1000 1.1 christos /*
1001 1.1 christos * Premature End-Of-File
1002 1.1 christos */
1003 1.1 christos AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
1004 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
1005 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
1006 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, NULL);
1007 1.1 christos return (FALSE);
1008 1.1 christos
1009 1.1 christos
1010 1.1 christos CompletedString:
1011 1.1 christos /*
1012 1.1 christos * Null terminate the input string and copy string to a new buffer
1013 1.1 christos */
1014 1.1 christos *StringBuffer = 0;
1015 1.1 christos
1016 1.12 christos CleanString = UtLocalCacheCalloc (strlen (AslGbl_MsgBuffer) + 1);
1017 1.12 christos strcpy (CleanString, AslGbl_MsgBuffer);
1018 1.1 christos AslCompilerlval.s = CleanString;
1019 1.1 christos return (TRUE);
1020 1.1 christos
1021 1.1 christos
1022 1.1 christos BufferOverflow:
1023 1.1 christos
1024 1.1 christos /* Literal was too long */
1025 1.1 christos
1026 1.1 christos AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
1027 1.12 christos AslGbl_CurrentLineNumber, AslGbl_LogicalLineNumber,
1028 1.12 christos AslGbl_CurrentLineOffset, AslGbl_CurrentColumn,
1029 1.12 christos AslGbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
1030 1.1 christos return (FALSE);
1031 1.1 christos }
1032