1233237Sjkim/****************************************************************************** 2233237Sjkim * 3233237Sjkim * Module Name: prscan - Preprocessor start-up and file scan module 4233237Sjkim * 5233237Sjkim *****************************************************************************/ 6233237Sjkim 7233237Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9233237Sjkim * All rights reserved. 10233237Sjkim * 11233237Sjkim * Redistribution and use in source and binary forms, with or without 12233237Sjkim * modification, are permitted provided that the following conditions 13233237Sjkim * are met: 14233237Sjkim * 1. Redistributions of source code must retain the above copyright 15233237Sjkim * notice, this list of conditions, and the following disclaimer, 16233237Sjkim * without modification. 17233237Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18233237Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19233237Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20233237Sjkim * including a substantially similar Disclaimer requirement for further 21233237Sjkim * binary redistribution. 22233237Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23233237Sjkim * of any contributors may be used to endorse or promote products derived 24233237Sjkim * from this software without specific prior written permission. 25233237Sjkim * 26233237Sjkim * Alternatively, this software may be distributed under the terms of the 27233237Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28233237Sjkim * Software Foundation. 29233237Sjkim * 30233237Sjkim * NO WARRANTY 31233237Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32233237Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33233237Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34233237Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35233237Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36233237Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37233237Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38233237Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39233237Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40233237Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41233237Sjkim * POSSIBILITY OF SUCH DAMAGES. 42233237Sjkim */ 43233237Sjkim 44233237Sjkim#define _DECLARE_PR_GLOBALS 45233237Sjkim 46233250Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 47233250Sjkim#include <contrib/dev/acpica/compiler/dtcompiler.h> 48233237Sjkim 49233237Sjkim/* 50233237Sjkim * TBDs: 51233237Sjkim * 52233237Sjkim * No nested macros, maybe never 53233237Sjkim * Implement ASL "Include" as well as "#include" here? 54233237Sjkim */ 55233237Sjkim#define _COMPONENT ASL_PREPROCESSOR 56233237Sjkim ACPI_MODULE_NAME ("prscan") 57233237Sjkim 58233237Sjkim 59233237Sjkim/* Local prototypes */ 60233237Sjkim 61233237Sjkimstatic void 62233237SjkimPrPreprocessInputFile ( 63233237Sjkim void); 64233237Sjkim 65233237Sjkimstatic void 66233237SjkimPrDoDirective ( 67233237Sjkim char *DirectiveToken, 68252279Sjkim char **Next); 69233237Sjkim 70306536Sjkimstatic void 71306536SjkimPrGetNextLineInit ( 72306536Sjkim void); 73306536Sjkim 74306536Sjkimstatic UINT32 75306536SjkimPrGetNextLine ( 76306536Sjkim FILE *Handle); 77306536Sjkim 78233237Sjkimstatic int 79233237SjkimPrMatchDirective ( 80233237Sjkim char *Directive); 81233237Sjkim 82252279Sjkimstatic void 83252279SjkimPrPushDirective ( 84252279Sjkim int Directive, 85252279Sjkim char *Argument); 86252279Sjkim 87252279Sjkimstatic ACPI_STATUS 88252279SjkimPrPopDirective ( 89252279Sjkim void); 90252279Sjkim 91252279Sjkimstatic void 92252279SjkimPrDbgPrint ( 93252279Sjkim char *Action, 94252279Sjkim char *DirectiveName); 95252279Sjkim 96284460Sjkimstatic void 97284460SjkimPrDoIncludeBuffer ( 98284460Sjkim char *Pathname, 99284460Sjkim char *BufferName); 100252279Sjkim 101284460Sjkimstatic void 102284460SjkimPrDoIncludeFile ( 103284460Sjkim char *Pathname); 104284460Sjkim 105284460Sjkim 106233237Sjkim/* 107233237Sjkim * Supported preprocessor directives 108284460Sjkim * Each entry is of the form "Name, ArgumentCount" 109233237Sjkim */ 110233237Sjkimstatic const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = 111233237Sjkim{ 112284460Sjkim {"define", 1}, 113284460Sjkim {"elif", 0}, /* Converted to #else..#if internally */ 114284460Sjkim {"else", 0}, 115284460Sjkim {"endif", 0}, 116284460Sjkim {"error", 1}, 117284460Sjkim {"if", 1}, 118284460Sjkim {"ifdef", 1}, 119284460Sjkim {"ifndef", 1}, 120284460Sjkim {"include", 0}, /* Argument is not standard format, so just use 0 here */ 121284460Sjkim {"includebuffer", 0}, /* Argument is not standard format, so just use 0 here */ 122284460Sjkim {"line", 1}, 123284460Sjkim {"pragma", 1}, 124284460Sjkim {"undef", 1}, 125284460Sjkim {"warning", 1}, 126284460Sjkim {NULL, 0} 127233237Sjkim}; 128233237Sjkim 129284460Sjkim/* This table must match ordering of above table exactly */ 130284460Sjkim 131233237Sjkimenum Gbl_DirectiveIndexes 132233237Sjkim{ 133233237Sjkim PR_DIRECTIVE_DEFINE = 0, 134233237Sjkim PR_DIRECTIVE_ELIF, 135233237Sjkim PR_DIRECTIVE_ELSE, 136233237Sjkim PR_DIRECTIVE_ENDIF, 137233237Sjkim PR_DIRECTIVE_ERROR, 138233237Sjkim PR_DIRECTIVE_IF, 139233237Sjkim PR_DIRECTIVE_IFDEF, 140233237Sjkim PR_DIRECTIVE_IFNDEF, 141233237Sjkim PR_DIRECTIVE_INCLUDE, 142284460Sjkim PR_DIRECTIVE_INCLUDEBUFFER, 143233237Sjkim PR_DIRECTIVE_LINE, 144233237Sjkim PR_DIRECTIVE_PRAGMA, 145233237Sjkim PR_DIRECTIVE_UNDEF, 146306536Sjkim PR_DIRECTIVE_WARNING 147233237Sjkim}; 148233237Sjkim 149233237Sjkim#define ASL_DIRECTIVE_NOT_FOUND -1 150233237Sjkim 151233237Sjkim 152233237Sjkim/******************************************************************************* 153233237Sjkim * 154233237Sjkim * FUNCTION: PrInitializePreprocessor 155233237Sjkim * 156233237Sjkim * PARAMETERS: None 157233237Sjkim * 158233237Sjkim * RETURN: None 159233237Sjkim * 160233237Sjkim * DESCRIPTION: Startup initialization for the Preprocessor. 161233237Sjkim * 162233237Sjkim ******************************************************************************/ 163233237Sjkim 164233237Sjkimvoid 165233237SjkimPrInitializePreprocessor ( 166233237Sjkim void) 167233237Sjkim{ 168233237Sjkim /* Init globals and the list of #defines */ 169233237Sjkim 170233237Sjkim PrInitializeGlobals (); 171233237Sjkim Gbl_DefineList = NULL; 172233237Sjkim} 173233237Sjkim 174233237Sjkim 175233237Sjkim/******************************************************************************* 176233237Sjkim * 177233237Sjkim * FUNCTION: PrInitializeGlobals 178233237Sjkim * 179233237Sjkim * PARAMETERS: None 180233237Sjkim * 181233237Sjkim * RETURN: None 182233237Sjkim * 183233237Sjkim * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup 184233237Sjkim * initialization and re-initialization between compiles during 185233237Sjkim * a multiple source file compile. 186233237Sjkim * 187233237Sjkim ******************************************************************************/ 188233237Sjkim 189233237Sjkimvoid 190233237SjkimPrInitializeGlobals ( 191233237Sjkim void) 192233237Sjkim{ 193233237Sjkim /* Init globals */ 194233237Sjkim 195233237Sjkim Gbl_InputFileList = NULL; 196306536Sjkim Gbl_CurrentLineNumber = 1; 197233237Sjkim Gbl_PreprocessorLineNumber = 1; 198233237Sjkim Gbl_PreprocessorError = FALSE; 199252279Sjkim 200252279Sjkim /* These are used to track #if/#else blocks (possibly nested) */ 201252279Sjkim 202252279Sjkim Gbl_IfDepth = 0; 203252279Sjkim Gbl_IgnoringThisCodeBlock = FALSE; 204252279Sjkim Gbl_DirectiveStack = NULL; 205233237Sjkim} 206233237Sjkim 207233237Sjkim 208233237Sjkim/******************************************************************************* 209233237Sjkim * 210233237Sjkim * FUNCTION: PrTerminatePreprocessor 211233237Sjkim * 212233237Sjkim * PARAMETERS: None 213233237Sjkim * 214233237Sjkim * RETURN: None 215233237Sjkim * 216233237Sjkim * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any 217233237Sjkim * defines that were specified on the command line, in order to 218233237Sjkim * support multiple compiles with a single compiler invocation. 219233237Sjkim * 220233237Sjkim ******************************************************************************/ 221233237Sjkim 222233237Sjkimvoid 223233237SjkimPrTerminatePreprocessor ( 224233237Sjkim void) 225233237Sjkim{ 226233237Sjkim PR_DEFINE_INFO *DefineInfo; 227233237Sjkim 228233237Sjkim 229233237Sjkim /* 230233237Sjkim * The persistent defines (created on the command line) are always at the 231233237Sjkim * end of the list. We save them. 232233237Sjkim */ 233233237Sjkim while ((Gbl_DefineList) && (!Gbl_DefineList->Persist)) 234233237Sjkim { 235233237Sjkim DefineInfo = Gbl_DefineList; 236233237Sjkim Gbl_DefineList = DefineInfo->Next; 237233237Sjkim 238233237Sjkim ACPI_FREE (DefineInfo->Replacement); 239233237Sjkim ACPI_FREE (DefineInfo->Identifier); 240233237Sjkim ACPI_FREE (DefineInfo); 241233237Sjkim } 242233237Sjkim} 243233237Sjkim 244233237Sjkim 245233237Sjkim/******************************************************************************* 246233237Sjkim * 247233237Sjkim * FUNCTION: PrDoPreprocess 248233237Sjkim * 249233237Sjkim * PARAMETERS: None 250233237Sjkim * 251252279Sjkim * RETURN: None 252233237Sjkim * 253233237Sjkim * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must 254233237Sjkim * be already open. Handles multiple input files via the 255233237Sjkim * #include directive. 256233237Sjkim * 257233237Sjkim ******************************************************************************/ 258233237Sjkim 259252279Sjkimvoid 260233237SjkimPrDoPreprocess ( 261233237Sjkim void) 262233237Sjkim{ 263233237Sjkim BOOLEAN MoreInputFiles; 264233237Sjkim 265233237Sjkim 266233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n"); 267233237Sjkim 268233237Sjkim 269233237Sjkim FlSeekFile (ASL_FILE_INPUT, 0); 270233237Sjkim PrDumpPredefinedNames (); 271233237Sjkim 272233237Sjkim /* Main preprocessor loop, handles include files */ 273233237Sjkim 274233237Sjkim do 275233237Sjkim { 276233237Sjkim PrPreprocessInputFile (); 277233237Sjkim MoreInputFiles = PrPopInputFileStack (); 278233237Sjkim 279233237Sjkim } while (MoreInputFiles); 280233237Sjkim 281306536Sjkim /* Point compiler input to the new preprocessor output file (.pre) */ 282233237Sjkim 283233237Sjkim FlCloseFile (ASL_FILE_INPUT); 284233237Sjkim Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; 285233237Sjkim AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle; 286233237Sjkim 287233237Sjkim /* Reset globals to allow compiler to run */ 288233237Sjkim 289233237Sjkim FlSeekFile (ASL_FILE_INPUT, 0); 290306536Sjkim if (!Gbl_PreprocessOnly) 291306536Sjkim { 292306536Sjkim Gbl_CurrentLineNumber = 0; 293306536Sjkim } 294233237Sjkim 295233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); 296233237Sjkim} 297233237Sjkim 298233237Sjkim 299233237Sjkim/******************************************************************************* 300233237Sjkim * 301233237Sjkim * FUNCTION: PrPreprocessInputFile 302233237Sjkim * 303233237Sjkim * PARAMETERS: None 304233237Sjkim * 305233237Sjkim * RETURN: None 306233237Sjkim * 307233237Sjkim * DESCRIPTION: Preprocess one entire file, line-by-line. 308233237Sjkim * 309233237Sjkim * Input: Raw user ASL from ASL_FILE_INPUT 310306536Sjkim * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and 311306536Sjkim * (optionally) ASL_FILE_PREPROCESSOR_USER 312233237Sjkim * 313233237Sjkim ******************************************************************************/ 314233237Sjkim 315233237Sjkimstatic void 316233237SjkimPrPreprocessInputFile ( 317233237Sjkim void) 318233237Sjkim{ 319306536Sjkim UINT32 Status; 320233237Sjkim char *Token; 321233237Sjkim char *ReplaceString; 322233237Sjkim PR_DEFINE_INFO *DefineInfo; 323233237Sjkim ACPI_SIZE TokenOffset; 324233237Sjkim char *Next; 325233237Sjkim int OffsetAdjust; 326233237Sjkim 327233237Sjkim 328306536Sjkim PrGetNextLineInit (); 329233237Sjkim 330306536Sjkim /* Scan source line-by-line and process directives. Then write the .i file */ 331306536Sjkim 332306536Sjkim while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) 333233237Sjkim { 334306536Sjkim Gbl_CurrentLineNumber++; 335306536Sjkim Gbl_LogicalLineNumber++; 336306536Sjkim 337306536Sjkim if (Status == ASL_IGNORE_LINE) 338306536Sjkim { 339306536Sjkim goto WriteEntireLine; 340306536Sjkim } 341306536Sjkim 342233237Sjkim /* Need a copy of the input line for strok() */ 343233237Sjkim 344233237Sjkim strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); 345233237Sjkim Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); 346233237Sjkim OffsetAdjust = 0; 347233237Sjkim 348233237Sjkim /* All preprocessor directives must begin with '#' */ 349233237Sjkim 350233237Sjkim if (Token && (*Token == '#')) 351233237Sjkim { 352233237Sjkim if (strlen (Token) == 1) 353233237Sjkim { 354233237Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 355233237Sjkim } 356233237Sjkim else 357233237Sjkim { 358233237Sjkim Token++; /* Skip leading # */ 359233237Sjkim } 360233237Sjkim 361233237Sjkim /* Execute the directive, do not write line to output file */ 362233237Sjkim 363252279Sjkim PrDoDirective (Token, &Next); 364233237Sjkim continue; 365233237Sjkim } 366233237Sjkim 367233237Sjkim /* 368233237Sjkim * If we are currently within the part of an IF/ELSE block that is 369233237Sjkim * FALSE, ignore the line and do not write it to the output file. 370233237Sjkim * This continues until an #else or #endif is encountered. 371233237Sjkim */ 372252279Sjkim if (Gbl_IgnoringThisCodeBlock) 373233237Sjkim { 374233237Sjkim continue; 375233237Sjkim } 376233237Sjkim 377233237Sjkim /* Match and replace all #defined names within this source line */ 378233237Sjkim 379233237Sjkim while (Token) 380233237Sjkim { 381233237Sjkim DefineInfo = PrMatchDefine (Token); 382233237Sjkim if (DefineInfo) 383233237Sjkim { 384233237Sjkim if (DefineInfo->Body) 385233237Sjkim { 386233237Sjkim /* This is a macro */ 387233237Sjkim 388233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 389233237Sjkim "Matched Macro: %s->%s\n", 390233237Sjkim Gbl_CurrentLineNumber, DefineInfo->Identifier, 391233237Sjkim DefineInfo->Replacement); 392233237Sjkim 393233237Sjkim PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, 394233237Sjkim DefineInfo, &Next); 395233237Sjkim } 396233237Sjkim else 397233237Sjkim { 398233237Sjkim ReplaceString = DefineInfo->Replacement; 399233237Sjkim 400233237Sjkim /* Replace the name in the original line buffer */ 401233237Sjkim 402233237Sjkim TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; 403233237Sjkim PrReplaceData ( 404233237Sjkim &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), 405233237Sjkim ReplaceString, strlen (ReplaceString)); 406233237Sjkim 407233237Sjkim /* Adjust for length difference between old and new name length */ 408233237Sjkim 409233237Sjkim OffsetAdjust += strlen (ReplaceString) - strlen (Token); 410233237Sjkim 411233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 412233237Sjkim "Matched #define: %s->%s\n", 413233237Sjkim Gbl_CurrentLineNumber, Token, 414233237Sjkim *ReplaceString ? ReplaceString : "(NULL STRING)"); 415233237Sjkim } 416233237Sjkim } 417233237Sjkim 418233237Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 419233237Sjkim } 420233237Sjkim 421234623Sjkim Gbl_PreprocessorLineNumber++; 422234623Sjkim 423306536Sjkim 424306536SjkimWriteEntireLine: 425234623Sjkim /* 426234623Sjkim * Now we can write the possibly modified source line to the 427306536Sjkim * preprocessor file(s). 428234623Sjkim */ 429233237Sjkim FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, 430233237Sjkim strlen (Gbl_CurrentLineBuffer)); 431233237Sjkim } 432233237Sjkim} 433233237Sjkim 434233237Sjkim 435233237Sjkim/******************************************************************************* 436233237Sjkim * 437233237Sjkim * FUNCTION: PrDoDirective 438233237Sjkim * 439233237Sjkim * PARAMETERS: Directive - Pointer to directive name token 440233237Sjkim * Next - "Next" buffer from GetNextToken 441233237Sjkim * 442252279Sjkim * RETURN: None. 443233237Sjkim * 444233237Sjkim * DESCRIPTION: Main processing for all preprocessor directives 445233237Sjkim * 446233237Sjkim ******************************************************************************/ 447233237Sjkim 448233237Sjkimstatic void 449233237SjkimPrDoDirective ( 450233237Sjkim char *DirectiveToken, 451252279Sjkim char **Next) 452233237Sjkim{ 453233237Sjkim char *Token = Gbl_MainTokenBuffer; 454284460Sjkim char *Token2 = NULL; 455233237Sjkim char *End; 456233237Sjkim UINT64 Value; 457233237Sjkim ACPI_SIZE TokenOffset; 458233237Sjkim int Directive; 459233237Sjkim ACPI_STATUS Status; 460233237Sjkim 461233237Sjkim 462233237Sjkim if (!DirectiveToken) 463233237Sjkim { 464233237Sjkim goto SyntaxError; 465233237Sjkim } 466233237Sjkim 467233237Sjkim Directive = PrMatchDirective (DirectiveToken); 468233237Sjkim if (Directive == ASL_DIRECTIVE_NOT_FOUND) 469233237Sjkim { 470233237Sjkim PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, 471233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 472233237Sjkim 473284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 474233237Sjkim "#%s: Unknown directive\n", 475233237Sjkim Gbl_CurrentLineNumber, DirectiveToken); 476233237Sjkim return; 477233237Sjkim } 478233237Sjkim 479252279Sjkim /* 480306536Sjkim * Emit a line directive into the preprocessor file (.pre) after 481306536Sjkim * every matched directive. This is passed through to the compiler 482306536Sjkim * so that error/warning messages are kept in sync with the 483306536Sjkim * original source file. 484306536Sjkim */ 485306536Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n", 486306536Sjkim Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename, 487306536Sjkim Gbl_DirectiveInfo[Directive].Name); 488306536Sjkim 489306536Sjkim /* 490252279Sjkim * If we are currently ignoring this block and we encounter a #else or 491252279Sjkim * #elif, we must ignore their blocks also if the parent block is also 492252279Sjkim * being ignored. 493252279Sjkim */ 494252279Sjkim if (Gbl_IgnoringThisCodeBlock) 495252279Sjkim { 496252279Sjkim switch (Directive) 497252279Sjkim { 498252279Sjkim case PR_DIRECTIVE_ELSE: 499252279Sjkim case PR_DIRECTIVE_ELIF: 500233237Sjkim 501306536Sjkim if (Gbl_DirectiveStack && 502306536Sjkim Gbl_DirectiveStack->IgnoringThisCodeBlock) 503252279Sjkim { 504252279Sjkim PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); 505252279Sjkim return; 506252279Sjkim } 507252279Sjkim break; 508252279Sjkim 509252279Sjkim default: 510252279Sjkim break; 511252279Sjkim } 512233237Sjkim } 513233237Sjkim 514233237Sjkim /* 515233237Sjkim * Need to always check for #else, #elif, #endif regardless of 516233237Sjkim * whether we are ignoring the current code block, since these 517233237Sjkim * are conditional code block terminators. 518233237Sjkim */ 519233237Sjkim switch (Directive) 520233237Sjkim { 521252279Sjkim case PR_DIRECTIVE_ELSE: 522252279Sjkim 523252279Sjkim Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); 524252279Sjkim PrDbgPrint ("Executing", "else block"); 525252279Sjkim return; 526252279Sjkim 527233237Sjkim case PR_DIRECTIVE_ELIF: 528250838Sjkim 529252279Sjkim Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); 530252279Sjkim Directive = PR_DIRECTIVE_IF; 531252279Sjkim 532252279Sjkim if (Gbl_IgnoringThisCodeBlock == TRUE) 533233237Sjkim { 534233237Sjkim /* Not executing the ELSE part -- all done here */ 535252279Sjkim PrDbgPrint ("Ignoring", "elif block"); 536233237Sjkim return; 537233237Sjkim } 538233237Sjkim 539252279Sjkim /* 540252279Sjkim * After this, we will execute the IF part further below. 541252279Sjkim * First, however, pop off the original #if directive. 542252279Sjkim */ 543252279Sjkim if (ACPI_FAILURE (PrPopDirective ())) 544252279Sjkim { 545252279Sjkim PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 546252279Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 547252279Sjkim } 548233237Sjkim 549252279Sjkim PrDbgPrint ("Executing", "elif block"); 550233237Sjkim break; 551233237Sjkim 552252279Sjkim case PR_DIRECTIVE_ENDIF: 553250838Sjkim 554252279Sjkim PrDbgPrint ("Executing", "endif"); 555233237Sjkim 556252279Sjkim /* Pop the owning #if/#ifdef/#ifndef */ 557250838Sjkim 558252279Sjkim if (ACPI_FAILURE (PrPopDirective ())) 559233237Sjkim { 560233237Sjkim PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, 561233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 562233237Sjkim } 563233237Sjkim return; 564233237Sjkim 565233237Sjkim default: 566233237Sjkim break; 567233237Sjkim } 568233237Sjkim 569252279Sjkim /* Most directives have at least one argument */ 570252279Sjkim 571284460Sjkim if (Gbl_DirectiveInfo[Directive].ArgCount >= 1) 572252279Sjkim { 573252279Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 574252279Sjkim if (!Token) 575252279Sjkim { 576252279Sjkim goto SyntaxError; 577252279Sjkim } 578252279Sjkim } 579252279Sjkim 580284460Sjkim if (Gbl_DirectiveInfo[Directive].ArgCount >= 2) 581284460Sjkim { 582284460Sjkim Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 583284460Sjkim if (!Token2) 584284460Sjkim { 585284460Sjkim goto SyntaxError; 586284460Sjkim } 587284460Sjkim } 588284460Sjkim 589233237Sjkim /* 590233237Sjkim * At this point, if we are ignoring the current code block, 591233237Sjkim * do not process any more directives (i.e., ignore them also.) 592252279Sjkim * For "if" style directives, open/push a new block anyway. We 593252279Sjkim * must do this to keep track of #endif directives 594233237Sjkim */ 595252279Sjkim if (Gbl_IgnoringThisCodeBlock) 596233237Sjkim { 597252279Sjkim switch (Directive) 598252279Sjkim { 599252279Sjkim case PR_DIRECTIVE_IF: 600252279Sjkim case PR_DIRECTIVE_IFDEF: 601252279Sjkim case PR_DIRECTIVE_IFNDEF: 602252279Sjkim 603252279Sjkim PrPushDirective (Directive, Token); 604252279Sjkim PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); 605252279Sjkim break; 606252279Sjkim 607252279Sjkim default: 608252279Sjkim break; 609252279Sjkim } 610252279Sjkim 611233237Sjkim return; 612233237Sjkim } 613233237Sjkim 614252279Sjkim /* 615252279Sjkim * Execute the directive 616252279Sjkim */ 617252279Sjkim PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name); 618233237Sjkim 619252279Sjkim switch (Directive) 620252279Sjkim { 621252279Sjkim case PR_DIRECTIVE_IF: 622233237Sjkim 623252279Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 624252279Sjkim 625252279Sjkim /* Need to expand #define macros in the expression string first */ 626252279Sjkim 627252279Sjkim Status = PrResolveIntegerExpression ( 628252279Sjkim &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 629252279Sjkim if (ACPI_FAILURE (Status)) 630233237Sjkim { 631252279Sjkim return; 632233237Sjkim } 633233237Sjkim 634252279Sjkim PrPushDirective (Directive, Token); 635252279Sjkim if (!Value) 636252279Sjkim { 637252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 638252279Sjkim } 639252279Sjkim 640284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 641252279Sjkim "Resolved #if: %8.8X%8.8X %s\n", 642252279Sjkim Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), 643252279Sjkim Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); 644252279Sjkim break; 645252279Sjkim 646252279Sjkim case PR_DIRECTIVE_IFDEF: 647252279Sjkim 648252279Sjkim PrPushDirective (Directive, Token); 649252279Sjkim if (!PrMatchDefine (Token)) 650252279Sjkim { 651252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 652252279Sjkim } 653252279Sjkim 654252279Sjkim PrDbgPrint ("Evaluated", "ifdef"); 655252279Sjkim break; 656252279Sjkim 657252279Sjkim case PR_DIRECTIVE_IFNDEF: 658252279Sjkim 659252279Sjkim PrPushDirective (Directive, Token); 660252279Sjkim if (PrMatchDefine (Token)) 661252279Sjkim { 662252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 663252279Sjkim } 664252279Sjkim 665252279Sjkim PrDbgPrint ("Evaluated", "ifndef"); 666252279Sjkim break; 667252279Sjkim 668233237Sjkim case PR_DIRECTIVE_DEFINE: 669233237Sjkim /* 670233237Sjkim * By definition, if first char after the name is a paren, 671233237Sjkim * this is a function macro. 672233237Sjkim */ 673233237Sjkim TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); 674233237Sjkim if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') 675233237Sjkim { 676233237Sjkim#ifndef MACROS_SUPPORTED 677306536Sjkim AcpiOsPrintf ( 678306536Sjkim "%s ERROR - line %u: #define macros are not supported yet\n", 679306536Sjkim Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber); 680234623Sjkim exit(1); 681233237Sjkim#else 682233237Sjkim PrAddMacro (Token, Next); 683233237Sjkim#endif 684233237Sjkim } 685233237Sjkim else 686233237Sjkim { 687233237Sjkim /* Use the remainder of the line for the #define */ 688233237Sjkim 689233237Sjkim Token2 = *Next; 690233237Sjkim if (Token2) 691233237Sjkim { 692233237Sjkim while ((*Token2 == ' ') || (*Token2 == '\t')) 693233237Sjkim { 694233237Sjkim Token2++; 695233237Sjkim } 696306536Sjkim 697233237Sjkim End = Token2; 698233237Sjkim while (*End != '\n') 699233237Sjkim { 700233237Sjkim End++; 701233237Sjkim } 702306536Sjkim 703233237Sjkim *End = 0; 704233237Sjkim } 705233237Sjkim else 706233237Sjkim { 707233237Sjkim Token2 = ""; 708233237Sjkim } 709233237Sjkim#if 0 710233237Sjkim Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); 711233237Sjkim if (!Token2) 712233237Sjkim { 713233237Sjkim Token2 = ""; 714233237Sjkim } 715233237Sjkim#endif 716284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 717233237Sjkim "New #define: %s->%s\n", 718306536Sjkim Gbl_LogicalLineNumber, Token, Token2); 719233237Sjkim 720233237Sjkim PrAddDefine (Token, Token2, FALSE); 721233237Sjkim } 722233237Sjkim break; 723233237Sjkim 724233237Sjkim case PR_DIRECTIVE_ERROR: 725250838Sjkim 726233237Sjkim /* Note: No macro expansion */ 727233237Sjkim 728233237Sjkim PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, 729233237Sjkim THIS_TOKEN_OFFSET (Token)); 730233237Sjkim 731252279Sjkim Gbl_SourceLine = 0; 732252279Sjkim Gbl_NextError = Gbl_ErrorLog; 733252279Sjkim CmCleanupAndExit (); 734252279Sjkim exit(1); 735250838Sjkim 736233237Sjkim case PR_DIRECTIVE_INCLUDE: 737250838Sjkim 738233237Sjkim Token = PrGetNextToken (NULL, " \"<>", Next); 739233237Sjkim if (!Token) 740233237Sjkim { 741233237Sjkim goto SyntaxError; 742233237Sjkim } 743233237Sjkim 744284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 745235945Sjkim "Start #include file \"%s\"\n", Gbl_CurrentLineNumber, 746233237Sjkim Token, Gbl_CurrentLineNumber); 747233237Sjkim 748284460Sjkim PrDoIncludeFile (Token); 749233237Sjkim break; 750233237Sjkim 751284460Sjkim case PR_DIRECTIVE_INCLUDEBUFFER: 752284460Sjkim 753284460Sjkim Token = PrGetNextToken (NULL, " \"<>", Next); 754284460Sjkim if (!Token) 755284460Sjkim { 756284460Sjkim goto SyntaxError; 757284460Sjkim } 758284460Sjkim 759284460Sjkim Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 760284460Sjkim if (!Token2) 761284460Sjkim { 762284460Sjkim goto SyntaxError; 763284460Sjkim } 764284460Sjkim 765284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 766284460Sjkim "Start #includebuffer input from file \"%s\", buffer name %s\n", 767284460Sjkim Gbl_CurrentLineNumber, Token, Token2); 768284460Sjkim 769284460Sjkim PrDoIncludeBuffer (Token, Token2); 770284460Sjkim break; 771284460Sjkim 772234623Sjkim case PR_DIRECTIVE_LINE: 773250838Sjkim 774234623Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 775234623Sjkim 776234623Sjkim Status = PrResolveIntegerExpression ( 777234623Sjkim &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 778234623Sjkim if (ACPI_FAILURE (Status)) 779234623Sjkim { 780234623Sjkim return; 781234623Sjkim } 782234623Sjkim 783284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 784234623Sjkim "User #line invocation %s\n", Gbl_CurrentLineNumber, 785234623Sjkim Token); 786234623Sjkim 787234623Sjkim Gbl_CurrentLineNumber = (UINT32) Value; 788234623Sjkim 789234623Sjkim /* Emit #line into the preprocessor file */ 790234623Sjkim 791234623Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", 792234623Sjkim Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename); 793234623Sjkim break; 794234623Sjkim 795233237Sjkim case PR_DIRECTIVE_PRAGMA: 796233237Sjkim 797250838Sjkim if (!strcmp (Token, "disable")) 798233237Sjkim { 799250838Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 800250838Sjkim if (!Token) 801250838Sjkim { 802250838Sjkim goto SyntaxError; 803250838Sjkim } 804250838Sjkim 805250838Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 806250838Sjkim AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]); 807250838Sjkim } 808250838Sjkim else if (!strcmp (Token, "message")) 809250838Sjkim { 810250838Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 811250838Sjkim if (!Token) 812250838Sjkim { 813250838Sjkim goto SyntaxError; 814250838Sjkim } 815250838Sjkim 816250838Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 817250838Sjkim AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); 818250838Sjkim } 819250838Sjkim else 820250838Sjkim { 821233237Sjkim PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, 822233237Sjkim THIS_TOKEN_OFFSET (Token)); 823233237Sjkim return; 824233237Sjkim } 825233237Sjkim 826233237Sjkim break; 827233237Sjkim 828233237Sjkim case PR_DIRECTIVE_UNDEF: 829250838Sjkim 830284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 831233237Sjkim "#undef: %s\n", Gbl_CurrentLineNumber, Token); 832233237Sjkim 833233237Sjkim PrRemoveDefine (Token); 834233237Sjkim break; 835233237Sjkim 836233237Sjkim case PR_DIRECTIVE_WARNING: 837250838Sjkim 838252279Sjkim PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, 839233237Sjkim THIS_TOKEN_OFFSET (Token)); 840306536Sjkim 841306536Sjkim Gbl_SourceLine = 0; 842306536Sjkim Gbl_NextError = Gbl_ErrorLog; 843233237Sjkim break; 844233237Sjkim 845233237Sjkim default: 846250838Sjkim 847233237Sjkim /* Should never get here */ 848284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 849233237Sjkim "Unrecognized directive: %u\n", 850233237Sjkim Gbl_CurrentLineNumber, Directive); 851233237Sjkim break; 852233237Sjkim } 853233237Sjkim 854233237Sjkim return; 855233237Sjkim 856233237SjkimSyntaxError: 857233237Sjkim 858233237Sjkim PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, 859233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 860233237Sjkim return; 861233237Sjkim} 862233237Sjkim 863233237Sjkim 864233237Sjkim/******************************************************************************* 865233237Sjkim * 866306536Sjkim * FUNCTION: PrGetNextLine, PrGetNextLineInit 867306536Sjkim * 868306536Sjkim * PARAMETERS: Handle - Open file handle for the source file 869306536Sjkim * 870306536Sjkim * RETURN: Status of the GetLine operation: 871306536Sjkim * AE_OK - Normal line, OK status 872306536Sjkim * ASL_IGNORE_LINE - Line is blank or part of a multi-line 873306536Sjkim * comment 874306536Sjkim * ASL_EOF - End-of-file reached 875306536Sjkim * 876306536Sjkim * DESCRIPTION: Get the next text line from the input file. Does not strip 877306536Sjkim * comments. 878306536Sjkim * 879306536Sjkim ******************************************************************************/ 880306536Sjkim 881306536Sjkim#define PR_NORMAL_TEXT 0 882306536Sjkim#define PR_MULTI_LINE_COMMENT 1 883306536Sjkim#define PR_SINGLE_LINE_COMMENT 2 884306536Sjkim#define PR_QUOTED_STRING 3 885306536Sjkim 886306536Sjkimstatic UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT; 887306536Sjkim 888306536Sjkimstatic void 889306536SjkimPrGetNextLineInit ( 890306536Sjkim void) 891306536Sjkim{ 892306536Sjkim AcpiGbl_LineScanState = 0; 893306536Sjkim} 894306536Sjkim 895306536Sjkimstatic UINT32 896306536SjkimPrGetNextLine ( 897306536Sjkim FILE *Handle) 898306536Sjkim{ 899306536Sjkim UINT32 i; 900306536Sjkim int c = 0; 901306536Sjkim int PreviousChar; 902306536Sjkim 903306536Sjkim 904306536Sjkim /* Always clear the global line buffer */ 905306536Sjkim 906306536Sjkim memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize); 907306536Sjkim for (i = 0; ;) 908306536Sjkim { 909306536Sjkim /* 910306536Sjkim * If line is too long, expand the line buffers. Also increases 911306536Sjkim * Gbl_LineBufferSize. 912306536Sjkim */ 913306536Sjkim if (i >= Gbl_LineBufferSize) 914306536Sjkim { 915306536Sjkim UtExpandLineBuffers (); 916306536Sjkim } 917306536Sjkim 918306536Sjkim PreviousChar = c; 919306536Sjkim c = getc (Handle); 920306536Sjkim if (c == EOF) 921306536Sjkim { 922306536Sjkim /* 923306536Sjkim * On EOF: If there is anything in the line buffer, terminate 924306536Sjkim * it with a newline, and catch the EOF on the next call 925306536Sjkim * to this function. 926306536Sjkim */ 927306536Sjkim if (i > 0) 928306536Sjkim { 929306536Sjkim Gbl_CurrentLineBuffer[i] = '\n'; 930306536Sjkim return (AE_OK); 931306536Sjkim } 932306536Sjkim 933306536Sjkim return (ASL_EOF); 934306536Sjkim } 935306536Sjkim 936306536Sjkim /* Update state machine as necessary */ 937306536Sjkim 938306536Sjkim switch (AcpiGbl_LineScanState) 939306536Sjkim { 940306536Sjkim case PR_NORMAL_TEXT: 941306536Sjkim 942306536Sjkim /* Check for multi-line comment start */ 943306536Sjkim 944306536Sjkim if ((PreviousChar == '/') && (c == '*')) 945306536Sjkim { 946306536Sjkim AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT; 947306536Sjkim } 948306536Sjkim 949306536Sjkim /* Check for single-line comment start */ 950306536Sjkim 951306536Sjkim else if ((PreviousChar == '/') && (c == '/')) 952306536Sjkim { 953306536Sjkim AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT; 954306536Sjkim } 955306536Sjkim 956306536Sjkim /* Check for quoted string start */ 957306536Sjkim 958306536Sjkim else if (PreviousChar == '"') 959306536Sjkim { 960306536Sjkim AcpiGbl_LineScanState = PR_QUOTED_STRING; 961306536Sjkim } 962306536Sjkim break; 963306536Sjkim 964306536Sjkim case PR_QUOTED_STRING: 965306536Sjkim 966306536Sjkim if (PreviousChar == '"') 967306536Sjkim { 968306536Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 969306536Sjkim } 970306536Sjkim break; 971306536Sjkim 972306536Sjkim case PR_MULTI_LINE_COMMENT: 973306536Sjkim 974306536Sjkim /* Check for multi-line comment end */ 975306536Sjkim 976306536Sjkim if ((PreviousChar == '*') && (c == '/')) 977306536Sjkim { 978306536Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 979306536Sjkim } 980306536Sjkim break; 981306536Sjkim 982306536Sjkim case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */ 983306536Sjkim default: 984306536Sjkim break; 985306536Sjkim } 986306536Sjkim 987306536Sjkim /* Always copy the character into line buffer */ 988306536Sjkim 989306536Sjkim Gbl_CurrentLineBuffer[i] = (char) c; 990306536Sjkim i++; 991306536Sjkim 992306536Sjkim /* Always exit on end-of-line */ 993306536Sjkim 994306536Sjkim if (c == '\n') 995306536Sjkim { 996306536Sjkim /* Handle multi-line comments */ 997306536Sjkim 998306536Sjkim if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT) 999306536Sjkim { 1000306536Sjkim return (ASL_IGNORE_LINE); 1001306536Sjkim } 1002306536Sjkim 1003306536Sjkim /* End of single-line comment */ 1004306536Sjkim 1005306536Sjkim if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT) 1006306536Sjkim { 1007306536Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 1008306536Sjkim return (AE_OK); 1009306536Sjkim } 1010306536Sjkim 1011306536Sjkim /* Blank line */ 1012306536Sjkim 1013306536Sjkim if (i == 1) 1014306536Sjkim { 1015306536Sjkim return (ASL_IGNORE_LINE); 1016306536Sjkim } 1017306536Sjkim 1018306536Sjkim return (AE_OK); 1019306536Sjkim } 1020306536Sjkim } 1021306536Sjkim} 1022306536Sjkim 1023306536Sjkim 1024306536Sjkim/******************************************************************************* 1025306536Sjkim * 1026233237Sjkim * FUNCTION: PrMatchDirective 1027233237Sjkim * 1028233237Sjkim * PARAMETERS: Directive - Pointer to directive name token 1029233237Sjkim * 1030233237Sjkim * RETURN: Index into command array, -1 if not found 1031233237Sjkim * 1032233237Sjkim * DESCRIPTION: Lookup the incoming directive in the known directives table. 1033233237Sjkim * 1034233237Sjkim ******************************************************************************/ 1035233237Sjkim 1036233237Sjkimstatic int 1037233237SjkimPrMatchDirective ( 1038233237Sjkim char *Directive) 1039233237Sjkim{ 1040233237Sjkim int i; 1041233237Sjkim 1042233237Sjkim 1043233237Sjkim if (!Directive || Directive[0] == 0) 1044233237Sjkim { 1045233237Sjkim return (ASL_DIRECTIVE_NOT_FOUND); 1046233237Sjkim } 1047233237Sjkim 1048233237Sjkim for (i = 0; Gbl_DirectiveInfo[i].Name; i++) 1049233237Sjkim { 1050233237Sjkim if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive)) 1051233237Sjkim { 1052233237Sjkim return (i); 1053233237Sjkim } 1054233237Sjkim } 1055233237Sjkim 1056233237Sjkim return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ 1057233237Sjkim} 1058252279Sjkim 1059252279Sjkim 1060252279Sjkim/******************************************************************************* 1061252279Sjkim * 1062252279Sjkim * FUNCTION: PrPushDirective 1063252279Sjkim * 1064252279Sjkim * PARAMETERS: Directive - Encoded directive ID 1065252279Sjkim * Argument - String containing argument to the 1066252279Sjkim * directive 1067252279Sjkim * 1068252279Sjkim * RETURN: None 1069252279Sjkim * 1070252279Sjkim * DESCRIPTION: Push an item onto the directive stack. Used for processing 1071252279Sjkim * nested #if/#else type conditional compilation directives. 1072252279Sjkim * Specifically: Used on detection of #if/#ifdef/#ifndef to open 1073252279Sjkim * a block. 1074252279Sjkim * 1075252279Sjkim ******************************************************************************/ 1076252279Sjkim 1077252279Sjkimstatic void 1078252279SjkimPrPushDirective ( 1079252279Sjkim int Directive, 1080252279Sjkim char *Argument) 1081252279Sjkim{ 1082252279Sjkim DIRECTIVE_INFO *Info; 1083252279Sjkim 1084252279Sjkim 1085252279Sjkim /* Allocate and populate a stack info item */ 1086252279Sjkim 1087252279Sjkim Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO)); 1088252279Sjkim 1089252279Sjkim Info->Next = Gbl_DirectiveStack; 1090252279Sjkim Info->Directive = Directive; 1091252279Sjkim Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock; 1092252279Sjkim strncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH); 1093252279Sjkim 1094252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 1095252279Sjkim "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n", 1096252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1097252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1098252279Sjkim Gbl_IfDepth * 4, " ", 1099252279Sjkim Gbl_DirectiveInfo[Directive].Name, 1100252279Sjkim Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); 1101252279Sjkim 1102252279Sjkim /* Push new item */ 1103252279Sjkim 1104252279Sjkim Gbl_DirectiveStack = Info; 1105252279Sjkim Gbl_IfDepth++; 1106252279Sjkim} 1107252279Sjkim 1108252279Sjkim 1109252279Sjkim/******************************************************************************* 1110252279Sjkim * 1111252279Sjkim * FUNCTION: PrPopDirective 1112252279Sjkim * 1113252279Sjkim * PARAMETERS: None 1114252279Sjkim * 1115252279Sjkim * RETURN: Status. Error if the stack is empty. 1116252279Sjkim * 1117252279Sjkim * DESCRIPTION: Pop an item off the directive stack. Used for processing 1118252279Sjkim * nested #if/#else type conditional compilation directives. 1119252279Sjkim * Specifically: Used on detection of #elif and #endif to remove 1120252279Sjkim * the original #if/#ifdef/#ifndef from the stack and close 1121252279Sjkim * the block. 1122252279Sjkim * 1123252279Sjkim ******************************************************************************/ 1124252279Sjkim 1125252279Sjkimstatic ACPI_STATUS 1126252279SjkimPrPopDirective ( 1127252279Sjkim void) 1128252279Sjkim{ 1129252279Sjkim DIRECTIVE_INFO *Info; 1130252279Sjkim 1131252279Sjkim 1132252279Sjkim /* Check for empty stack */ 1133252279Sjkim 1134252279Sjkim Info = Gbl_DirectiveStack; 1135252279Sjkim if (!Info) 1136252279Sjkim { 1137252279Sjkim return (AE_ERROR); 1138252279Sjkim } 1139252279Sjkim 1140252279Sjkim /* Pop one item, keep globals up-to-date */ 1141252279Sjkim 1142252279Sjkim Gbl_IfDepth--; 1143252279Sjkim Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock; 1144252279Sjkim Gbl_DirectiveStack = Info->Next; 1145252279Sjkim 1146252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 1147252279Sjkim "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n", 1148252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1149252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1150252279Sjkim Gbl_IfDepth * 4, " ", 1151252279Sjkim Gbl_DirectiveInfo[Info->Directive].Name, 1152252279Sjkim Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); 1153252279Sjkim 1154252279Sjkim ACPI_FREE (Info); 1155252279Sjkim return (AE_OK); 1156252279Sjkim} 1157252279Sjkim 1158252279Sjkim 1159252279Sjkim/******************************************************************************* 1160252279Sjkim * 1161252279Sjkim * FUNCTION: PrDbgPrint 1162252279Sjkim * 1163252279Sjkim * PARAMETERS: Action - Action being performed 1164252279Sjkim * DirectiveName - Directive being processed 1165252279Sjkim * 1166252279Sjkim * RETURN: None 1167252279Sjkim * 1168252279Sjkim * DESCRIPTION: Special debug print for directive processing. 1169252279Sjkim * 1170252279Sjkim ******************************************************************************/ 1171252279Sjkim 1172252279Sjkimstatic void 1173252279SjkimPrDbgPrint ( 1174252279Sjkim char *Action, 1175252279Sjkim char *DirectiveName) 1176252279Sjkim{ 1177252279Sjkim 1178252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] " 1179284460Sjkim "%*s %s #%s, IfDepth %u\n", 1180252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1181252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1182252279Sjkim Gbl_IfDepth * 4, " ", 1183252279Sjkim Action, DirectiveName, Gbl_IfDepth); 1184252279Sjkim} 1185284460Sjkim 1186284460Sjkim 1187284460Sjkim/******************************************************************************* 1188284460Sjkim * 1189284460Sjkim * FUNCTION: PrDoIncludeFile 1190284460Sjkim * 1191284460Sjkim * PARAMETERS: Pathname - Name of the input file 1192284460Sjkim * 1193284460Sjkim * RETURN: None. 1194284460Sjkim * 1195284460Sjkim * DESCRIPTION: Open an include file, from #include. 1196284460Sjkim * 1197284460Sjkim ******************************************************************************/ 1198284460Sjkim 1199284460Sjkimstatic void 1200284460SjkimPrDoIncludeFile ( 1201284460Sjkim char *Pathname) 1202284460Sjkim{ 1203284460Sjkim char *FullPathname; 1204284460Sjkim 1205284460Sjkim 1206284460Sjkim (void) PrOpenIncludeFile (Pathname, "r", &FullPathname); 1207284460Sjkim} 1208284460Sjkim 1209284460Sjkim 1210284460Sjkim/******************************************************************************* 1211284460Sjkim * 1212284460Sjkim * FUNCTION: PrDoIncludeBuffer 1213284460Sjkim * 1214284460Sjkim * PARAMETERS: Pathname - Name of the input binary file 1215284460Sjkim * BufferName - ACPI namepath of the buffer 1216284460Sjkim * 1217284460Sjkim * RETURN: None. 1218284460Sjkim * 1219284460Sjkim * DESCRIPTION: Create an ACPI buffer object from a binary file. The contents 1220284460Sjkim * of the file are emitted into the buffer object as ascii 1221284460Sjkim * hex data. From #includebuffer. 1222284460Sjkim * 1223284460Sjkim ******************************************************************************/ 1224284460Sjkim 1225284460Sjkimstatic void 1226284460SjkimPrDoIncludeBuffer ( 1227284460Sjkim char *Pathname, 1228284460Sjkim char *BufferName) 1229284460Sjkim{ 1230284460Sjkim char *FullPathname; 1231284460Sjkim FILE *BinaryBufferFile; 1232284460Sjkim UINT32 i = 0; 1233284460Sjkim UINT8 c; 1234284460Sjkim 1235284460Sjkim 1236284460Sjkim BinaryBufferFile = PrOpenIncludeFile (Pathname, "rb", &FullPathname); 1237284460Sjkim if (!BinaryBufferFile) 1238284460Sjkim { 1239284460Sjkim return; 1240284460Sjkim } 1241284460Sjkim 1242284460Sjkim /* Emit "Name (XXXX, Buffer() {" header */ 1243284460Sjkim 1244284460Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "Name (%s, Buffer()\n{", BufferName); 1245284460Sjkim 1246284460Sjkim /* Dump the entire file in ascii hex format */ 1247284460Sjkim 1248284460Sjkim while (fread (&c, 1, 1, BinaryBufferFile)) 1249284460Sjkim { 1250284460Sjkim if (!(i % 8)) 1251284460Sjkim { 1252284460Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "\n ", c); 1253284460Sjkim } 1254284460Sjkim 1255284460Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, " 0x%2.2X,", c); 1256284460Sjkim i++; 1257284460Sjkim } 1258284460Sjkim 1259284460Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 1260284460Sjkim "#includebuffer: read %u bytes from %s\n", 1261284460Sjkim Gbl_CurrentLineNumber, i, FullPathname); 1262284460Sjkim 1263284460Sjkim /* Close the Name() operator */ 1264284460Sjkim 1265284460Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "\n})\n", BufferName); 1266284460Sjkim fclose (BinaryBufferFile); 1267284460Sjkim} 1268