ACPI_STATUS CmDoCompile ( void) { UINT8 FullCompile; UINT8 Event; ASL_GLOBAL_FILE_NODE *FileNode; FullCompile = UtBeginEvent ("*** Total Compile time ***"); Event = UtBeginEvent ("Open input and output files"); UtEndEvent (Event); Event = UtBeginEvent ("Preprocess input file"); if (AslGbl_PreprocessFlag) { /* Enter compiler name as a #define */ PrAddDefine (ASL_DEFINE, "", FALSE); /* Preprocessor */ PrDoPreprocess (); AslGbl_CurrentLineNumber = 1; AslGbl_LogicalLineNumber = 1; if (AslGbl_PreprocessOnly) { UtEndEvent (Event); CmCleanupAndExit (); return (AE_OK); } } UtEndEvent (Event); /* Build the parse tree */ Event = UtBeginEvent ("Parse source code and build parse tree"); AslCompilerparse(); UtEndEvent (Event); /* Check for parser-detected syntax errors */ if (AslGbl_SyntaxError) { fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n"); /* Flag this error in the FileNode for compilation summary */ FileNode = FlGetCurrentFileNode (); FileNode->ParserErrorDetected = TRUE; AslGbl_ParserErrorDetected = TRUE; LsDumpParseTree (); goto ErrorExit; } /* Did the parse tree get successfully constructed? */ if (!AslGbl_ParseTreeRoot) { /* * If there are no errors, then we have some sort of * internal problem. */ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, "- Could not resolve parse tree root node"); goto ErrorExit; } /* Flush out any remaining source after parse tree is complete */ Event = UtBeginEvent ("Flush source input"); CmFlushSourceCode (); /* Prune the parse tree if requested (debug purposes only) */ if (AslGbl_PruneParseTree) { AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType); } /* Optional parse tree dump, compiler debug output only */ LsDumpParseTree (); OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child); UtEndEvent (Event); /* Pre-process parse tree for any operator transforms */ Event = UtBeginEvent ("Parse tree transforms"); DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL); UtEndEvent (Event); /* Generate AML opcodes corresponding to the parse tokens */ Event = UtBeginEvent ("Generate AML opcodes"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlOpcodeWalk, NULL); UtEndEvent (Event); UtEndEvent (FullCompile); return (AE_OK); ErrorExit: UtEndEvent (FullCompile); return (AE_ERROR); }
static void PrDoDirective ( char *DirectiveToken, char **Next) { char *Token = Gbl_MainTokenBuffer; char *Token2 = NULL; char *End; UINT64 Value; ACPI_SIZE TokenOffset; int Directive; ACPI_STATUS Status; if (!DirectiveToken) { goto SyntaxError; } Directive = PrMatchDirective (DirectiveToken); if (Directive == ASL_DIRECTIVE_NOT_FOUND) { PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, THIS_TOKEN_OFFSET (DirectiveToken)); DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "#%s: Unknown directive\n", Gbl_CurrentLineNumber, DirectiveToken); return; } /* * 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. */ if (Gbl_IgnoringThisCodeBlock) { switch (Directive) { case PR_DIRECTIVE_ELSE: case PR_DIRECTIVE_ELIF: if (Gbl_DirectiveStack && Gbl_DirectiveStack->IgnoringThisCodeBlock) { PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); return; } break; default: break; } } /* * Need to always check for #else, #elif, #endif regardless of * whether we are ignoring the current code block, since these * are conditional code block terminators. */ switch (Directive) { case PR_DIRECTIVE_ELSE: Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); PrDbgPrint ("Executing", "else block"); return; case PR_DIRECTIVE_ELIF: Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); Directive = PR_DIRECTIVE_IF; if (Gbl_IgnoringThisCodeBlock == TRUE) { /* Not executing the ELSE part -- all done here */ PrDbgPrint ("Ignoring", "elif block"); return; } /* * After this, we will execute the IF part further below. * First, however, pop off the original #if directive. */ if (ACPI_FAILURE (PrPopDirective ())) { PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, THIS_TOKEN_OFFSET (DirectiveToken)); } PrDbgPrint ("Executing", "elif block"); break; case PR_DIRECTIVE_ENDIF: PrDbgPrint ("Executing", "endif"); /* Pop the owning #if/#ifdef/#ifndef */ if (ACPI_FAILURE (PrPopDirective ())) { PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, THIS_TOKEN_OFFSET (DirectiveToken)); } return; default: break; } /* Most directives have at least one argument */ if (Gbl_DirectiveInfo[Directive].ArgCount >= 1) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token) { goto SyntaxError; } } if (Gbl_DirectiveInfo[Directive].ArgCount >= 2) { Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token2) { goto SyntaxError; } } /* * At this point, if we are ignoring the current code block, * do not process any more directives (i.e., ignore them also.) * For "if" style directives, open/push a new block anyway. We * must do this to keep track of #endif directives */ if (Gbl_IgnoringThisCodeBlock) { switch (Directive) { case PR_DIRECTIVE_IF: case PR_DIRECTIVE_IFDEF: case PR_DIRECTIVE_IFNDEF: PrPushDirective (Directive, Token); PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); break; default: break; } return; } /* * Execute the directive */ PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name); switch (Directive) { case PR_DIRECTIVE_IF: TokenOffset = Token - Gbl_MainTokenBuffer; /* Need to expand #define macros in the expression string first */ Status = PrResolveIntegerExpression ( &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); if (ACPI_FAILURE (Status)) { return; } PrPushDirective (Directive, Token); if (!Value) { Gbl_IgnoringThisCodeBlock = TRUE; } DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "Resolved #if: %8.8X%8.8X %s\n", Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); break; case PR_DIRECTIVE_IFDEF: PrPushDirective (Directive, Token); if (!PrMatchDefine (Token)) { Gbl_IgnoringThisCodeBlock = TRUE; } PrDbgPrint ("Evaluated", "ifdef"); break; case PR_DIRECTIVE_IFNDEF: PrPushDirective (Directive, Token); if (PrMatchDefine (Token)) { Gbl_IgnoringThisCodeBlock = TRUE; } PrDbgPrint ("Evaluated", "ifndef"); break; case PR_DIRECTIVE_DEFINE: /* * By definition, if first char after the name is a paren, * this is a function macro. */ TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') { #ifndef MACROS_SUPPORTED AcpiOsPrintf ( "%s ERROR - line %u: #define macros are not supported yet\n", Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber); exit(1); #else PrAddMacro (Token, Next); #endif } else { /* Use the remainder of the line for the #define */ Token2 = *Next; if (Token2) { while ((*Token2 == ' ') || (*Token2 == '\t')) { Token2++; } End = Token2; while (*End != '\n') { End++; } *End = 0; } else { Token2 = ""; } #if 0 Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); if (!Token2) { Token2 = ""; } #endif DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "New #define: %s->%s\n", Gbl_LogicalLineNumber, Token, Token2); PrAddDefine (Token, Token2, FALSE); } break; case PR_DIRECTIVE_ERROR: /* Note: No macro expansion */ PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); Gbl_SourceLine = 0; Gbl_NextError = Gbl_ErrorLog; CmCleanupAndExit (); exit(1); case PR_DIRECTIVE_INCLUDE: Token = PrGetNextToken (NULL, " \"<>", Next); if (!Token) { goto SyntaxError; } DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "Start #include file \"%s\"\n", Gbl_CurrentLineNumber, Token, Gbl_CurrentLineNumber); PrDoIncludeFile (Token); break; case PR_DIRECTIVE_INCLUDEBUFFER: Token = PrGetNextToken (NULL, " \"<>", Next); if (!Token) { goto SyntaxError; } Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token2) { goto SyntaxError; } DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "Start #includebuffer input from file \"%s\", buffer name %s\n", Gbl_CurrentLineNumber, Token, Token2); PrDoIncludeBuffer (Token, Token2); break; case PR_DIRECTIVE_LINE: TokenOffset = Token - Gbl_MainTokenBuffer; Status = PrResolveIntegerExpression ( &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); if (ACPI_FAILURE (Status)) { return; } DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "User #line invocation %s\n", Gbl_CurrentLineNumber, Token); Gbl_CurrentLineNumber = (UINT32) Value; /* Emit #line into the preprocessor file */ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename); break; case PR_DIRECTIVE_PRAGMA: if (!strcmp (Token, "disable")) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token) { goto SyntaxError; } TokenOffset = Token - Gbl_MainTokenBuffer; AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]); } else if (!strcmp (Token, "message")) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token) { goto SyntaxError; } TokenOffset = Token - Gbl_MainTokenBuffer; AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); } else { PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, THIS_TOKEN_OFFSET (Token)); return; } break; case PR_DIRECTIVE_UNDEF: DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "#undef: %s\n", Gbl_CurrentLineNumber, Token); PrRemoveDefine (Token); break; case PR_DIRECTIVE_WARNING: PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); Gbl_SourceLine = 0; Gbl_NextError = Gbl_ErrorLog; break; default: /* Should never get here */ DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID "Unrecognized directive: %u\n", Gbl_CurrentLineNumber, Directive); break; } return; SyntaxError: PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, THIS_TOKEN_OFFSET (DirectiveToken)); return; }
static int AslDoOptions ( int argc, char **argv, BOOLEAN IsResponseFile) { ACPI_STATUS Status; UINT32 j; /* Get the command line options */ while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) { case '@': /* Begin a response file */ if (IsResponseFile) { printf ("Nested command files are not supported\n"); return (-1); } if (AslDoResponseFile (AcpiGbl_Optarg)) { return (-1); } break; case 'a': /* Debug options */ switch (AcpiGbl_Optarg[0]) { case 'r': Gbl_EnableReferenceTypechecking = TRUE; break; default: printf ("Unknown option: -a%s\n", AcpiGbl_Optarg); return (-1); } break; case 'b': /* Debug options */ switch (AcpiGbl_Optarg[0]) { case 'f': AslCompilerdebug = 1; /* same as yydebug */ DtParserdebug = 1; PrParserdebug = 1; Gbl_DebugFlag = TRUE; Gbl_KeepPreprocessorTempFile = TRUE; break; case 'p': /* Prune ASL parse tree */ /* Get the required argument */ if (AcpiGetoptArgument (argc, argv)) { return (-1); } Gbl_PruneParseTree = TRUE; Gbl_PruneDepth = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; case 's': Gbl_DebugFlag = TRUE; break; case 't': /* Get the required argument */ if (AcpiGetoptArgument (argc, argv)) { return (-1); } Gbl_PruneType = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; default: printf ("Unknown option: -b%s\n", AcpiGbl_Optarg); return (-1); } break; case 'c': switch (AcpiGbl_Optarg[0]) { case 'r': Gbl_NoResourceChecking = TRUE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'd': /* Disassembler */ switch (AcpiGbl_Optarg[0]) { case '^': Gbl_DoCompile = FALSE; break; case 'a': Gbl_DoCompile = FALSE; Gbl_DisassembleAll = TRUE; break; case 'b': /* Do not convert buffers to resource descriptors */ AcpiGbl_NoResourceDisassembly = TRUE; break; case 'c': break; case 'f': AcpiGbl_ForceAmlDisassembly = TRUE; break; case 'l': /* Use legacy ASL code (not ASL+) for disassembly */ Gbl_DoCompile = FALSE; AcpiGbl_CstyleDisassembly = FALSE; break; default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); return (-1); } Gbl_DisasmFlag = TRUE; break; case 'D': /* Define a symbol */ PrAddDefine (AcpiGbl_Optarg, NULL, TRUE); break; case 'e': /* External files for disassembler */ /* Get entire list of external files */ AcpiGbl_Optind--; argv[AcpiGbl_Optind] = AcpiGbl_Optarg; while (argv[AcpiGbl_Optind] && (argv[AcpiGbl_Optind][0] != '-')) { Status = AcpiDmAddToExternalFileList (argv[AcpiGbl_Optind]); if (ACPI_FAILURE (Status)) { printf ("Could not add %s to external list\n", argv[AcpiGbl_Optind]); return (-1); } AcpiGbl_Optind++; } break; case 'f': switch (AcpiGbl_Optarg[0]) { case '^': /* Ignore errors and force creation of aml file */ Gbl_IgnoreErrors = TRUE; break; case 'e': /* Disassembler: Get external declaration file */ if (AcpiGetoptArgument (argc, argv)) { return (-1); } Gbl_ExternalRefFilename = AcpiGbl_Optarg; break; default: printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); return (-1); } break; case 'G': Gbl_CompileGeneric = TRUE; break; case 'g': /* Get all ACPI tables */ printf ("-g option is deprecated, use acpidump utility instead\n"); exit (1); case 'h': switch (AcpiGbl_Optarg[0]) { case '^': Usage (); exit (0); case 'c': UtDisplayConstantOpcodes (); exit (0); case 'f': AslFilenameHelp (); exit (0); case 'r': /* reserved names */ ApDisplayReservedNames (); exit (0); case 't': UtDisplaySupportedTables (); exit (0); default: printf ("Unknown option: -h%s\n", AcpiGbl_Optarg); return (-1); } case 'I': /* Add an include file search directory */ FlAddIncludeDirectory (AcpiGbl_Optarg); break; case 'i': /* Output AML as an include file */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code include file */ Gbl_AsmIncludeOutputFlag = TRUE; break; case 'c': /* Produce C include file */ Gbl_C_IncludeOutputFlag = TRUE; break; case 'n': /* Compiler/Disassembler: Ignore the NOOP operator */ AcpiGbl_IgnoreNoopOperator = TRUE; break; default: printf ("Unknown option: -i%s\n", AcpiGbl_Optarg); return (-1); } break; case 'l': /* Listing files */ switch (AcpiGbl_Optarg[0]) { case '^': /* Produce listing file (Mixed source/aml) */ Gbl_ListingFlag = TRUE; AcpiGbl_DmOpt_Listing = TRUE; break; case 'i': /* Produce preprocessor output file */ Gbl_PreprocessorOutputFlag = TRUE; break; case 'm': /* Produce hardware map summary file */ Gbl_MapfileFlag = TRUE; break; case 'n': /* Produce namespace file */ Gbl_NsOutputFlag = TRUE; break; case 's': /* Produce combined source file */ Gbl_SourceOutputFlag = TRUE; break; case 'x': /* Produce cross-reference file */ Gbl_CrossReferenceOutput = TRUE; break; default: printf ("Unknown option: -l%s\n", AcpiGbl_Optarg); return (-1); } break; case 'm': /* Set line buffer size */ Gbl_LineBufferSize = (UINT32) strtoul (AcpiGbl_Optarg, NULL, 0) * 1024; if (Gbl_LineBufferSize < ASL_DEFAULT_LINE_BUFFER_SIZE) { Gbl_LineBufferSize = ASL_DEFAULT_LINE_BUFFER_SIZE; } printf ("Line Buffer Size: %u\n", Gbl_LineBufferSize); break; case 'n': /* Parse only */ Gbl_ParseOnlyFlag = TRUE; break; case 'o': /* Control compiler AML optimizations */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Disable all optimizations */ Gbl_FoldConstants = FALSE; Gbl_IntegerOptimizationFlag = FALSE; Gbl_ReferenceOptimizationFlag = FALSE; break; case 'c': /* Display compile time(s) */ Gbl_CompileTimesFlag = TRUE; break; case 'e': /* Disable External opcode generation */ Gbl_DoExternals = FALSE; break; case 'f': /* Disable folding on "normal" expressions */ Gbl_FoldConstants = FALSE; break; case 'i': /* Disable integer optimization to constants */ Gbl_IntegerOptimizationFlag = FALSE; break; case 'n': /* Disable named reference optimization */ Gbl_ReferenceOptimizationFlag = FALSE; break; case 't': /* Disable heavy typechecking */ Gbl_DoTypechecking = FALSE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'P': /* Preprocessor options */ switch (AcpiGbl_Optarg[0]) { case '^': /* Proprocess only, emit (.i) file */ Gbl_PreprocessOnly = TRUE; Gbl_PreprocessorOutputFlag = TRUE; break; case 'n': /* Disable preprocessor */ Gbl_PreprocessFlag = FALSE; break; default: printf ("Unknown option: -P%s\n", AcpiGbl_Optarg); return (-1); } break; case 'p': /* Override default AML output filename */ Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; UtConvertBackslashes (Gbl_OutputFilenamePrefix); Gbl_UseDefaultAmlFilename = FALSE; break; case 'r': /* Override revision found in table header */ Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; case 's': /* Create AML in a source code file */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code output file */ Gbl_AsmOutputFlag = TRUE; break; case 'c': /* Produce C hex output file */ Gbl_C_OutputFlag = TRUE; break; case 'o': /* Produce AML offset table in C */ Gbl_C_OffsetTableFlag = TRUE; break; default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); return (-1); } break; case 't': /* Produce hex table output file */ switch (AcpiGbl_Optarg[0]) { case 'a': Gbl_HexOutputFlag = HEX_OUTPUT_ASM; break; case 'c': Gbl_HexOutputFlag = HEX_OUTPUT_C; break; case 's': Gbl_HexOutputFlag = HEX_OUTPUT_ASL; break; default: printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); return (-1); } break; case 'T': /* Create a ACPI table template file */ Gbl_DoTemplates = TRUE; break; case 'v': /* Version and verbosity settings */ switch (AcpiGbl_Optarg[0]) { case '^': printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); exit (0); case 'a': /* Disable all error/warning/remark messages */ Gbl_NoErrors = TRUE; break; case 'e': /* Disable all warning/remark messages (errors only) */ Gbl_DisplayRemarks = FALSE; Gbl_DisplayWarnings = FALSE; break; case 'i': /* * Support for integrated development environment(s). * * 1) No compiler signon * 2) Send stderr messages to stdout * 3) Less verbose error messages (single line only for each) * 4) Error/warning messages are formatted appropriately to * be recognized by MS Visual Studio */ Gbl_VerboseErrors = FALSE; Gbl_DoSignon = FALSE; Gbl_Files[ASL_FILE_STDERR].Handle = stdout; break; case 'o': Gbl_DisplayOptimizations = TRUE; break; case 'r': Gbl_DisplayRemarks = FALSE; break; case 's': Gbl_DoSignon = FALSE; break; case 't': Gbl_VerboseTemplates = TRUE; break; case 'w': /* Get the required argument */ if (AcpiGetoptArgument (argc, argv)) { return (-1); } Status = AslDisableException (AcpiGbl_Optarg); if (ACPI_FAILURE (Status)) { return (-1); } break; default: printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); return (-1); } break; case 'w': /* Set warning levels */ switch (AcpiGbl_Optarg[0]) { case '1': Gbl_WarningLevel = ASL_WARNING; break; case '2': Gbl_WarningLevel = ASL_WARNING2; break; case '3': Gbl_WarningLevel = ASL_WARNING3; break; case 'e': Gbl_WarningsAsErrors = TRUE; break; default: printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); return (-1); } break; case 'x': /* Set debug print output level */ AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); break; case 'z': Gbl_UseOriginalCompilerId = TRUE; break; default: return (-1); } return (0); }
void PrAddMacro ( char *Name, char **Next) { char *Token = NULL; ACPI_SIZE TokenOffset; ACPI_SIZE MacroBodyOffset; PR_DEFINE_INFO *DefineInfo; PR_MACRO_ARG *Args; char *Body; char *BodyInSource; UINT32 i; UINT16 UseCount = 0; UINT16 ArgCount = 0; UINT32 Depth = 1; UINT32 EndOfArgList; char BufferChar; /* Find the end of the arguments list */ TokenOffset = Name - Gbl_MainTokenBuffer + strlen (Name) + 1; while (1) { BufferChar = Gbl_CurrentLineBuffer[TokenOffset]; if (BufferChar == '(') { Depth++; } else if (BufferChar == ')') { Depth--; } else if (BufferChar == 0) { PrError (ASL_ERROR, ASL_MSG_MACRO_SYNTAX, TokenOffset); return; } if (Depth == 0) { /* Found arg list end */ EndOfArgList = TokenOffset; break; } TokenOffset++; } /* At this point, we know that we have a reasonable argument list */ Args = UtLocalCalloc (sizeof (PR_MACRO_ARG) * PR_MAX_MACRO_ARGS); /* Get the macro argument names */ for (i = 0; i < PR_MAX_MACRO_ARGS; i++) { Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); if (!Token) { /* This is the case for a NULL macro body */ BodyInSource = ""; goto AddMacroToList; } /* Don't go beyond the argument list */ TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); if (TokenOffset > EndOfArgList) { break; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Macro arg: %s \n", Gbl_CurrentLineNumber, Token); Args[i].Name = UtLocalCalloc (strlen (Token) + 1); strcpy (Args[i].Name, Token); Args[i].UseCount = 0; ArgCount++; if (ArgCount >= PR_MAX_MACRO_ARGS) { PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, TokenOffset); goto ErrorExit; } } /* Get the macro body. Token now points to start of body */ MacroBodyOffset = Token - Gbl_MainTokenBuffer; /* Match each method arg in the macro body for later use */ Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); while (Token) { /* Search the macro arg list for matching arg */ for (i = 0; Args[i].Name && (i < PR_MAX_MACRO_ARGS); i++) { /* * Save argument offset within macro body. This is the mechanism * used to expand the macro upon invocation. * * Handles multiple instances of the same argument */ if (!strcmp (Token, Args[i].Name)) { UseCount = Args[i].UseCount; Args[i].Offset[UseCount] = (Token - Gbl_MainTokenBuffer) - MacroBodyOffset; DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Macro Arg #%u: %s UseCount %u Offset %u \n", Gbl_CurrentLineNumber, i, Token, UseCount+1, Args[i].Offset[UseCount]); Args[i].UseCount++; if (Args[i].UseCount >= PR_MAX_ARG_INSTANCES) { PrError (ASL_ERROR, ASL_MSG_TOO_MANY_ARGUMENTS, THIS_TOKEN_OFFSET (Token)); goto ErrorExit; } break; } } Token = PrGetNextToken (NULL, PR_MACRO_SEPARATORS, Next); } BodyInSource = &Gbl_CurrentLineBuffer[MacroBodyOffset]; AddMacroToList: /* Check if name is already defined first */ DefineInfo = PrMatchDefine (Name); if (DefineInfo) { DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "#define: macro name already exists: %s\n", Gbl_CurrentLineNumber, Name); /* Error only if not exactly the same macro */ if (strcmp (DefineInfo->Body, BodyInSource) || (DefineInfo->ArgCount != ArgCount)) { PrError (ASL_ERROR, ASL_MSG_EXISTING_NAME, THIS_TOKEN_OFFSET (Name)); } goto ErrorExit; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Macro body: %s \n", Gbl_CurrentLineNumber, BodyInSource); /* Add macro to the #define list */ DefineInfo = PrAddDefine (Name, BodyInSource, FALSE); if (DefineInfo) { Body = UtLocalCalloc (strlen (BodyInSource) + 1); strcpy (Body, BodyInSource); DefineInfo->Body = Body; DefineInfo->Args = Args; DefineInfo->ArgCount = ArgCount; } return; ErrorExit: ACPI_FREE (Args); return; }
static int AslDoOptions ( int argc, char **argv, BOOLEAN IsResponseFile) { int j; ACPI_STATUS Status; /* Get the command line options */ while ((j = AcpiGetopt (argc, argv, ASL_SUPPORTED_OPTIONS)) != EOF) switch (j) { case '@': /* Begin a response file */ if (IsResponseFile) { printf ("Nested command files are not supported\n"); return (-1); } if (AslDoResponseFile (AcpiGbl_Optarg)) { return (-1); } break; case '2': /* ACPI 2.0 compatibility mode */ Gbl_Acpi2 = TRUE; break; case 'b': /* Debug output options */ switch (AcpiGbl_Optarg[0]) { case 'f': AslCompilerdebug = 1; /* same as yydebug */ DtParserdebug = 1; PrParserdebug = 1; break; case 't': break; default: printf ("Unknown option: -b%s\n", AcpiGbl_Optarg); return (-1); } /* Produce debug output file */ Gbl_DebugFlag = TRUE; break; case 'c': switch (AcpiGbl_Optarg[0]) { case 'r': Gbl_NoResourceChecking = TRUE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'd': /* Disassembler */ switch (AcpiGbl_Optarg[0]) { case '^': Gbl_DoCompile = FALSE; break; case 'a': Gbl_DoCompile = FALSE; Gbl_DisassembleAll = TRUE; break; case 'c': break; default: printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); return (-1); } Gbl_DisasmFlag = TRUE; break; case 'D': /* Define a symbol */ PrAddDefine (AcpiGbl_Optarg, NULL, TRUE); break; case 'e': /* External files for disassembler */ Status = AcpiDmAddToExternalFileList (AcpiGbl_Optarg); if (ACPI_FAILURE (Status)) { printf ("Could not add %s to external list\n", AcpiGbl_Optarg); return (-1); } break; case 'f': /* Ignore errors and force creation of aml file */ Gbl_IgnoreErrors = TRUE; break; case 'G': Gbl_CompileGeneric = TRUE; break; case 'g': /* Get all ACPI tables */ Gbl_GetAllTables = TRUE; Gbl_DoCompile = FALSE; break; case 'h': switch (AcpiGbl_Optarg[0]) { case '^': Usage (); exit (0); case 'c': UtDisplayConstantOpcodes (); exit (0); case 'f': FilenameHelp (); exit (0); case 'r': /* reserved names */ ApDisplayReservedNames (); exit (0); case 't': UtDisplaySupportedTables (); exit (0); default: printf ("Unknown option: -h%s\n", AcpiGbl_Optarg); return (-1); } case 'I': /* Add an include file search directory */ FlAddIncludeDirectory (AcpiGbl_Optarg); break; case 'i': /* Output AML as an include file */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code include file */ Gbl_AsmIncludeOutputFlag = TRUE; break; case 'c': /* Produce C include file */ Gbl_C_IncludeOutputFlag = TRUE; break; default: printf ("Unknown option: -i%s\n", AcpiGbl_Optarg); return (-1); } break; case 'l': /* Listing files */ switch (AcpiGbl_Optarg[0]) { case '^': /* Produce listing file (Mixed source/aml) */ Gbl_ListingFlag = TRUE; break; case 'i': /* Produce preprocessor output file */ Gbl_PreprocessorOutputFlag = TRUE; break; case 'n': /* Produce namespace file */ Gbl_NsOutputFlag = TRUE; break; case 's': /* Produce combined source file */ Gbl_SourceOutputFlag = TRUE; break; default: printf ("Unknown option: -l%s\n", AcpiGbl_Optarg); return (-1); } break; case 'm': /* Do not convert buffers to resource descriptors */ AcpiGbl_NoResourceDisassembly = TRUE; break; case 'n': /* Parse only */ Gbl_ParseOnlyFlag = TRUE; break; case 'o': /* Control compiler AML optimizations */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Disable all optimizations */ Gbl_FoldConstants = FALSE; Gbl_IntegerOptimizationFlag = FALSE; Gbl_ReferenceOptimizationFlag = FALSE; break; case 'f': /* Disable folding on "normal" expressions */ Gbl_FoldConstants = FALSE; break; case 'i': /* Disable integer optimization to constants */ Gbl_IntegerOptimizationFlag = FALSE; break; case 'n': /* Disable named reference optimization */ Gbl_ReferenceOptimizationFlag = FALSE; break; case 't': /* Display compile time(s) */ Gbl_CompileTimesFlag = TRUE; break; default: printf ("Unknown option: -c%s\n", AcpiGbl_Optarg); return (-1); } break; case 'P': /* Preprocessor options */ switch (AcpiGbl_Optarg[0]) { case '^': /* Proprocess only, emit (.i) file */ Gbl_PreprocessOnly = TRUE; Gbl_PreprocessorOutputFlag = TRUE; break; case 'n': /* Disable preprocessor */ Gbl_PreprocessFlag = FALSE; break; default: printf ("Unknown option: -P%s\n", AcpiGbl_Optarg); return (-1); } break; case 'p': /* Override default AML output filename */ Gbl_OutputFilenamePrefix = AcpiGbl_Optarg; Gbl_UseDefaultAmlFilename = FALSE; break; case 'r': /* Override revision found in table header */ Gbl_RevisionOverride = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); break; case 's': /* Create AML in a source code file */ switch (AcpiGbl_Optarg[0]) { case 'a': /* Produce assembly code output file */ Gbl_AsmOutputFlag = TRUE; break; case 'c': /* Produce C hex output file */ Gbl_C_OutputFlag = TRUE; break; default: printf ("Unknown option: -s%s\n", AcpiGbl_Optarg); return (-1); } break; case 't': /* Produce hex table output file */ switch (AcpiGbl_Optarg[0]) { case 'a': Gbl_HexOutputFlag = HEX_OUTPUT_ASM; break; case 'c': Gbl_HexOutputFlag = HEX_OUTPUT_C; break; case 's': Gbl_HexOutputFlag = HEX_OUTPUT_ASL; break; default: printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); return (-1); } break; case 'T': /* Create a ACPI table template file */ Gbl_DoTemplates = TRUE; Gbl_TemplateSignature = AcpiGbl_Optarg; break; case 'v': /* Version and verbosity settings */ switch (AcpiGbl_Optarg[0]) { case '^': printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); exit (0); case 'a': /* Disable All error/warning messages */ Gbl_NoErrors = TRUE; break; case 'i': /* * Support for integrated development environment(s). * * 1) No compiler signon * 2) Send stderr messages to stdout * 3) Less verbose error messages (single line only for each) * 4) Error/warning messages are formatted appropriately to * be recognized by MS Visual Studio */ Gbl_VerboseErrors = FALSE; Gbl_DoSignon = FALSE; Gbl_Files[ASL_FILE_STDERR].Handle = stdout; break; case 'o': Gbl_DisplayOptimizations = TRUE; break; case 'r': Gbl_DisplayRemarks = FALSE; break; case 's': Gbl_DoSignon = FALSE; break; case 't': Gbl_VerboseTemplates = TRUE; break; default: printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); return (-1); } break; case 'w': /* Set warning levels */ switch (AcpiGbl_Optarg[0]) { case '1': Gbl_WarningLevel = ASL_WARNING; break; case '2': Gbl_WarningLevel = ASL_WARNING2; break; case '3': Gbl_WarningLevel = ASL_WARNING3; break; case 'e': Gbl_WarningsAsErrors = TRUE; break; default: printf ("Unknown option: -w%s\n", AcpiGbl_Optarg); return (-1); } break; case 'x': /* Set debug print output level */ AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 16); break; case 'z': Gbl_UseOriginalCompilerId = TRUE; break; default: return (-1); } return (0); }
int CmDoCompile ( void) { ACPI_STATUS Status; UINT8 FullCompile; UINT8 Event; FullCompile = UtBeginEvent ("*** Total Compile time ***"); Event = UtBeginEvent ("Open input and output files"); UtEndEvent (Event); Event = UtBeginEvent ("Preprocess input file"); if (AslGbl_PreprocessFlag) { /* Enter compiler name as a #define */ PrAddDefine (ASL_DEFINE, "", FALSE); /* Preprocessor */ PrDoPreprocess (); AslGbl_CurrentLineNumber = 1; AslGbl_LogicalLineNumber = 1; if (AslGbl_PreprocessOnly) { UtEndEvent (Event); CmCleanupAndExit (); return (0); } } UtEndEvent (Event); /* Build the parse tree */ Event = UtBeginEvent ("Parse source code and build parse tree"); AslCompilerparse(); UtEndEvent (Event); /* Check for parser-detected syntax errors */ if (AslGbl_SyntaxError) { fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n"); LsDumpParseTree (); goto ErrorExit; } /* Did the parse tree get successfully constructed? */ if (!AslGbl_ParseTreeRoot) { /* * If there are no errors, then we have some sort of * internal problem. */ AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, NULL, "- Could not resolve parse tree root node"); goto ErrorExit; } /* Flush out any remaining source after parse tree is complete */ Event = UtBeginEvent ("Flush source input"); CmFlushSourceCode (); /* Prune the parse tree if requested (debug purposes only) */ if (AslGbl_PruneParseTree) { AslPruneParseTree (AslGbl_PruneDepth, AslGbl_PruneType); } /* Optional parse tree dump, compiler debug output only */ LsDumpParseTree (); OpcGetIntegerWidth (AslGbl_ParseTreeRoot->Asl.Child); UtEndEvent (Event); /* Pre-process parse tree for any operator transforms */ Event = UtBeginEvent ("Parse tree transforms"); DbgPrint (ASL_DEBUG_OUTPUT, "\nParse tree transforms\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, TrAmlTransformWalkBegin, TrAmlTransformWalkEnd, NULL); UtEndEvent (Event); /* Generate AML opcodes corresponding to the parse tokens */ Event = UtBeginEvent ("Generate AML opcodes"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating AML opcodes\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlOpcodeWalk, NULL); UtEndEvent (Event); /* * Now that the input is parsed, we can open the AML output file. * Note: by default, the name of this file comes from the table * descriptor within the input file. */ Event = UtBeginEvent ("Open AML output file"); Status = FlOpenAmlOutputFile (AslGbl_OutputFilenamePrefix); UtEndEvent (Event); if (ACPI_FAILURE (Status)) { AePrintErrorLog (ASL_FILE_STDERR); return (-1); } /* Interpret and generate all compile-time constants */ Event = UtBeginEvent ("Constant folding via AML interpreter"); DbgPrint (ASL_DEBUG_OUTPUT, "Interpreting compile-time constant expressions\n\n"); if (AslGbl_FoldConstants) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlConstantWalk, NULL); } else { DbgPrint (ASL_PARSE_OUTPUT, " Optional folding disabled\n"); } UtEndEvent (Event); /* Update AML opcodes if necessary, after constant folding */ Event = UtBeginEvent ("Updating AML opcodes after constant folding"); DbgPrint (ASL_DEBUG_OUTPUT, "Updating AML opcodes after constant folding\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, OpcAmlOpcodeUpdateWalk, NULL); UtEndEvent (Event); /* Calculate all AML package lengths */ Event = UtBeginEvent ("Generate AML package lengths"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnPackageLengthWalk, NULL); UtEndEvent (Event); if (AslGbl_ParseOnlyFlag) { AePrintErrorLog (ASL_FILE_STDERR); UtDisplaySummary (ASL_FILE_STDERR); if (AslGbl_DebugFlag) { /* Print error summary to the stdout also */ AePrintErrorLog (ASL_FILE_STDOUT); UtDisplaySummary (ASL_FILE_STDOUT); } UtEndEvent (FullCompile); return (0); } /* * Create an internal namespace and use it as a symbol table */ /* Namespace loading */ Event = UtBeginEvent ("Create ACPI Namespace"); DbgPrint (ASL_DEBUG_OUTPUT, "Creating ACPI Namespace\n\n"); Status = LdLoadNamespace (AslGbl_ParseTreeRoot); UtEndEvent (Event); if (ACPI_FAILURE (Status)) { goto ErrorExit; } /* Namespace cross-reference */ AslGbl_NamespaceEvent = UtBeginEvent ( "Cross reference parse tree and Namespace"); DbgPrint (ASL_DEBUG_OUTPUT, "Cross referencing namespace\n\n"); Status = XfCrossReferenceNamespace (); if (ACPI_FAILURE (Status)) { goto ErrorExit; } /* Namespace - Check for non-referenced objects */ LkFindUnreferencedObjects (); UtEndEvent (AslGbl_NamespaceEvent); /* Resolve External Declarations */ Event = UtBeginEvent ("Resolve all Externals"); DbgPrint (ASL_DEBUG_OUTPUT, "\nResolve Externals\n\n"); if (AslGbl_DoExternalsInPlace) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, ExAmlExternalWalkBegin, NULL, NULL); } else { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, ExAmlExternalWalkBegin, ExAmlExternalWalkEnd, NULL); } UtEndEvent (Event); /* * Semantic analysis. This can happen only after the * namespace has been loaded and cross-referenced. * * part one - check control methods */ Event = UtBeginEvent ("Analyze control method return types"); AslGbl_AnalysisWalkInfo.MethodStack = NULL; DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method analysis\n\n"); if (AslGbl_CrossReferenceOutput) { OtPrintHeaders ("Part 1: Object Reference Map " "(Object references from within each control method)"); } TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_TWICE, MtMethodAnalysisWalkBegin, MtMethodAnalysisWalkEnd, &AslGbl_AnalysisWalkInfo); UtEndEvent (Event); /* Generate the object cross-reference file if requested */ Event = UtBeginEvent ("Generate cross-reference file"); OtCreateXrefFile (); UtEndEvent (Event); /* Semantic error checking part two - typing of method returns */ Event = UtBeginEvent ("Determine object types returned by methods"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Method typing\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, AnMethodTypingWalkEnd, NULL); UtEndEvent (Event); /* Semantic error checking part three - operand type checking */ Event = UtBeginEvent ("Analyze AML operand types"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - Operand type checking\n\n"); if (AslGbl_DoTypechecking) { TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, AnOperandTypecheckWalkEnd, &AslGbl_AnalysisWalkInfo); } UtEndEvent (Event); /* Semantic error checking part four - other miscellaneous checks */ Event = UtBeginEvent ("Miscellaneous analysis"); DbgPrint (ASL_DEBUG_OUTPUT, "Semantic analysis - miscellaneous\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, AnOtherSemanticAnalysisWalkBegin, NULL, &AslGbl_AnalysisWalkInfo); UtEndEvent (Event); /* * ASL-/ASL+ converter: Gbl_ParseTreeRoot->CommentList contains the * very last comment of a given ASL file because it's the last constructed * node during compilation. We take the very last comment and save it in a * global for it to be used by the disassembler. */ if (AcpiGbl_CaptureComments) { AcpiGbl_LastListHead = AslGbl_ParseTreeRoot->Asl.CommentList; AslGbl_ParseTreeRoot->Asl.CommentList = NULL; } /* Calculate all AML package lengths */ Event = UtBeginEvent ("Finish AML package length generation"); DbgPrint (ASL_DEBUG_OUTPUT, "Generating Package lengths\n\n"); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnInitLengthsWalk, NULL); TrWalkParseTree (AslGbl_ParseTreeRoot, ASL_WALK_VISIT_UPWARD, NULL, LnPackageLengthWalk, NULL); UtEndEvent (Event); /* Code generation - emit the AML */ Event = UtBeginEvent ("Generate AML code and write output files"); DbgPrint (ASL_DEBUG_OUTPUT, "Writing AML byte code\n\n"); CgGenerateAmlOutput (); UtEndEvent (Event); Event = UtBeginEvent ("Write optional output files"); CmDoOutputFiles (); UtEndEvent (Event); UtEndEvent (FullCompile); AslCheckExpectedExceptions (); CmCleanupAndExit (); return (0); ErrorExit: UtEndEvent (FullCompile); CmCleanupAndExit (); return (-1); }
static void PrDoDirective ( char *DirectiveToken, char **Next, BOOLEAN *IgnoringThisCodeBlock) { char *Token = Gbl_MainTokenBuffer; char *Token2; char *End; UINT64 Value; ACPI_SIZE TokenOffset; int Directive; ACPI_STATUS Status; if (!DirectiveToken) { goto SyntaxError; } Directive = PrMatchDirective (DirectiveToken); if (Directive == ASL_DIRECTIVE_NOT_FOUND) { PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, THIS_TOKEN_OFFSET (DirectiveToken)); DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "#%s: Unknown directive\n", Gbl_CurrentLineNumber, DirectiveToken); return; } /* TBD: Need a faster way to do this: */ if ((Directive == PR_DIRECTIVE_ELIF) || (Directive == PR_DIRECTIVE_ELSE) || (Directive == PR_DIRECTIVE_ENDIF)) { DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); } /* * Need to always check for #else, #elif, #endif regardless of * whether we are ignoring the current code block, since these * are conditional code block terminators. */ switch (Directive) { case PR_DIRECTIVE_ELIF: *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); if (*IgnoringThisCodeBlock == TRUE) { /* Not executing the ELSE part -- all done here */ return; } /* Will execute the ELSE..IF part */ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "#elif - Executing else block\n", Gbl_CurrentLineNumber); Directive = PR_DIRECTIVE_IF; break; case PR_DIRECTIVE_ELSE: *IgnoringThisCodeBlock = !(*IgnoringThisCodeBlock); return; case PR_DIRECTIVE_ENDIF: *IgnoringThisCodeBlock = FALSE; Gbl_IfDepth--; if (Gbl_IfDepth < 0) { PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, THIS_TOKEN_OFFSET (DirectiveToken)); Gbl_IfDepth = 0; } return; default: break; } /* * At this point, if we are ignoring the current code block, * do not process any more directives (i.e., ignore them also.) */ if (*IgnoringThisCodeBlock == TRUE) { return; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Begin #%s\n", Gbl_CurrentLineNumber, Gbl_DirectiveInfo[Directive].Name); /* Most directives have at least one argument */ if (Gbl_DirectiveInfo[Directive].ArgCount == 1) { Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token) { goto SyntaxError; } } switch (Directive) { case PR_DIRECTIVE_DEFINE: /* * By definition, if first char after the name is a paren, * this is a function macro. */ TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') { #ifndef MACROS_SUPPORTED AcpiOsPrintf ("%s ERROR - line %u: #define macros are not supported yet\n", Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber); exit(1); #else PrAddMacro (Token, Next); #endif } else { /* Use the remainder of the line for the #define */ Token2 = *Next; if (Token2) { while ((*Token2 == ' ') || (*Token2 == '\t')) { Token2++; } End = Token2; while (*End != '\n') { End++; } *End = 0; } else { Token2 = ""; } #if 0 Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); if (!Token2) { Token2 = ""; } #endif DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "New #define: %s->%s\n", Gbl_CurrentLineNumber, Token, Token2); PrAddDefine (Token, Token2, FALSE); } break; case PR_DIRECTIVE_ERROR: /* TBD compiler should abort */ /* Note: No macro expansion */ PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); break; case PR_DIRECTIVE_IF: TokenOffset = Token - Gbl_MainTokenBuffer; /* Need to expand #define macros in the expression string first */ Status = PrResolveIntegerExpression ( &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); if (ACPI_FAILURE (Status)) { return; } if (!Value) { *IgnoringThisCodeBlock = TRUE; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Resolved #if: %8.8X%8.8X %s\n", Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), *IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); Gbl_IfDepth++; break; case PR_DIRECTIVE_IFDEF: if (!PrMatchDefine (Token)) { *IgnoringThisCodeBlock = TRUE; } Gbl_IfDepth++; DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Start #ifdef %s\n", Gbl_CurrentLineNumber, *IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); break; case PR_DIRECTIVE_IFNDEF: if (PrMatchDefine (Token)) { *IgnoringThisCodeBlock = TRUE; } Gbl_IfDepth++; DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Start #ifndef %2.2X\n", Gbl_CurrentLineNumber, *IgnoringThisCodeBlock, Gbl_CurrentLineNumber); break; case PR_DIRECTIVE_INCLUDE: Token = PrGetNextToken (NULL, " \"<>", Next); if (!Token) { goto SyntaxError; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Start #include file \"%s\"\n", Gbl_CurrentLineNumber, Token, Gbl_CurrentLineNumber); PrOpenIncludeFile (Token); break; case PR_DIRECTIVE_LINE: TokenOffset = Token - Gbl_MainTokenBuffer; Status = PrResolveIntegerExpression ( &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); if (ACPI_FAILURE (Status)) { return; } DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "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 */ FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename); break; case PR_DIRECTIVE_PRAGMA: /* Only "#pragma message" supported at this time */ if (strcmp (Token, "message")) { PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, THIS_TOKEN_OFFSET (Token)); return; } Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); if (!Token) { goto SyntaxError; } TokenOffset = Token - Gbl_MainTokenBuffer; AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); break; case PR_DIRECTIVE_UNDEF: DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "#undef: %s\n", Gbl_CurrentLineNumber, Token); PrRemoveDefine (Token); break; case PR_DIRECTIVE_WARNING: PrError (ASL_WARNING, ASL_MSG_ERROR_DIRECTIVE, THIS_TOKEN_OFFSET (Token)); break; default: /* Should never get here */ DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID "Unrecognized directive: %u\n", Gbl_CurrentLineNumber, Directive); break; } return; SyntaxError: PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, THIS_TOKEN_OFFSET (DirectiveToken)); return; }