1233237Sjkim/****************************************************************************** 2233237Sjkim * 3233237Sjkim * Module Name: prscan - Preprocessor start-up and file scan module 4233237Sjkim * 5233237Sjkim *****************************************************************************/ 6233237Sjkim 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12233237Sjkim * All rights reserved. 13233237Sjkim * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119233237Sjkim * Redistribution and use in source and binary forms, with or without 120233237Sjkim * modification, are permitted provided that the following conditions 121233237Sjkim * are met: 122233237Sjkim * 1. Redistributions of source code must retain the above copyright 123233237Sjkim * notice, this list of conditions, and the following disclaimer, 124233237Sjkim * without modification. 125233237Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126233237Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127233237Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128233237Sjkim * including a substantially similar Disclaimer requirement for further 129233237Sjkim * binary redistribution. 130233237Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131233237Sjkim * of any contributors may be used to endorse or promote products derived 132233237Sjkim * from this software without specific prior written permission. 133233237Sjkim * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147233237Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148233237Sjkim * Software Foundation. 149233237Sjkim * 150316303Sjkim *****************************************************************************/ 151233237Sjkim 152233237Sjkim#define _DECLARE_PR_GLOBALS 153233237Sjkim 154233250Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 155233237Sjkim 156233237Sjkim/* 157233237Sjkim * TBDs: 158233237Sjkim * 159233237Sjkim * No nested macros, maybe never 160233237Sjkim * Implement ASL "Include" as well as "#include" here? 161233237Sjkim */ 162233237Sjkim#define _COMPONENT ASL_PREPROCESSOR 163233237Sjkim ACPI_MODULE_NAME ("prscan") 164233237Sjkim 165233237Sjkim 166233237Sjkim/* Local prototypes */ 167233237Sjkim 168233237Sjkimstatic void 169233237SjkimPrPreprocessInputFile ( 170233237Sjkim void); 171233237Sjkim 172233237Sjkimstatic void 173233237SjkimPrDoDirective ( 174233237Sjkim char *DirectiveToken, 175252279Sjkim char **Next); 176233237Sjkim 177284583Sjkimstatic void 178284583SjkimPrGetNextLineInit ( 179284583Sjkim void); 180284583Sjkim 181284583Sjkimstatic UINT32 182284583SjkimPrGetNextLine ( 183284583Sjkim FILE *Handle); 184284583Sjkim 185233237Sjkimstatic int 186233237SjkimPrMatchDirective ( 187233237Sjkim char *Directive); 188233237Sjkim 189252279Sjkimstatic void 190252279SjkimPrPushDirective ( 191252279Sjkim int Directive, 192252279Sjkim char *Argument); 193252279Sjkim 194252279Sjkimstatic ACPI_STATUS 195252279SjkimPrPopDirective ( 196252279Sjkim void); 197252279Sjkim 198252279Sjkimstatic void 199252279SjkimPrDbgPrint ( 200252279Sjkim char *Action, 201252279Sjkim char *DirectiveName); 202252279Sjkim 203283092Sjkimstatic void 204283092SjkimPrDoIncludeBuffer ( 205283092Sjkim char *Pathname, 206283092Sjkim char *BufferName); 207252279Sjkim 208283092Sjkimstatic void 209283092SjkimPrDoIncludeFile ( 210283092Sjkim char *Pathname); 211283092Sjkim 212283092Sjkim 213233237Sjkim/* 214233237Sjkim * Supported preprocessor directives 215283092Sjkim * Each entry is of the form "Name, ArgumentCount" 216233237Sjkim */ 217233237Sjkimstatic const PR_DIRECTIVE_INFO Gbl_DirectiveInfo[] = 218233237Sjkim{ 219283092Sjkim {"define", 1}, 220283092Sjkim {"elif", 0}, /* Converted to #else..#if internally */ 221283092Sjkim {"else", 0}, 222283092Sjkim {"endif", 0}, 223283092Sjkim {"error", 1}, 224283092Sjkim {"if", 1}, 225283092Sjkim {"ifdef", 1}, 226283092Sjkim {"ifndef", 1}, 227283092Sjkim {"include", 0}, /* Argument is not standard format, so just use 0 here */ 228283092Sjkim {"includebuffer", 0}, /* Argument is not standard format, so just use 0 here */ 229283092Sjkim {"line", 1}, 230283092Sjkim {"pragma", 1}, 231283092Sjkim {"undef", 1}, 232283092Sjkim {"warning", 1}, 233283092Sjkim {NULL, 0} 234233237Sjkim}; 235233237Sjkim 236283092Sjkim/* This table must match ordering of above table exactly */ 237283092Sjkim 238233237Sjkimenum Gbl_DirectiveIndexes 239233237Sjkim{ 240233237Sjkim PR_DIRECTIVE_DEFINE = 0, 241233237Sjkim PR_DIRECTIVE_ELIF, 242233237Sjkim PR_DIRECTIVE_ELSE, 243233237Sjkim PR_DIRECTIVE_ENDIF, 244233237Sjkim PR_DIRECTIVE_ERROR, 245233237Sjkim PR_DIRECTIVE_IF, 246233237Sjkim PR_DIRECTIVE_IFDEF, 247233237Sjkim PR_DIRECTIVE_IFNDEF, 248233237Sjkim PR_DIRECTIVE_INCLUDE, 249283092Sjkim PR_DIRECTIVE_INCLUDEBUFFER, 250233237Sjkim PR_DIRECTIVE_LINE, 251233237Sjkim PR_DIRECTIVE_PRAGMA, 252233237Sjkim PR_DIRECTIVE_UNDEF, 253285797Sjkim PR_DIRECTIVE_WARNING 254233237Sjkim}; 255233237Sjkim 256233237Sjkim#define ASL_DIRECTIVE_NOT_FOUND -1 257233237Sjkim 258233237Sjkim 259233237Sjkim/******************************************************************************* 260233237Sjkim * 261233237Sjkim * FUNCTION: PrInitializePreprocessor 262233237Sjkim * 263233237Sjkim * PARAMETERS: None 264233237Sjkim * 265233237Sjkim * RETURN: None 266233237Sjkim * 267233237Sjkim * DESCRIPTION: Startup initialization for the Preprocessor. 268233237Sjkim * 269233237Sjkim ******************************************************************************/ 270233237Sjkim 271233237Sjkimvoid 272233237SjkimPrInitializePreprocessor ( 273233237Sjkim void) 274233237Sjkim{ 275233237Sjkim /* Init globals and the list of #defines */ 276233237Sjkim 277233237Sjkim PrInitializeGlobals (); 278233237Sjkim Gbl_DefineList = NULL; 279233237Sjkim} 280233237Sjkim 281233237Sjkim 282233237Sjkim/******************************************************************************* 283233237Sjkim * 284233237Sjkim * FUNCTION: PrInitializeGlobals 285233237Sjkim * 286233237Sjkim * PARAMETERS: None 287233237Sjkim * 288233237Sjkim * RETURN: None 289233237Sjkim * 290233237Sjkim * DESCRIPTION: Initialize globals for the Preprocessor. Used for startuup 291233237Sjkim * initialization and re-initialization between compiles during 292233237Sjkim * a multiple source file compile. 293233237Sjkim * 294233237Sjkim ******************************************************************************/ 295233237Sjkim 296233237Sjkimvoid 297233237SjkimPrInitializeGlobals ( 298233237Sjkim void) 299233237Sjkim{ 300233237Sjkim /* Init globals */ 301233237Sjkim 302233237Sjkim Gbl_InputFileList = NULL; 303284583Sjkim Gbl_CurrentLineNumber = 1; 304233237Sjkim Gbl_PreprocessorLineNumber = 1; 305233237Sjkim Gbl_PreprocessorError = FALSE; 306252279Sjkim 307252279Sjkim /* These are used to track #if/#else blocks (possibly nested) */ 308252279Sjkim 309252279Sjkim Gbl_IfDepth = 0; 310252279Sjkim Gbl_IgnoringThisCodeBlock = FALSE; 311252279Sjkim Gbl_DirectiveStack = NULL; 312233237Sjkim} 313233237Sjkim 314233237Sjkim 315233237Sjkim/******************************************************************************* 316233237Sjkim * 317233237Sjkim * FUNCTION: PrTerminatePreprocessor 318233237Sjkim * 319233237Sjkim * PARAMETERS: None 320233237Sjkim * 321233237Sjkim * RETURN: None 322233237Sjkim * 323233237Sjkim * DESCRIPTION: Termination of the preprocessor. Delete lists. Keep any 324233237Sjkim * defines that were specified on the command line, in order to 325233237Sjkim * support multiple compiles with a single compiler invocation. 326233237Sjkim * 327233237Sjkim ******************************************************************************/ 328233237Sjkim 329233237Sjkimvoid 330233237SjkimPrTerminatePreprocessor ( 331233237Sjkim void) 332233237Sjkim{ 333233237Sjkim PR_DEFINE_INFO *DefineInfo; 334233237Sjkim 335233237Sjkim 336233237Sjkim /* 337233237Sjkim * The persistent defines (created on the command line) are always at the 338233237Sjkim * end of the list. We save them. 339233237Sjkim */ 340233237Sjkim while ((Gbl_DefineList) && (!Gbl_DefineList->Persist)) 341233237Sjkim { 342233237Sjkim DefineInfo = Gbl_DefineList; 343233237Sjkim Gbl_DefineList = DefineInfo->Next; 344233237Sjkim 345233237Sjkim ACPI_FREE (DefineInfo->Replacement); 346233237Sjkim ACPI_FREE (DefineInfo->Identifier); 347233237Sjkim ACPI_FREE (DefineInfo); 348233237Sjkim } 349233237Sjkim} 350233237Sjkim 351233237Sjkim 352233237Sjkim/******************************************************************************* 353233237Sjkim * 354233237Sjkim * FUNCTION: PrDoPreprocess 355233237Sjkim * 356233237Sjkim * PARAMETERS: None 357233237Sjkim * 358252279Sjkim * RETURN: None 359233237Sjkim * 360233237Sjkim * DESCRIPTION: Main entry point for the iASL Preprocessor. Input file must 361233237Sjkim * be already open. Handles multiple input files via the 362233237Sjkim * #include directive. 363233237Sjkim * 364233237Sjkim ******************************************************************************/ 365233237Sjkim 366252279Sjkimvoid 367233237SjkimPrDoPreprocess ( 368233237Sjkim void) 369233237Sjkim{ 370233237Sjkim BOOLEAN MoreInputFiles; 371233237Sjkim 372233237Sjkim 373233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Starting preprocessing phase\n\n"); 374233237Sjkim 375233237Sjkim 376233237Sjkim FlSeekFile (ASL_FILE_INPUT, 0); 377233237Sjkim PrDumpPredefinedNames (); 378233237Sjkim 379233237Sjkim /* Main preprocessor loop, handles include files */ 380233237Sjkim 381233237Sjkim do 382233237Sjkim { 383233237Sjkim PrPreprocessInputFile (); 384233237Sjkim MoreInputFiles = PrPopInputFileStack (); 385233237Sjkim 386233237Sjkim } while (MoreInputFiles); 387233237Sjkim 388284583Sjkim /* Point compiler input to the new preprocessor output file (.pre) */ 389233237Sjkim 390233237Sjkim FlCloseFile (ASL_FILE_INPUT); 391233237Sjkim Gbl_Files[ASL_FILE_INPUT].Handle = Gbl_Files[ASL_FILE_PREPROCESSOR].Handle; 392233237Sjkim AslCompilerin = Gbl_Files[ASL_FILE_INPUT].Handle; 393233237Sjkim 394233237Sjkim /* Reset globals to allow compiler to run */ 395233237Sjkim 396233237Sjkim FlSeekFile (ASL_FILE_INPUT, 0); 397284583Sjkim if (!Gbl_PreprocessOnly) 398284583Sjkim { 399284583Sjkim Gbl_CurrentLineNumber = 0; 400284583Sjkim } 401233237Sjkim 402233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Preprocessing phase complete \n\n"); 403233237Sjkim} 404233237Sjkim 405233237Sjkim 406233237Sjkim/******************************************************************************* 407233237Sjkim * 408233237Sjkim * FUNCTION: PrPreprocessInputFile 409233237Sjkim * 410233237Sjkim * PARAMETERS: None 411233237Sjkim * 412233237Sjkim * RETURN: None 413233237Sjkim * 414233237Sjkim * DESCRIPTION: Preprocess one entire file, line-by-line. 415233237Sjkim * 416233237Sjkim * Input: Raw user ASL from ASL_FILE_INPUT 417284583Sjkim * Output: Preprocessed file written to ASL_FILE_PREPROCESSOR and 418284583Sjkim * (optionally) ASL_FILE_PREPROCESSOR_USER 419233237Sjkim * 420233237Sjkim ******************************************************************************/ 421233237Sjkim 422233237Sjkimstatic void 423233237SjkimPrPreprocessInputFile ( 424233237Sjkim void) 425233237Sjkim{ 426284583Sjkim UINT32 Status; 427233237Sjkim char *Token; 428233237Sjkim char *ReplaceString; 429233237Sjkim PR_DEFINE_INFO *DefineInfo; 430233237Sjkim ACPI_SIZE TokenOffset; 431233237Sjkim char *Next; 432233237Sjkim int OffsetAdjust; 433233237Sjkim 434233237Sjkim 435284583Sjkim PrGetNextLineInit (); 436284583Sjkim 437285797Sjkim /* Scan source line-by-line and process directives. Then write the .i file */ 438233237Sjkim 439284583Sjkim while ((Status = PrGetNextLine (Gbl_Files[ASL_FILE_INPUT].Handle)) != ASL_EOF) 440233237Sjkim { 441284583Sjkim Gbl_CurrentLineNumber++; 442284583Sjkim Gbl_LogicalLineNumber++; 443284583Sjkim 444298714Sjkim if (Status == ASL_IGNORE_LINE) 445284583Sjkim { 446284583Sjkim goto WriteEntireLine; 447284583Sjkim } 448284583Sjkim 449233237Sjkim /* Need a copy of the input line for strok() */ 450233237Sjkim 451233237Sjkim strcpy (Gbl_MainTokenBuffer, Gbl_CurrentLineBuffer); 452233237Sjkim Token = PrGetNextToken (Gbl_MainTokenBuffer, PR_TOKEN_SEPARATORS, &Next); 453233237Sjkim OffsetAdjust = 0; 454233237Sjkim 455233237Sjkim /* All preprocessor directives must begin with '#' */ 456233237Sjkim 457233237Sjkim if (Token && (*Token == '#')) 458233237Sjkim { 459233237Sjkim if (strlen (Token) == 1) 460233237Sjkim { 461233237Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 462233237Sjkim } 463233237Sjkim else 464233237Sjkim { 465233237Sjkim Token++; /* Skip leading # */ 466233237Sjkim } 467233237Sjkim 468233237Sjkim /* Execute the directive, do not write line to output file */ 469233237Sjkim 470252279Sjkim PrDoDirective (Token, &Next); 471233237Sjkim continue; 472233237Sjkim } 473233237Sjkim 474233237Sjkim /* 475233237Sjkim * If we are currently within the part of an IF/ELSE block that is 476233237Sjkim * FALSE, ignore the line and do not write it to the output file. 477233237Sjkim * This continues until an #else or #endif is encountered. 478233237Sjkim */ 479252279Sjkim if (Gbl_IgnoringThisCodeBlock) 480233237Sjkim { 481233237Sjkim continue; 482233237Sjkim } 483233237Sjkim 484233237Sjkim /* Match and replace all #defined names within this source line */ 485233237Sjkim 486233237Sjkim while (Token) 487233237Sjkim { 488233237Sjkim DefineInfo = PrMatchDefine (Token); 489233237Sjkim if (DefineInfo) 490233237Sjkim { 491233237Sjkim if (DefineInfo->Body) 492233237Sjkim { 493233237Sjkim /* This is a macro */ 494233237Sjkim 495233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 496233237Sjkim "Matched Macro: %s->%s\n", 497233237Sjkim Gbl_CurrentLineNumber, DefineInfo->Identifier, 498233237Sjkim DefineInfo->Replacement); 499233237Sjkim 500233237Sjkim PrDoMacroInvocation (Gbl_MainTokenBuffer, Token, 501233237Sjkim DefineInfo, &Next); 502233237Sjkim } 503233237Sjkim else 504233237Sjkim { 505233237Sjkim ReplaceString = DefineInfo->Replacement; 506233237Sjkim 507233237Sjkim /* Replace the name in the original line buffer */ 508233237Sjkim 509233237Sjkim TokenOffset = Token - Gbl_MainTokenBuffer + OffsetAdjust; 510233237Sjkim PrReplaceData ( 511233237Sjkim &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token), 512233237Sjkim ReplaceString, strlen (ReplaceString)); 513233237Sjkim 514233237Sjkim /* Adjust for length difference between old and new name length */ 515233237Sjkim 516233237Sjkim OffsetAdjust += strlen (ReplaceString) - strlen (Token); 517233237Sjkim 518233237Sjkim DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID 519233237Sjkim "Matched #define: %s->%s\n", 520233237Sjkim Gbl_CurrentLineNumber, Token, 521233237Sjkim *ReplaceString ? ReplaceString : "(NULL STRING)"); 522233237Sjkim } 523233237Sjkim } 524233237Sjkim 525233237Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, &Next); 526233237Sjkim } 527233237Sjkim 528234623Sjkim Gbl_PreprocessorLineNumber++; 529234623Sjkim 530284583Sjkim 531284583SjkimWriteEntireLine: 532234623Sjkim /* 533234623Sjkim * Now we can write the possibly modified source line to the 534284583Sjkim * preprocessor file(s). 535234623Sjkim */ 536233237Sjkim FlWriteFile (ASL_FILE_PREPROCESSOR, Gbl_CurrentLineBuffer, 537233237Sjkim strlen (Gbl_CurrentLineBuffer)); 538233237Sjkim } 539233237Sjkim} 540233237Sjkim 541233237Sjkim 542233237Sjkim/******************************************************************************* 543233237Sjkim * 544233237Sjkim * FUNCTION: PrDoDirective 545233237Sjkim * 546233237Sjkim * PARAMETERS: Directive - Pointer to directive name token 547233237Sjkim * Next - "Next" buffer from GetNextToken 548233237Sjkim * 549252279Sjkim * RETURN: None. 550233237Sjkim * 551233237Sjkim * DESCRIPTION: Main processing for all preprocessor directives 552233237Sjkim * 553233237Sjkim ******************************************************************************/ 554233237Sjkim 555233237Sjkimstatic void 556233237SjkimPrDoDirective ( 557233237Sjkim char *DirectiveToken, 558252279Sjkim char **Next) 559233237Sjkim{ 560233237Sjkim char *Token = Gbl_MainTokenBuffer; 561283092Sjkim char *Token2 = NULL; 562233237Sjkim char *End; 563233237Sjkim UINT64 Value; 564233237Sjkim ACPI_SIZE TokenOffset; 565233237Sjkim int Directive; 566233237Sjkim ACPI_STATUS Status; 567233237Sjkim 568233237Sjkim 569233237Sjkim if (!DirectiveToken) 570233237Sjkim { 571233237Sjkim goto SyntaxError; 572233237Sjkim } 573233237Sjkim 574233237Sjkim Directive = PrMatchDirective (DirectiveToken); 575233237Sjkim if (Directive == ASL_DIRECTIVE_NOT_FOUND) 576233237Sjkim { 577233237Sjkim PrError (ASL_ERROR, ASL_MSG_UNKNOWN_DIRECTIVE, 578233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 579233237Sjkim 580283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 581233237Sjkim "#%s: Unknown directive\n", 582233237Sjkim Gbl_CurrentLineNumber, DirectiveToken); 583233237Sjkim return; 584233237Sjkim } 585233237Sjkim 586252279Sjkim /* 587285797Sjkim * Emit a line directive into the preprocessor file (.pre) after 588285797Sjkim * every matched directive. This is passed through to the compiler 589285797Sjkim * so that error/warning messages are kept in sync with the 590285797Sjkim * original source file. 591285797Sjkim */ 592285797Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\" // #%s\n", 593285797Sjkim Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename, 594285797Sjkim Gbl_DirectiveInfo[Directive].Name); 595285797Sjkim 596285797Sjkim /* 597252279Sjkim * If we are currently ignoring this block and we encounter a #else or 598252279Sjkim * #elif, we must ignore their blocks also if the parent block is also 599252279Sjkim * being ignored. 600252279Sjkim */ 601252279Sjkim if (Gbl_IgnoringThisCodeBlock) 602252279Sjkim { 603252279Sjkim switch (Directive) 604252279Sjkim { 605252279Sjkim case PR_DIRECTIVE_ELSE: 606252279Sjkim case PR_DIRECTIVE_ELIF: 607233237Sjkim 608298714Sjkim if (Gbl_DirectiveStack && 609298714Sjkim Gbl_DirectiveStack->IgnoringThisCodeBlock) 610252279Sjkim { 611252279Sjkim PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); 612252279Sjkim return; 613252279Sjkim } 614252279Sjkim break; 615252279Sjkim 616252279Sjkim default: 617252279Sjkim break; 618252279Sjkim } 619233237Sjkim } 620233237Sjkim 621233237Sjkim /* 622233237Sjkim * Need to always check for #else, #elif, #endif regardless of 623233237Sjkim * whether we are ignoring the current code block, since these 624233237Sjkim * are conditional code block terminators. 625233237Sjkim */ 626233237Sjkim switch (Directive) 627233237Sjkim { 628252279Sjkim case PR_DIRECTIVE_ELSE: 629252279Sjkim 630252279Sjkim Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); 631252279Sjkim PrDbgPrint ("Executing", "else block"); 632252279Sjkim return; 633252279Sjkim 634233237Sjkim case PR_DIRECTIVE_ELIF: 635250838Sjkim 636252279Sjkim Gbl_IgnoringThisCodeBlock = !(Gbl_IgnoringThisCodeBlock); 637252279Sjkim Directive = PR_DIRECTIVE_IF; 638252279Sjkim 639252279Sjkim if (Gbl_IgnoringThisCodeBlock == TRUE) 640233237Sjkim { 641233237Sjkim /* Not executing the ELSE part -- all done here */ 642252279Sjkim PrDbgPrint ("Ignoring", "elif block"); 643233237Sjkim return; 644233237Sjkim } 645233237Sjkim 646252279Sjkim /* 647252279Sjkim * After this, we will execute the IF part further below. 648252279Sjkim * First, however, pop off the original #if directive. 649252279Sjkim */ 650252279Sjkim if (ACPI_FAILURE (PrPopDirective ())) 651252279Sjkim { 652252279Sjkim PrError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, 653252279Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 654252279Sjkim } 655233237Sjkim 656252279Sjkim PrDbgPrint ("Executing", "elif block"); 657233237Sjkim break; 658233237Sjkim 659252279Sjkim case PR_DIRECTIVE_ENDIF: 660250838Sjkim 661252279Sjkim PrDbgPrint ("Executing", "endif"); 662233237Sjkim 663252279Sjkim /* Pop the owning #if/#ifdef/#ifndef */ 664250838Sjkim 665252279Sjkim if (ACPI_FAILURE (PrPopDirective ())) 666233237Sjkim { 667233237Sjkim PrError (ASL_ERROR, ASL_MSG_ENDIF_MISMATCH, 668233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 669233237Sjkim } 670233237Sjkim return; 671233237Sjkim 672233237Sjkim default: 673233237Sjkim break; 674233237Sjkim } 675233237Sjkim 676252279Sjkim /* Most directives have at least one argument */ 677252279Sjkim 678283092Sjkim if (Gbl_DirectiveInfo[Directive].ArgCount >= 1) 679252279Sjkim { 680252279Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 681252279Sjkim if (!Token) 682252279Sjkim { 683252279Sjkim goto SyntaxError; 684252279Sjkim } 685252279Sjkim } 686252279Sjkim 687283092Sjkim if (Gbl_DirectiveInfo[Directive].ArgCount >= 2) 688283092Sjkim { 689283092Sjkim Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 690283092Sjkim if (!Token2) 691283092Sjkim { 692283092Sjkim goto SyntaxError; 693283092Sjkim } 694283092Sjkim } 695283092Sjkim 696233237Sjkim /* 697233237Sjkim * At this point, if we are ignoring the current code block, 698233237Sjkim * do not process any more directives (i.e., ignore them also.) 699252279Sjkim * For "if" style directives, open/push a new block anyway. We 700252279Sjkim * must do this to keep track of #endif directives 701233237Sjkim */ 702252279Sjkim if (Gbl_IgnoringThisCodeBlock) 703233237Sjkim { 704252279Sjkim switch (Directive) 705252279Sjkim { 706252279Sjkim case PR_DIRECTIVE_IF: 707252279Sjkim case PR_DIRECTIVE_IFDEF: 708252279Sjkim case PR_DIRECTIVE_IFNDEF: 709252279Sjkim 710252279Sjkim PrPushDirective (Directive, Token); 711252279Sjkim PrDbgPrint ("Ignoring", Gbl_DirectiveInfo[Directive].Name); 712252279Sjkim break; 713252279Sjkim 714252279Sjkim default: 715252279Sjkim break; 716252279Sjkim } 717252279Sjkim 718233237Sjkim return; 719233237Sjkim } 720233237Sjkim 721252279Sjkim /* 722252279Sjkim * Execute the directive 723252279Sjkim */ 724252279Sjkim PrDbgPrint ("Begin execution", Gbl_DirectiveInfo[Directive].Name); 725233237Sjkim 726252279Sjkim switch (Directive) 727252279Sjkim { 728252279Sjkim case PR_DIRECTIVE_IF: 729233237Sjkim 730252279Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 731252279Sjkim 732252279Sjkim /* Need to expand #define macros in the expression string first */ 733252279Sjkim 734252279Sjkim Status = PrResolveIntegerExpression ( 735252279Sjkim &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 736252279Sjkim if (ACPI_FAILURE (Status)) 737233237Sjkim { 738252279Sjkim return; 739233237Sjkim } 740233237Sjkim 741252279Sjkim PrPushDirective (Directive, Token); 742252279Sjkim if (!Value) 743252279Sjkim { 744252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 745252279Sjkim } 746252279Sjkim 747283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 748252279Sjkim "Resolved #if: %8.8X%8.8X %s\n", 749252279Sjkim Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value), 750252279Sjkim Gbl_IgnoringThisCodeBlock ? "<Skipping Block>" : "<Executing Block>"); 751252279Sjkim break; 752252279Sjkim 753252279Sjkim case PR_DIRECTIVE_IFDEF: 754252279Sjkim 755252279Sjkim PrPushDirective (Directive, Token); 756252279Sjkim if (!PrMatchDefine (Token)) 757252279Sjkim { 758252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 759252279Sjkim } 760252279Sjkim 761252279Sjkim PrDbgPrint ("Evaluated", "ifdef"); 762252279Sjkim break; 763252279Sjkim 764252279Sjkim case PR_DIRECTIVE_IFNDEF: 765252279Sjkim 766252279Sjkim PrPushDirective (Directive, Token); 767252279Sjkim if (PrMatchDefine (Token)) 768252279Sjkim { 769252279Sjkim Gbl_IgnoringThisCodeBlock = TRUE; 770252279Sjkim } 771252279Sjkim 772252279Sjkim PrDbgPrint ("Evaluated", "ifndef"); 773252279Sjkim break; 774252279Sjkim 775233237Sjkim case PR_DIRECTIVE_DEFINE: 776233237Sjkim /* 777233237Sjkim * By definition, if first char after the name is a paren, 778233237Sjkim * this is a function macro. 779233237Sjkim */ 780233237Sjkim TokenOffset = Token - Gbl_MainTokenBuffer + strlen (Token); 781233237Sjkim if (*(&Gbl_CurrentLineBuffer[TokenOffset]) == '(') 782233237Sjkim { 783233237Sjkim#ifndef MACROS_SUPPORTED 784298714Sjkim AcpiOsPrintf ( 785298714Sjkim "%s ERROR - line %u: #define macros are not supported yet\n", 786284583Sjkim Gbl_CurrentLineBuffer, Gbl_LogicalLineNumber); 787234623Sjkim exit(1); 788233237Sjkim#else 789233237Sjkim PrAddMacro (Token, Next); 790233237Sjkim#endif 791233237Sjkim } 792233237Sjkim else 793233237Sjkim { 794233237Sjkim /* Use the remainder of the line for the #define */ 795233237Sjkim 796233237Sjkim Token2 = *Next; 797233237Sjkim if (Token2) 798233237Sjkim { 799233237Sjkim while ((*Token2 == ' ') || (*Token2 == '\t')) 800233237Sjkim { 801233237Sjkim Token2++; 802233237Sjkim } 803298714Sjkim 804233237Sjkim End = Token2; 805233237Sjkim while (*End != '\n') 806233237Sjkim { 807233237Sjkim End++; 808233237Sjkim } 809298714Sjkim 810233237Sjkim *End = 0; 811233237Sjkim } 812233237Sjkim else 813233237Sjkim { 814233237Sjkim Token2 = ""; 815233237Sjkim } 816233237Sjkim#if 0 817233237Sjkim Token2 = PrGetNextToken (NULL, "\n", /*PR_TOKEN_SEPARATORS,*/ Next); 818233237Sjkim if (!Token2) 819233237Sjkim { 820233237Sjkim Token2 = ""; 821233237Sjkim } 822233237Sjkim#endif 823283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 824233237Sjkim "New #define: %s->%s\n", 825284583Sjkim Gbl_LogicalLineNumber, Token, Token2); 826233237Sjkim 827233237Sjkim PrAddDefine (Token, Token2, FALSE); 828233237Sjkim } 829233237Sjkim break; 830233237Sjkim 831233237Sjkim case PR_DIRECTIVE_ERROR: 832250838Sjkim 833233237Sjkim /* Note: No macro expansion */ 834233237Sjkim 835233237Sjkim PrError (ASL_ERROR, ASL_MSG_ERROR_DIRECTIVE, 836233237Sjkim THIS_TOKEN_OFFSET (Token)); 837233237Sjkim 838252279Sjkim Gbl_SourceLine = 0; 839252279Sjkim Gbl_NextError = Gbl_ErrorLog; 840252279Sjkim CmCleanupAndExit (); 841252279Sjkim exit(1); 842250838Sjkim 843233237Sjkim case PR_DIRECTIVE_INCLUDE: 844250838Sjkim 845233237Sjkim Token = PrGetNextToken (NULL, " \"<>", Next); 846233237Sjkim if (!Token) 847233237Sjkim { 848233237Sjkim goto SyntaxError; 849233237Sjkim } 850233237Sjkim 851283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 852235945Sjkim "Start #include file \"%s\"\n", Gbl_CurrentLineNumber, 853233237Sjkim Token, Gbl_CurrentLineNumber); 854233237Sjkim 855283092Sjkim PrDoIncludeFile (Token); 856233237Sjkim break; 857233237Sjkim 858283092Sjkim case PR_DIRECTIVE_INCLUDEBUFFER: 859283092Sjkim 860283092Sjkim Token = PrGetNextToken (NULL, " \"<>", Next); 861283092Sjkim if (!Token) 862283092Sjkim { 863283092Sjkim goto SyntaxError; 864283092Sjkim } 865283092Sjkim 866283092Sjkim Token2 = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 867283092Sjkim if (!Token2) 868283092Sjkim { 869283092Sjkim goto SyntaxError; 870283092Sjkim } 871283092Sjkim 872283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 873283092Sjkim "Start #includebuffer input from file \"%s\", buffer name %s\n", 874283092Sjkim Gbl_CurrentLineNumber, Token, Token2); 875283092Sjkim 876283092Sjkim PrDoIncludeBuffer (Token, Token2); 877283092Sjkim break; 878283092Sjkim 879234623Sjkim case PR_DIRECTIVE_LINE: 880250838Sjkim 881234623Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 882234623Sjkim 883234623Sjkim Status = PrResolveIntegerExpression ( 884234623Sjkim &Gbl_CurrentLineBuffer[TokenOffset-1], &Value); 885234623Sjkim if (ACPI_FAILURE (Status)) 886234623Sjkim { 887234623Sjkim return; 888234623Sjkim } 889234623Sjkim 890283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 891234623Sjkim "User #line invocation %s\n", Gbl_CurrentLineNumber, 892234623Sjkim Token); 893234623Sjkim 894234623Sjkim Gbl_CurrentLineNumber = (UINT32) Value; 895234623Sjkim 896234623Sjkim /* Emit #line into the preprocessor file */ 897234623Sjkim 898234623Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "#line %u \"%s\"\n", 899234623Sjkim Gbl_CurrentLineNumber, Gbl_Files[ASL_FILE_INPUT].Filename); 900234623Sjkim break; 901234623Sjkim 902233237Sjkim case PR_DIRECTIVE_PRAGMA: 903233237Sjkim 904250838Sjkim if (!strcmp (Token, "disable")) 905233237Sjkim { 906250838Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 907250838Sjkim if (!Token) 908250838Sjkim { 909250838Sjkim goto SyntaxError; 910250838Sjkim } 911250838Sjkim 912250838Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 913250838Sjkim AslDisableException (&Gbl_CurrentLineBuffer[TokenOffset]); 914250838Sjkim } 915250838Sjkim else if (!strcmp (Token, "message")) 916250838Sjkim { 917250838Sjkim Token = PrGetNextToken (NULL, PR_TOKEN_SEPARATORS, Next); 918250838Sjkim if (!Token) 919250838Sjkim { 920250838Sjkim goto SyntaxError; 921250838Sjkim } 922250838Sjkim 923250838Sjkim TokenOffset = Token - Gbl_MainTokenBuffer; 924250838Sjkim AcpiOsPrintf ("%s\n", &Gbl_CurrentLineBuffer[TokenOffset]); 925250838Sjkim } 926250838Sjkim else 927250838Sjkim { 928233237Sjkim PrError (ASL_ERROR, ASL_MSG_UNKNOWN_PRAGMA, 929233237Sjkim THIS_TOKEN_OFFSET (Token)); 930233237Sjkim return; 931233237Sjkim } 932233237Sjkim 933233237Sjkim break; 934233237Sjkim 935233237Sjkim case PR_DIRECTIVE_UNDEF: 936250838Sjkim 937283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 938233237Sjkim "#undef: %s\n", Gbl_CurrentLineNumber, Token); 939233237Sjkim 940233237Sjkim PrRemoveDefine (Token); 941233237Sjkim break; 942233237Sjkim 943233237Sjkim case PR_DIRECTIVE_WARNING: 944250838Sjkim 945252279Sjkim PrError (ASL_WARNING, ASL_MSG_WARNING_DIRECTIVE, 946233237Sjkim THIS_TOKEN_OFFSET (Token)); 947285797Sjkim 948285797Sjkim Gbl_SourceLine = 0; 949285797Sjkim Gbl_NextError = Gbl_ErrorLog; 950233237Sjkim break; 951233237Sjkim 952233237Sjkim default: 953250838Sjkim 954233237Sjkim /* Should never get here */ 955283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 956233237Sjkim "Unrecognized directive: %u\n", 957233237Sjkim Gbl_CurrentLineNumber, Directive); 958233237Sjkim break; 959233237Sjkim } 960233237Sjkim 961233237Sjkim return; 962233237Sjkim 963233237SjkimSyntaxError: 964233237Sjkim 965233237Sjkim PrError (ASL_ERROR, ASL_MSG_DIRECTIVE_SYNTAX, 966233237Sjkim THIS_TOKEN_OFFSET (DirectiveToken)); 967233237Sjkim return; 968233237Sjkim} 969233237Sjkim 970233237Sjkim 971233237Sjkim/******************************************************************************* 972233237Sjkim * 973284583Sjkim * FUNCTION: PrGetNextLine, PrGetNextLineInit 974284583Sjkim * 975284583Sjkim * PARAMETERS: Handle - Open file handle for the source file 976284583Sjkim * 977284583Sjkim * RETURN: Status of the GetLine operation: 978284583Sjkim * AE_OK - Normal line, OK status 979298714Sjkim * ASL_IGNORE_LINE - Line is blank or part of a multi-line 980298714Sjkim * comment 981284583Sjkim * ASL_EOF - End-of-file reached 982284583Sjkim * 983284583Sjkim * DESCRIPTION: Get the next text line from the input file. Does not strip 984284583Sjkim * comments. 985284583Sjkim * 986284583Sjkim ******************************************************************************/ 987284583Sjkim 988284583Sjkim#define PR_NORMAL_TEXT 0 989285797Sjkim#define PR_MULTI_LINE_COMMENT 1 990285797Sjkim#define PR_SINGLE_LINE_COMMENT 2 991285797Sjkim#define PR_QUOTED_STRING 3 992284583Sjkim 993284583Sjkimstatic UINT8 AcpiGbl_LineScanState = PR_NORMAL_TEXT; 994284583Sjkim 995284583Sjkimstatic void 996284583SjkimPrGetNextLineInit ( 997284583Sjkim void) 998284583Sjkim{ 999284583Sjkim AcpiGbl_LineScanState = 0; 1000284583Sjkim} 1001284583Sjkim 1002284583Sjkimstatic UINT32 1003284583SjkimPrGetNextLine ( 1004284583Sjkim FILE *Handle) 1005284583Sjkim{ 1006284583Sjkim UINT32 i; 1007284583Sjkim int c = 0; 1008284583Sjkim int PreviousChar; 1009284583Sjkim 1010284583Sjkim 1011284583Sjkim /* Always clear the global line buffer */ 1012284583Sjkim 1013284583Sjkim memset (Gbl_CurrentLineBuffer, 0, Gbl_LineBufferSize); 1014284583Sjkim for (i = 0; ;) 1015284583Sjkim { 1016284583Sjkim /* 1017284583Sjkim * If line is too long, expand the line buffers. Also increases 1018284583Sjkim * Gbl_LineBufferSize. 1019284583Sjkim */ 1020284583Sjkim if (i >= Gbl_LineBufferSize) 1021284583Sjkim { 1022284583Sjkim UtExpandLineBuffers (); 1023284583Sjkim } 1024284583Sjkim 1025284583Sjkim PreviousChar = c; 1026284583Sjkim c = getc (Handle); 1027284583Sjkim if (c == EOF) 1028284583Sjkim { 1029298714Sjkim /* 1030298714Sjkim * On EOF: If there is anything in the line buffer, terminate 1031298714Sjkim * it with a newline, and catch the EOF on the next call 1032298714Sjkim * to this function. 1033298714Sjkim */ 1034298714Sjkim if (i > 0) 1035298714Sjkim { 1036298714Sjkim Gbl_CurrentLineBuffer[i] = '\n'; 1037298714Sjkim return (AE_OK); 1038298714Sjkim } 1039298714Sjkim 1040284583Sjkim return (ASL_EOF); 1041284583Sjkim } 1042284583Sjkim 1043285797Sjkim /* Update state machine as necessary */ 1044284583Sjkim 1045285797Sjkim switch (AcpiGbl_LineScanState) 1046284583Sjkim { 1047285797Sjkim case PR_NORMAL_TEXT: 1048284583Sjkim 1049285797Sjkim /* Check for multi-line comment start */ 1050284583Sjkim 1051285797Sjkim if ((PreviousChar == '/') && (c == '*')) 1052285797Sjkim { 1053285797Sjkim AcpiGbl_LineScanState = PR_MULTI_LINE_COMMENT; 1054285797Sjkim } 1055285797Sjkim 1056285797Sjkim /* Check for single-line comment start */ 1057285797Sjkim 1058285797Sjkim else if ((PreviousChar == '/') && (c == '/')) 1059285797Sjkim { 1060285797Sjkim AcpiGbl_LineScanState = PR_SINGLE_LINE_COMMENT; 1061285797Sjkim } 1062285797Sjkim 1063285797Sjkim /* Check for quoted string start */ 1064285797Sjkim 1065285797Sjkim else if (PreviousChar == '"') 1066285797Sjkim { 1067285797Sjkim AcpiGbl_LineScanState = PR_QUOTED_STRING; 1068285797Sjkim } 1069285797Sjkim break; 1070285797Sjkim 1071285797Sjkim case PR_QUOTED_STRING: 1072285797Sjkim 1073285797Sjkim if (PreviousChar == '"') 1074285797Sjkim { 1075285797Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 1076285797Sjkim } 1077285797Sjkim break; 1078285797Sjkim 1079285797Sjkim case PR_MULTI_LINE_COMMENT: 1080285797Sjkim 1081285797Sjkim /* Check for multi-line comment end */ 1082285797Sjkim 1083285797Sjkim if ((PreviousChar == '*') && (c == '/')) 1084285797Sjkim { 1085285797Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 1086285797Sjkim } 1087285797Sjkim break; 1088285797Sjkim 1089285797Sjkim case PR_SINGLE_LINE_COMMENT: /* Just ignore text until EOL */ 1090285797Sjkim default: 1091285797Sjkim break; 1092284583Sjkim } 1093284583Sjkim 1094284583Sjkim /* Always copy the character into line buffer */ 1095284583Sjkim 1096284583Sjkim Gbl_CurrentLineBuffer[i] = (char) c; 1097284583Sjkim i++; 1098284583Sjkim 1099284583Sjkim /* Always exit on end-of-line */ 1100284583Sjkim 1101284583Sjkim if (c == '\n') 1102284583Sjkim { 1103284583Sjkim /* Handle multi-line comments */ 1104284583Sjkim 1105285797Sjkim if (AcpiGbl_LineScanState == PR_MULTI_LINE_COMMENT) 1106284583Sjkim { 1107298714Sjkim return (ASL_IGNORE_LINE); 1108284583Sjkim } 1109285797Sjkim 1110285797Sjkim /* End of single-line comment */ 1111285797Sjkim 1112285797Sjkim if (AcpiGbl_LineScanState == PR_SINGLE_LINE_COMMENT) 1113285797Sjkim { 1114285797Sjkim AcpiGbl_LineScanState = PR_NORMAL_TEXT; 1115285797Sjkim return (AE_OK); 1116285797Sjkim } 1117285797Sjkim 1118285797Sjkim /* Blank line */ 1119285797Sjkim 1120284583Sjkim if (i == 1) 1121284583Sjkim { 1122298714Sjkim return (ASL_IGNORE_LINE); 1123284583Sjkim } 1124298714Sjkim 1125284583Sjkim return (AE_OK); 1126284583Sjkim } 1127284583Sjkim } 1128284583Sjkim} 1129284583Sjkim 1130284583Sjkim 1131284583Sjkim/******************************************************************************* 1132284583Sjkim * 1133233237Sjkim * FUNCTION: PrMatchDirective 1134233237Sjkim * 1135233237Sjkim * PARAMETERS: Directive - Pointer to directive name token 1136233237Sjkim * 1137233237Sjkim * RETURN: Index into command array, -1 if not found 1138233237Sjkim * 1139233237Sjkim * DESCRIPTION: Lookup the incoming directive in the known directives table. 1140233237Sjkim * 1141233237Sjkim ******************************************************************************/ 1142233237Sjkim 1143233237Sjkimstatic int 1144233237SjkimPrMatchDirective ( 1145233237Sjkim char *Directive) 1146233237Sjkim{ 1147233237Sjkim int i; 1148233237Sjkim 1149233237Sjkim 1150233237Sjkim if (!Directive || Directive[0] == 0) 1151233237Sjkim { 1152233237Sjkim return (ASL_DIRECTIVE_NOT_FOUND); 1153233237Sjkim } 1154233237Sjkim 1155233237Sjkim for (i = 0; Gbl_DirectiveInfo[i].Name; i++) 1156233237Sjkim { 1157233237Sjkim if (!strcmp (Gbl_DirectiveInfo[i].Name, Directive)) 1158233237Sjkim { 1159233237Sjkim return (i); 1160233237Sjkim } 1161233237Sjkim } 1162233237Sjkim 1163233237Sjkim return (ASL_DIRECTIVE_NOT_FOUND); /* Command not recognized */ 1164233237Sjkim} 1165252279Sjkim 1166252279Sjkim 1167252279Sjkim/******************************************************************************* 1168252279Sjkim * 1169252279Sjkim * FUNCTION: PrPushDirective 1170252279Sjkim * 1171252279Sjkim * PARAMETERS: Directive - Encoded directive ID 1172252279Sjkim * Argument - String containing argument to the 1173252279Sjkim * directive 1174252279Sjkim * 1175252279Sjkim * RETURN: None 1176252279Sjkim * 1177252279Sjkim * DESCRIPTION: Push an item onto the directive stack. Used for processing 1178252279Sjkim * nested #if/#else type conditional compilation directives. 1179252279Sjkim * Specifically: Used on detection of #if/#ifdef/#ifndef to open 1180252279Sjkim * a block. 1181252279Sjkim * 1182252279Sjkim ******************************************************************************/ 1183252279Sjkim 1184252279Sjkimstatic void 1185252279SjkimPrPushDirective ( 1186252279Sjkim int Directive, 1187252279Sjkim char *Argument) 1188252279Sjkim{ 1189252279Sjkim DIRECTIVE_INFO *Info; 1190252279Sjkim 1191252279Sjkim 1192252279Sjkim /* Allocate and populate a stack info item */ 1193252279Sjkim 1194252279Sjkim Info = ACPI_ALLOCATE (sizeof (DIRECTIVE_INFO)); 1195252279Sjkim 1196252279Sjkim Info->Next = Gbl_DirectiveStack; 1197252279Sjkim Info->Directive = Directive; 1198252279Sjkim Info->IgnoringThisCodeBlock = Gbl_IgnoringThisCodeBlock; 1199327557Sjkim AcpiUtSafeStrncpy (Info->Argument, Argument, MAX_ARGUMENT_LENGTH); 1200252279Sjkim 1201252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 1202252279Sjkim "Pr(%.4u) - [%u %s] %*s Pushed [#%s %s]: IgnoreFlag = %s\n", 1203252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1204252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1205252279Sjkim Gbl_IfDepth * 4, " ", 1206252279Sjkim Gbl_DirectiveInfo[Directive].Name, 1207252279Sjkim Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); 1208252279Sjkim 1209252279Sjkim /* Push new item */ 1210252279Sjkim 1211252279Sjkim Gbl_DirectiveStack = Info; 1212252279Sjkim Gbl_IfDepth++; 1213252279Sjkim} 1214252279Sjkim 1215252279Sjkim 1216252279Sjkim/******************************************************************************* 1217252279Sjkim * 1218252279Sjkim * FUNCTION: PrPopDirective 1219252279Sjkim * 1220252279Sjkim * PARAMETERS: None 1221252279Sjkim * 1222252279Sjkim * RETURN: Status. Error if the stack is empty. 1223252279Sjkim * 1224252279Sjkim * DESCRIPTION: Pop an item off the directive stack. Used for processing 1225252279Sjkim * nested #if/#else type conditional compilation directives. 1226252279Sjkim * Specifically: Used on detection of #elif and #endif to remove 1227252279Sjkim * the original #if/#ifdef/#ifndef from the stack and close 1228252279Sjkim * the block. 1229252279Sjkim * 1230252279Sjkim ******************************************************************************/ 1231252279Sjkim 1232252279Sjkimstatic ACPI_STATUS 1233252279SjkimPrPopDirective ( 1234252279Sjkim void) 1235252279Sjkim{ 1236252279Sjkim DIRECTIVE_INFO *Info; 1237252279Sjkim 1238252279Sjkim 1239252279Sjkim /* Check for empty stack */ 1240252279Sjkim 1241252279Sjkim Info = Gbl_DirectiveStack; 1242252279Sjkim if (!Info) 1243252279Sjkim { 1244252279Sjkim return (AE_ERROR); 1245252279Sjkim } 1246252279Sjkim 1247252279Sjkim /* Pop one item, keep globals up-to-date */ 1248252279Sjkim 1249252279Sjkim Gbl_IfDepth--; 1250252279Sjkim Gbl_IgnoringThisCodeBlock = Info->IgnoringThisCodeBlock; 1251252279Sjkim Gbl_DirectiveStack = Info->Next; 1252252279Sjkim 1253252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, 1254252279Sjkim "Pr(%.4u) - [%u %s] %*s Popped [#%s %s]: IgnoreFlag now = %s\n", 1255252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1256252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1257252279Sjkim Gbl_IfDepth * 4, " ", 1258252279Sjkim Gbl_DirectiveInfo[Info->Directive].Name, 1259252279Sjkim Info->Argument, Gbl_IgnoringThisCodeBlock ? "TRUE" : "FALSE"); 1260252279Sjkim 1261252279Sjkim ACPI_FREE (Info); 1262252279Sjkim return (AE_OK); 1263252279Sjkim} 1264252279Sjkim 1265252279Sjkim 1266252279Sjkim/******************************************************************************* 1267252279Sjkim * 1268252279Sjkim * FUNCTION: PrDbgPrint 1269252279Sjkim * 1270252279Sjkim * PARAMETERS: Action - Action being performed 1271252279Sjkim * DirectiveName - Directive being processed 1272252279Sjkim * 1273252279Sjkim * RETURN: None 1274252279Sjkim * 1275252279Sjkim * DESCRIPTION: Special debug print for directive processing. 1276252279Sjkim * 1277252279Sjkim ******************************************************************************/ 1278252279Sjkim 1279252279Sjkimstatic void 1280252279SjkimPrDbgPrint ( 1281252279Sjkim char *Action, 1282252279Sjkim char *DirectiveName) 1283252279Sjkim{ 1284252279Sjkim 1285252279Sjkim DbgPrint (ASL_DEBUG_OUTPUT, "Pr(%.4u) - [%u %s] " 1286283092Sjkim "%*s %s #%s, IfDepth %u\n", 1287252279Sjkim Gbl_CurrentLineNumber, Gbl_IfDepth, 1288252279Sjkim Gbl_IgnoringThisCodeBlock ? "I" : "E", 1289252279Sjkim Gbl_IfDepth * 4, " ", 1290252279Sjkim Action, DirectiveName, Gbl_IfDepth); 1291252279Sjkim} 1292283092Sjkim 1293283092Sjkim 1294283092Sjkim/******************************************************************************* 1295283092Sjkim * 1296283092Sjkim * FUNCTION: PrDoIncludeFile 1297283092Sjkim * 1298283092Sjkim * PARAMETERS: Pathname - Name of the input file 1299283092Sjkim * 1300283092Sjkim * RETURN: None. 1301283092Sjkim * 1302283092Sjkim * DESCRIPTION: Open an include file, from #include. 1303283092Sjkim * 1304283092Sjkim ******************************************************************************/ 1305283092Sjkim 1306283092Sjkimstatic void 1307283092SjkimPrDoIncludeFile ( 1308283092Sjkim char *Pathname) 1309283092Sjkim{ 1310283092Sjkim char *FullPathname; 1311283092Sjkim 1312283092Sjkim 1313283092Sjkim (void) PrOpenIncludeFile (Pathname, "r", &FullPathname); 1314283092Sjkim} 1315283092Sjkim 1316283092Sjkim 1317283092Sjkim/******************************************************************************* 1318283092Sjkim * 1319283092Sjkim * FUNCTION: PrDoIncludeBuffer 1320283092Sjkim * 1321283092Sjkim * PARAMETERS: Pathname - Name of the input binary file 1322283092Sjkim * BufferName - ACPI namepath of the buffer 1323283092Sjkim * 1324283092Sjkim * RETURN: None. 1325283092Sjkim * 1326283092Sjkim * DESCRIPTION: Create an ACPI buffer object from a binary file. The contents 1327283092Sjkim * of the file are emitted into the buffer object as ascii 1328283092Sjkim * hex data. From #includebuffer. 1329283092Sjkim * 1330283092Sjkim ******************************************************************************/ 1331283092Sjkim 1332283092Sjkimstatic void 1333283092SjkimPrDoIncludeBuffer ( 1334283092Sjkim char *Pathname, 1335283092Sjkim char *BufferName) 1336283092Sjkim{ 1337283092Sjkim char *FullPathname; 1338283092Sjkim FILE *BinaryBufferFile; 1339283092Sjkim UINT32 i = 0; 1340283092Sjkim UINT8 c; 1341283092Sjkim 1342283092Sjkim 1343283092Sjkim BinaryBufferFile = PrOpenIncludeFile (Pathname, "rb", &FullPathname); 1344283092Sjkim if (!BinaryBufferFile) 1345283092Sjkim { 1346283092Sjkim return; 1347283092Sjkim } 1348283092Sjkim 1349283092Sjkim /* Emit "Name (XXXX, Buffer() {" header */ 1350283092Sjkim 1351283092Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "Name (%s, Buffer()\n{", BufferName); 1352283092Sjkim 1353283092Sjkim /* Dump the entire file in ascii hex format */ 1354283092Sjkim 1355283092Sjkim while (fread (&c, 1, 1, BinaryBufferFile)) 1356283092Sjkim { 1357283092Sjkim if (!(i % 8)) 1358283092Sjkim { 1359283092Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "\n ", c); 1360283092Sjkim } 1361283092Sjkim 1362283092Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, " 0x%2.2X,", c); 1363283092Sjkim i++; 1364283092Sjkim } 1365283092Sjkim 1366283092Sjkim DbgPrint (ASL_PARSE_OUTPUT, PR_PREFIX_ID 1367283092Sjkim "#includebuffer: read %u bytes from %s\n", 1368283092Sjkim Gbl_CurrentLineNumber, i, FullPathname); 1369283092Sjkim 1370283092Sjkim /* Close the Name() operator */ 1371283092Sjkim 1372283092Sjkim FlPrintFile (ASL_FILE_PREPROCESSOR, "\n})\n", BufferName); 1373283092Sjkim fclose (BinaryBufferFile); 1374283092Sjkim} 1375