diff options
Diffstat (limited to 'sys/contrib/dev/acpica/compiler/prscan.c')
-rw-r--r-- | sys/contrib/dev/acpica/compiler/prscan.c | 246 |
1 files changed, 215 insertions, 31 deletions
diff --git a/sys/contrib/dev/acpica/compiler/prscan.c b/sys/contrib/dev/acpica/compiler/prscan.c index 12d303c..c02280d 100644 --- a/sys/contrib/dev/acpica/compiler/prscan.c +++ b/sys/contrib/dev/acpica/compiler/prscan.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2015, Intel Corp. + * Copyright (C) 2000 - 2016, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,6 +67,14 @@ PrDoDirective ( char *DirectiveToken, char **Next); +static void +PrGetNextLineInit ( + void); + +static UINT32 +PrGetNextLine ( + FILE *Handle); + static int PrMatchDirective ( char *Directive); @@ -112,7 +120,6 @@ static const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = {"include", 0}, /* Argument is not standard format, so just use 0 here */ {"includebuffer", 0}, /* Argument is not standard format, so just use 0 here */ {"line", 1}, - {"loadbuffer", 0}, {"pragma", 1}, {"undef", 1}, {"warning", 1}, @@ -136,7 +143,7 @@ enum Gbl_DirectiveIndexes PR_DIRECTIVE_LINE, PR_DIRECTIVE_PRAGMA, PR_DIRECTIVE_UNDEF, - PR_DIRECTIVE_WARNING, + PR_DIRECTIVE_WARNING }; #define ASL_DIRECTIVE_NOT_FOUND -1 @@ -186,7 +193,7 @@ PrInitializeGlobals ( /* Init globals */ Gbl_InputFileList = NULL; - Gbl_CurrentLineNumber = 0; + Gbl_CurrentLineNumber = 1; Gbl_PreprocessorLineNumber = 1; Gbl_PreprocessorError = FALSE; @@ -271,7 +278,7 @@ PrDoPreprocess ( } while (MoreInputFiles); - /* Point compiler input to the new preprocessor output file (.i) */ + /* Point compiler input to the new preprocessor output file (.pre) */ FlCloseFile (ASL_FILE_INPUT); Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; @@ -280,7 +287,10 @@ PrDoPreprocess ( /* Reset globals to allow compiler to run */ FlSeekFile (ASL_FILE_INPUT, 0); - Gbl_CurrentLineNumber = 1; + if (!Gbl_PreprocessOnly) + { + Gbl_CurrentLineNumber = 0; + } DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); } @@ -297,7 +307,8 @@ PrDoPreprocess ( * DESCRIPTION: Preprocess one entire file, line-by-line. * * Input: Raw user ASL from ASL_FILE_INPUT - * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR + * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and + * (optionally) ASL_FILE_PREPROCESSOR_USER * ******************************************************************************/ @@ -305,7 +316,7 @@ static void PrPreprocessInputFile ( void) { - UINT32 Offset; + UINT32 Status; char *Token; char *ReplaceString; PR_DEFINE_INFO *DefineInfo; @@ -314,10 +325,20 @@ PrPreprocessInputFile ( int OffsetAdjust; - /* Scan line-by-line. Comments and blank lines are skipped by this function */ + PrGetNextLineInit (); + + /* Scan source line-by-line and process directives. Then write the .i file */ - while ((Offset = DtGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) + while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) { + Gbl_CurrentLineNumber++; + Gbl_LogicalLineNumber++; + + if (Status == ASL_IGNORE_LINE) + { + goto WriteEntireLine; + } + /* Need a copy of the input line for strok() */ strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); @@ -397,24 +418,13 @@ PrPreprocessInputFile ( Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); } - /* - * Emit a #line directive if necessary, to keep the line numbers in - * the (.i) file synchronized with the original source code file, so - * that the correct line number appears in any error messages - * generated by the actual compiler. - */ - if (Gbl_CurrentLineNumber > (Gbl_PreviousLineNumber + 1)) - { - FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u\n", - Gbl_CurrentLineNumber); - } - - Gbl_PreviousLineNumber = Gbl_CurrentLineNumber; Gbl_PreprocessorLineNumber++; + +WriteEntireLine: /* * Now we can write the possibly modified source line to the - * preprocessor (.i) file + * preprocessor file(s). */ FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, strlen (Gbl_CurrentLineBuffer)); @@ -467,6 +477,16 @@ PrDoDirective ( } /* + * Emit a line directive into the preprocessor file (.pre) after + * every matched directive. This is passed through to the compiler + * so that error/warning messages are kept in sync with the + * original source file. + */ + FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n", + Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename, + Gbl_DirectiveInfo[Directive].Name); + + /* * If we are currently ignoring this block and we encounter a #else or * #elif, we must ignore their blocks also if the parent block is also * being ignored. @@ -478,7 +498,8 @@ PrDoDirective ( case PR_DIRECTIVE_ELSE: case PR_DIRECTIVE_ELIF: - if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock) + if (Gbl_DirectiveStack && + Gbl_DirectiveStack->IgnoringThisCodeBlock) { PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); return; @@ -653,8 +674,9 @@ PrDoDirective ( if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') { #ifndef MACROS_SUPPORTED - AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n", - Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber); + AcpiOsPrintf ( + "%s ERROR - line %u: #define macros are not supported yet\n", + Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber); exit(1); #else PrAddMacro (Token, Next); @@ -671,11 +693,13 @@ PrDoDirective ( { Token2++; } + End = Token2; while (*End != '\n') { End++; } + *End = 0; } else @@ -691,7 +715,7 @@ PrDoDirective ( #endif DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "New #define: %s->%s\n", - Gbl_CurrentLineNumber, Token, Token2); + Gbl_LogicalLineNumber, Token, Token2); PrAddDefine (Token, Token2, FALSE); } @@ -760,10 +784,7 @@ PrDoDirective ( "User #line invocation %s\n", Gbl_CurrentLineNumber, Token); - /* Update local line numbers */ - Gbl_CurrentLineNumber = (UINT32) Value; - Gbl_PreviousLineNumber = 0; /* Emit #line into the preprocessor file */ @@ -816,6 +837,9 @@ PrDoDirective ( PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); + + Gbl_SourceLine = 0; + Gbl_NextError = Gbl_ErrorLog; break; default: @@ -839,6 +863,166 @@ SyntaxError: /******************************************************************************* * + * FUNCTION: PrGetNextLine, PrGetNextLineInit + * + * PARAMETERS: Handle - Open file handle for the source file + * + * RETURN: Status of the GetLine operation: + * AE_OK - Normal line, OK status + * ASL_IGNORE_LINE - Line is blank or part of a multi-line + * comment + * ASL_EOF - End-of-file reached + * + * DESCRIPTION: Get the next text line from the input file. Does not strip + * comments. + * + ******************************************************************************/ + +#define PR_NORMAL_TEXT 0 +#define PR_MULTI_LINE_COMMENT 1 +#define PR_SINGLE_LINE_COMMENT 2 +#define PR_QUOTED_STRING 3 + +static UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT; + +static void +PrGetNextLineInit ( + void) +{ + AcpiGbl_LineScanState = 0; +} + +static UINT32 +PrGetNextLine ( + FILE *Handle) +{ + UINT32 i; + int c = 0; + int PreviousChar; + + + /* Always clear the global line buffer */ + + memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize); + for (i = 0; ;) + { + /* + * If line is too long, expand the line buffers. Also increases + * Gbl_LineBufferSize. + */ + if (i >= Gbl_LineBufferSize) + { + UtExpandLineBuffers (); + } + + PreviousChar = c; + c = getc (Handle); + if (c == EOF) + { + /* + * On EOF: If there is anything in the line buffer, terminate + * it with a newline, and catch the EOF on the next call + * to this function. + */ + if (i > 0) + { + Gbl_CurrentLineBuffer[i] = '\n'; + return (AE_OK); + } + + return (ASL_EOF); + } + + /* Update state machine as necessary */ + + switch (AcpiGbl_LineScanState) + { + case PR_NORMAL_TEXT: + + /* Check for multi-line comment start */ + + if ((PreviousChar == '/') && (c == '*')) + { + AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT; + } + + /* Check for single-line comment start */ + + else if ((PreviousChar == '/') && (c == '/')) + { + AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT; + } + + /* Check for quoted string start */ + + else if (PreviousChar == '"') + { + AcpiGbl_LineScanState = PR_QUOTED_STRING; + } + break; + + case PR_QUOTED_STRING: + + if (PreviousChar == '"') + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + } + break; + + case PR_MULTI_LINE_COMMENT: + + /* Check for multi-line comment end */ + + if ((PreviousChar == '*') && (c == '/')) + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + } + break; + + case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */ + default: + break; + } + + /* Always copy the character into line buffer */ + + Gbl_CurrentLineBuffer[i] = (char) c; + i++; + + /* Always exit on end-of-line */ + + if (c == '\n') + { + /* Handle multi-line comments */ + + if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT) + { + return (ASL_IGNORE_LINE); + } + + /* End of single-line comment */ + + if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT) + { + AcpiGbl_LineScanState = PR_NORMAL_TEXT; + return (AE_OK); + } + + /* Blank line */ + + if (i == 1) + { + return (ASL_IGNORE_LINE); + } + + return (AE_OK); + } + } +} + + +/******************************************************************************* + * * FUNCTION: PrMatchDirective * * PARAMETERS: Directive - Pointer to directive name token |