1 /******************************************************************************
3 * Module Name: aslsupport.l - Flex/lex scanner C support routines.
4 * NOTE: Included into aslcompile.l, not compiled by itself.
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2014, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
47 #define ASL_SPACES_PER_TAB 4
49 #define ASL_NORMAL_CHAR 0
50 #define ASL_ESCAPE_SEQUENCE 1
51 #define ASL_OCTAL_CONSTANT 2
52 #define ASL_HEX_CONSTANT 3
55 /* File node - used for "Include" operator file stack */
57 typedef struct asl_file_node
60 UINT32 CurrentLineNumber;
61 YY_BUFFER_STATE State;
63 struct asl_file_node *Next;
67 /* File stack for the "Include" operator (NOT #include operator) */
69 ASL_FILE_NODE *Gbl_IncludeFileStack = NULL;
77 yy_delete_buffer (YY_CURRENT_BUFFER);
81 /*******************************************************************************
83 * FUNCTION: AslDoLineDirective
85 * PARAMETERS: None. Uses input() to access current source code line
87 * RETURN: Updates global line number and filename
89 * DESCRIPTION: Handle #line directives emitted by the preprocessor.
91 * The #line directive is emitted by the preprocesser, and is used to
92 * pass through line numbers from the original source code file to the
93 * preprocessor output file (.i). This allows any compiler-generated
94 * error messages to be displayed with the correct line number.
96 ******************************************************************************/
109 /* Eat the entire line that contains the #line directive */
111 Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
113 while ((c = input()) != '\n' && c != EOF)
120 /* First argument is the actual line number */
122 Token = strtok (Gbl_CurrentLineBuffer, " ");
128 /* First argument is the line number */
130 LineNumber = (UINT32) UtDoConstant (Token);
132 /* Emit the appropriate number of newlines */
134 Gbl_CurrentColumn = 0;
135 if (LineNumber > Gbl_CurrentLineNumber)
137 for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
139 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
144 FlSetLineNumber (LineNumber);
146 /* Second argument is the optional filename (in double quotes) */
148 Token = strtok (NULL, " \"");
151 Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
152 strcpy (Filename, Token);
153 FlSetFilename (Filename);
156 /* Third argument is not supported at this time */
160 /* Reset globals for a new line */
162 Gbl_CurrentLineOffset += Gbl_CurrentColumn;
163 Gbl_CurrentColumn = 0;
164 Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
168 /*******************************************************************************
170 * FUNCTION: AslPopInputFileStack
174 * RETURN: 0 if a node was popped, -1 otherwise
176 * DESCRIPTION: Pop the top of the input file stack and point the parser to
177 * the saved parse buffer contained in the fnode. Also, set the
178 * global line counters to the saved values. This function is
179 * called when an include file reaches EOF.
181 ******************************************************************************/
184 AslPopInputFileStack (
187 ASL_FILE_NODE *Fnode;
190 Fnode = Gbl_IncludeFileStack;
191 DbgPrint (ASL_PARSE_OUTPUT, "\nPop InputFile Stack, Fnode %p\n\n", Fnode);
198 /* Close the current include file */
202 /* Update the top-of-stack */
204 Gbl_IncludeFileStack = Fnode->Next;
206 /* Reset global line counter and filename */
208 Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
209 Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;
211 /* Point the parser to the popped file */
213 yy_delete_buffer (YY_CURRENT_BUFFER);
214 yy_switch_to_buffer (Fnode->State);
216 /* All done with this node */
223 /*******************************************************************************
225 * FUNCTION: AslPushInputFileStack
227 * PARAMETERS: InputFile - Open file pointer
228 * Filename - Name of the file
232 * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
233 * to this file. Called when an include file is successfully
236 ******************************************************************************/
239 AslPushInputFileStack (
243 ASL_FILE_NODE *Fnode;
244 YY_BUFFER_STATE State;
247 /* Save the current state in an Fnode */
249 Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));
252 Fnode->Next = Gbl_IncludeFileStack;
253 Fnode->State = YY_CURRENT_BUFFER;
254 Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;
255 Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
257 /* Push it on the stack */
259 Gbl_IncludeFileStack = Fnode;
261 /* Point the parser to this file */
263 State = yy_create_buffer (InputFile, YY_BUF_SIZE);
264 yy_switch_to_buffer (State);
266 DbgPrint (ASL_PARSE_OUTPUT, "\nPush InputFile Stack, returning %p\n\n", InputFile);
268 /* Reset the global line count and filename */
270 Gbl_Files[ASL_FILE_INPUT].Filename =
271 UtStringCacheCalloc (strlen (Filename) + 1);
273 strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);
275 Gbl_CurrentLineNumber = 1;
280 /*******************************************************************************
282 * FUNCTION: AslResetCurrentLineBuffer
288 * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
290 ******************************************************************************/
293 AslResetCurrentLineBuffer (
297 if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
299 FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
300 Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
303 Gbl_CurrentLineOffset += Gbl_CurrentColumn;
304 Gbl_CurrentColumn = 0;
306 Gbl_CurrentLineNumber++;
307 Gbl_LogicalLineNumber++;
308 Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
312 /*******************************************************************************
314 * FUNCTION: AslInsertLineBuffer
316 * PARAMETERS: SourceChar - One char from the input ASL source file
320 * DESCRIPTION: Put one character of the source file into the temp line buffer
322 ******************************************************************************/
325 AslInsertLineBuffer (
332 if (SourceChar == EOF)
337 Gbl_InputByteCount++;
339 /* Handle tabs. Convert to spaces */
341 if (SourceChar == '\t')
344 Count = ASL_SPACES_PER_TAB -
345 (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
348 for (i = 0; i < Count; i++)
352 /* Insert the character into the line buffer */
354 *Gbl_LineBufPtr = (UINT8) SourceChar;
357 if (Gbl_LineBufPtr > (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
361 * Warning if we have split a long source line.
362 * <Probably overkill>
364 sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
365 AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
366 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
367 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
368 Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
371 AslResetCurrentLineBuffer ();
373 else if (SourceChar == '\n')
377 AslResetCurrentLineBuffer ();
383 /*******************************************************************************
387 * PARAMETERS: yytext - Contains the matched keyword.
388 * Type - Keyword/Character type:
389 * 0 = anything except a keyword
390 * 1 = pseudo-keywords
391 * 2 = non-executable ASL keywords
392 * 3 = executable ASL keywords
396 * DESCRIPTION: Count keywords and put them into the line buffer
398 ******************************************************************************/
418 TotalExecutableOpcodes++;
426 for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
428 AslInsertLineBuffer (yytext[i]);
434 /*******************************************************************************
436 * FUNCTION: AslDoComment
442 * DESCRIPTION: Process a standard comment.
444 ******************************************************************************/
454 AslInsertLineBuffer ('/');
455 AslInsertLineBuffer ('*');
459 /* Eat chars until end-of-comment */
461 while ((c = input()) != '*' && c != EOF)
463 AslInsertLineBuffer (c);
473 * Check for nested comment -- can help catch cases where a previous
474 * comment was accidently left unterminated
476 if ((c1 == '/') && (c == '*'))
478 AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
479 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
480 Gbl_InputByteCount, Gbl_CurrentColumn,
481 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
484 /* Comment is closed only if the NEXT character is a slash */
486 AslInsertLineBuffer (c);
488 if ((c1 = input()) != '/' && c1 != EOF)
499 AslInsertLineBuffer (c1);
505 * Premature End-Of-File
507 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
508 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
509 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
510 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
515 /*******************************************************************************
517 * FUNCTION: AslDoCommentType2
523 * DESCRIPTION: Process a new "//" comment.
525 ******************************************************************************/
534 AslInsertLineBuffer ('/');
535 AslInsertLineBuffer ('/');
537 while ((c = input()) != '\n' && c != EOF)
539 AslInsertLineBuffer (c);
544 /* End of file is OK, change to newline. Let parser detect EOF later */
549 AslInsertLineBuffer (c);
554 /*******************************************************************************
556 * FUNCTION: AslDoStringLiteral
562 * DESCRIPTION: Process a string literal (surrounded by quotes)
564 ******************************************************************************/
570 char *StringBuffer = MsgBuffer;
571 char *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
574 UINT32 State = ASL_NORMAL_CHAR;
577 char ConvertBuffer[4];
581 * Eat chars until end-of-literal.
582 * NOTE: Put back the original surrounding quotes into the
583 * source line buffer.
585 AslInsertLineBuffer ('\"');
586 while ((StringChar = input()) != EOF)
588 AslInsertLineBuffer (StringChar);
593 case ASL_NORMAL_CHAR:
599 * Special handling for backslash-escape sequence. We will
600 * toss the backslash and translate the escape char(s).
602 State = ASL_ESCAPE_SEQUENCE;
607 /* String terminator */
609 goto CompletedString;
618 case ASL_ESCAPE_SEQUENCE:
620 State = ASL_NORMAL_CHAR;
625 StringChar = 0x07; /* BELL */
630 StringChar = 0x08; /* BACKSPACE */
635 StringChar = 0x0C; /* FORMFEED */
640 StringChar = 0x0A; /* LINEFEED */
645 StringChar = 0x0D; /* CARRIAGE RETURN*/
650 StringChar = 0x09; /* HORIZONTAL TAB */
655 StringChar = 0x0B; /* VERTICAL TAB */
660 State = ASL_HEX_CONSTANT;
664 case '\'': /* Single Quote */
665 case '\"': /* Double Quote */
666 case '\\': /* Backslash */
672 /* Check for an octal digit (0-7) */
674 if (ACPI_IS_OCTAL_DIGIT (StringChar))
676 State = ASL_OCTAL_CONSTANT;
677 ConvertBuffer[0] = StringChar;
682 /* Unknown escape sequence issue warning, but use the character */
684 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
685 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
686 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
687 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
693 case ASL_OCTAL_CONSTANT:
695 /* Up to three octal digits allowed */
697 if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
701 * Reached end of the constant. Convert the assembled ASCII
702 * string and resume processing of the next character
704 ConvertBuffer[i] = 0;
705 Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 8);
707 /* Check for NULL or non-ascii character (ignore if so) */
709 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
711 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
712 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
713 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
714 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
718 *StringBuffer = (char) Digit;
720 if (StringBuffer >= EndBuffer)
726 State = ASL_NORMAL_CHAR;
731 /* Append another digit of the constant */
733 ConvertBuffer[i] = StringChar;
737 case ASL_HEX_CONSTANT:
739 /* Up to two hex digits allowed */
741 if (!ACPI_IS_XDIGIT (StringChar) ||
745 * Reached end of the constant. Convert the assembled ASCII
746 * string and resume processing of the next character
748 ConvertBuffer[i] = 0;
749 Digit = (UINT8) ACPI_STRTOUL (ConvertBuffer, NULL, 16);
751 /* Check for NULL or non-ascii character (ignore if so) */
753 if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
755 AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
756 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
757 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
758 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
762 *StringBuffer = (char) Digit;
764 if (StringBuffer >= EndBuffer)
770 State = ASL_NORMAL_CHAR;
775 /* Append another digit of the constant */
777 ConvertBuffer[i] = StringChar;
786 /* Save the finished character */
788 *StringBuffer = StringChar;
790 if (StringBuffer >= EndBuffer)
797 * Premature End-Of-File
799 AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
800 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
801 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
802 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
808 * Null terminate the input string and copy string to a new buffer
812 CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
815 AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
816 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
817 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
818 Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
822 ACPI_STRCPY (CleanString, MsgBuffer);
823 AslCompilerlval.s = CleanString;
829 /* Literal was too long */
831 AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
832 Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
833 Gbl_CurrentLineOffset, Gbl_CurrentColumn,
834 Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");