Home | History | Annotate | Line # | Download | only in acpisrc
asremove.c revision 1.1.1.13
      1 /******************************************************************************
      2  *
      3  * Module Name: asremove - Source conversion - removal functions
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpisrc.h"
     45 
     46 /* Local prototypes */
     47 
     48 void
     49 AsRemoveStatement (
     50     char                    *Buffer,
     51     char                    *Keyword,
     52     UINT32                  Type);
     53 
     54 
     55 /******************************************************************************
     56  *
     57  * FUNCTION:    AsRemoveStatement
     58  *
     59  * DESCRIPTION: Remove all statements that contain the given keyword.
     60  *              Limitations:  Removes text from the start of the line that
     61  *              contains the keyword to the next semicolon. Currently
     62  *              doesn't ignore comments.
     63  *
     64  ******************************************************************************/
     65 
     66 void
     67 AsRemoveStatement (
     68     char                    *Buffer,
     69     char                    *Keyword,
     70     UINT32                  Type)
     71 {
     72     char                    *SubString;
     73     char                    *SubBuffer;
     74     int                     KeywordLength;
     75 
     76 
     77     KeywordLength = strlen (Keyword);
     78     SubBuffer = Buffer;
     79     SubString = Buffer;
     80 
     81     while (SubString)
     82     {
     83         SubString = strstr (SubBuffer, Keyword);
     84 
     85         if (SubString)
     86         {
     87             SubBuffer = SubString;
     88 
     89             if ((Type == REPLACE_WHOLE_WORD) &&
     90                 (!AsMatchExactWord (SubString, KeywordLength)))
     91             {
     92                 SubBuffer++;
     93                 continue;
     94             }
     95 
     96             /* Find start of this line */
     97 
     98             while (*SubString != '\n')
     99             {
    100                 SubString--;
    101             }
    102             SubString++;
    103 
    104             /* Find end of this statement */
    105 
    106             SubBuffer = AsSkipPastChar (SubBuffer, ';');
    107             if (!SubBuffer)
    108             {
    109                 return;
    110             }
    111 
    112             /* Find end of this line */
    113 
    114             SubBuffer = AsSkipPastChar (SubBuffer, '\n');
    115             if (!SubBuffer)
    116             {
    117                 return;
    118             }
    119 
    120             /* If next line is blank, remove it too */
    121 
    122             if (*SubBuffer == '\n')
    123             {
    124                 SubBuffer++;
    125             }
    126 
    127             /* Remove the lines */
    128 
    129             SubBuffer = AsRemoveData (SubString, SubBuffer);
    130         }
    131     }
    132 }
    133 
    134 
    135 /******************************************************************************
    136  *
    137  * FUNCTION:    AsRemoveConditionalCompile
    138  *
    139  * DESCRIPTION: Remove a "#ifdef" statement, and all text that it encompasses.
    140  *              Limitations: cannot handle nested ifdefs.
    141  *
    142  ******************************************************************************/
    143 
    144 void
    145 AsRemoveConditionalCompile (
    146     char                    *Buffer,
    147     char                    *Keyword)
    148 {
    149     char                    *SubString;
    150     char                    *SubBuffer;
    151     char                    *IfPtr;
    152     char                    *EndifPtr;
    153     char                    *ElsePtr;
    154     char                    *Comment;
    155     int                     KeywordLength;
    156 
    157 
    158     KeywordLength = strlen (Keyword);
    159     SubString = Buffer;
    160 
    161     while (SubString)
    162     {
    163         SubBuffer = strstr (SubString, Keyword);
    164         if (!SubBuffer)
    165         {
    166             return;
    167         }
    168 
    169         /*
    170          * Check for translation escape string -- means to ignore
    171          * blocks of code while replacing
    172          */
    173         if (Gbl_IgnoreTranslationEscapes)
    174         {
    175             Comment = NULL;
    176         }
    177         else
    178         {
    179             Comment = strstr (SubString, AS_START_IGNORE);
    180         }
    181 
    182         if ((Comment) &&
    183             (Comment < SubBuffer))
    184         {
    185             SubString = strstr (Comment, AS_STOP_IGNORE);
    186             if (!SubString)
    187             {
    188                 return;
    189             }
    190 
    191             SubString += 3;
    192             continue;
    193         }
    194 
    195         /* Check for ordinary comment */
    196 
    197         Comment = strstr (SubString, "/*");
    198 
    199         if ((Comment) &&
    200             (Comment < SubBuffer))
    201         {
    202             SubString = strstr (Comment, "*/");
    203             if (!SubString)
    204             {
    205                 return;
    206             }
    207 
    208             SubString += 2;
    209             continue;
    210         }
    211 
    212         SubString = SubBuffer;
    213         if (!AsMatchExactWord (SubString, KeywordLength))
    214         {
    215             SubString++;
    216             continue;
    217         }
    218 
    219         /* Find start of this line */
    220 
    221         while (*SubString != '\n' && (SubString > Buffer))
    222         {
    223             SubString--;
    224         }
    225 
    226         SubString++;
    227 
    228         /* Find the "#ifxxxx" */
    229 
    230         IfPtr = strstr (SubString, "#if");
    231         if (!IfPtr)
    232         {
    233             return;
    234         }
    235 
    236         if (IfPtr > SubBuffer)
    237         {
    238             /* Not the right #if */
    239 
    240             SubString = SubBuffer + strlen (Keyword);
    241             continue;
    242         }
    243 
    244         /* Find closing #endif or #else */
    245 
    246         EndifPtr = strstr (SubBuffer, "#endif");
    247         if (!EndifPtr)
    248         {
    249             /* There has to be an #endif */
    250 
    251             return;
    252         }
    253 
    254         ElsePtr = strstr (SubBuffer, "#else");
    255         if ((ElsePtr) &&
    256             (EndifPtr > ElsePtr))
    257         {
    258             /* This #ifdef contains an #else clause */
    259             /* Find end of this line */
    260 
    261             SubBuffer = AsSkipPastChar (ElsePtr, '\n');
    262             if (!SubBuffer)
    263             {
    264                 return;
    265             }
    266 
    267             /* Remove the #ifdef .... #else code */
    268 
    269             AsRemoveData (SubString, SubBuffer);
    270 
    271             /* Next, we will remove the #endif statement */
    272 
    273             EndifPtr = strstr (SubString, "#endif");
    274             if (!EndifPtr)
    275             {
    276                 /* There has to be an #endif */
    277 
    278                 return;
    279             }
    280 
    281             SubString = EndifPtr;
    282         }
    283 
    284         /* Remove the ... #endif part */
    285         /* Find end of this line */
    286 
    287         SubBuffer = AsSkipPastChar (EndifPtr, '\n');
    288         if (!SubBuffer)
    289         {
    290             return;
    291         }
    292 
    293         /* Remove the lines */
    294 
    295         (void) AsRemoveData (SubString, SubBuffer);
    296     }
    297 }
    298 
    299 
    300 #ifdef _OBSOLETE_FUNCTIONS
    301 /******************************************************************************
    302  *
    303  * FUNCTION:    AsRemoveMacro
    304  *
    305  * DESCRIPTION: Remove every line that contains the keyword. Does not
    306  *              skip comments.
    307  *
    308  ******************************************************************************/
    309 
    310 NOTE: This function is no longer used and is commented out for now.
    311 
    312 Also, it appears to have one or more bugs in it. It can incorrectly remove
    313 lines of code, producing some garbage.
    314 
    315 void
    316 AsRemoveMacro (
    317     char                    *Buffer,
    318     char                    *Keyword)
    319 {
    320     char                    *SubString;
    321     char                    *SubBuffer;
    322     int                     NestLevel;
    323 
    324 
    325     SubBuffer = Buffer;
    326     SubString = Buffer;
    327 
    328     while (SubString)
    329     {
    330         SubString = strstr (SubBuffer, Keyword);
    331 
    332         if (SubString)
    333         {
    334             SubBuffer = SubString;
    335 
    336             /* Find start of the macro parameters */
    337 
    338             while (*SubString != '(')
    339             {
    340                 SubString++;
    341             }
    342             SubString++;
    343 
    344             /* Remove the macro name and opening paren */
    345 
    346             SubString = AsRemoveData (SubBuffer, SubString);
    347 
    348             NestLevel = 1;
    349             while (*SubString)
    350             {
    351                 if (*SubString == '(')
    352                 {
    353                     NestLevel++;
    354                 }
    355                 else if (*SubString == ')')
    356                 {
    357                     NestLevel--;
    358                 }
    359 
    360                 SubString++;
    361 
    362                 if (NestLevel == 0)
    363                 {
    364                     break;
    365                 }
    366             }
    367 
    368             /* Remove the closing paren */
    369 
    370             SubBuffer = AsRemoveData (SubString-1, SubString);
    371         }
    372     }
    373 }
    374 #endif
    375 
    376 /******************************************************************************
    377  *
    378  * FUNCTION:    AsRemoveLine
    379  *
    380  * DESCRIPTION: Remove every line that contains the keyword. Does not
    381  *              skip comments.
    382  *
    383  ******************************************************************************/
    384 
    385 void
    386 AsRemoveLine (
    387     char                    *Buffer,
    388     char                    *Keyword)
    389 {
    390     char                    *SubString;
    391     char                    *SubBuffer;
    392 
    393 
    394     SubBuffer = Buffer;
    395     SubString = Buffer;
    396 
    397     while (SubString)
    398     {
    399         SubString = strstr (SubBuffer, Keyword);
    400 
    401         if (SubString)
    402         {
    403             SubBuffer = SubString;
    404 
    405             /* Find start of this line */
    406 
    407             while (*SubString != '\n')
    408             {
    409                 SubString--;
    410             }
    411             SubString++;
    412 
    413             /* Find end of this line */
    414 
    415             SubBuffer = AsSkipPastChar (SubBuffer, '\n');
    416             if (!SubBuffer)
    417             {
    418                 return;
    419             }
    420 
    421             /* Remove the line */
    422 
    423             SubBuffer = AsRemoveData (SubString, SubBuffer);
    424         }
    425     }
    426 }
    427 
    428 
    429 /******************************************************************************
    430  *
    431  * FUNCTION:    AsReduceTypedefs
    432  *
    433  * DESCRIPTION: Eliminate certain typedefs
    434  *
    435  ******************************************************************************/
    436 
    437 void
    438 AsReduceTypedefs (
    439     char                    *Buffer,
    440     char                    *Keyword)
    441 {
    442     char                    *SubString;
    443     char                    *SubBuffer;
    444     char                    *SubSubString;
    445     int                     NestLevel;
    446 
    447 
    448     SubBuffer = Buffer;
    449     SubString = Buffer;
    450 
    451     while (SubString)
    452     {
    453         SubString = strstr (SubBuffer, Keyword);
    454 
    455         if (SubString)
    456         {
    457             SubSubString = SubString + strlen (Keyword);
    458 
    459             /* skip spaces */
    460 
    461             while (strchr(" \t\r\n", *SubSubString))
    462             {
    463                 SubSubString++;
    464             }
    465 
    466             /* skip type name */
    467 
    468             while (!strchr(" \t\r\n", *SubSubString))
    469             {
    470                 SubSubString++;
    471             }
    472 
    473             /* skip spaces */
    474 
    475             while (strchr(" \t\r\n", *SubSubString))
    476             {
    477                 SubSubString++;
    478             }
    479 
    480             if (*SubSubString == '{')
    481             {
    482                 /* Remove the typedef itself */
    483 
    484                 SubBuffer = SubString + strlen ("typedef") + 1;
    485                 (void) AsRemoveData (SubString, SubBuffer);
    486 
    487                 /* Find the opening brace of the struct or union */
    488 
    489                 while (*SubString != '{')
    490                 {
    491                     SubString++;
    492                 }
    493                 SubString++;
    494 
    495                 /* Find the closing brace. Handles nested braces */
    496 
    497                 NestLevel = 1;
    498                 while (*SubString)
    499                 {
    500                     if (*SubString == '{')
    501                     {
    502                         NestLevel++;
    503                     }
    504                     else if (*SubString == '}')
    505                     {
    506                         NestLevel--;
    507                     }
    508 
    509                     SubString++;
    510 
    511                     if (NestLevel == 0)
    512                     {
    513                         break;
    514                     }
    515                 }
    516 
    517                 /* Remove an extra line feed if present */
    518 
    519                 if (!strncmp (SubString - 3, "\n\n", 2))
    520                 {
    521                     *(SubString -2) = '}';
    522                     SubString--;
    523                 }
    524 
    525                 /* Find the end of the typedef name */
    526 
    527                 SubBuffer = AsSkipUntilChar (SubString, ';');
    528 
    529                 /* And remove the typedef name */
    530 
    531                 SubBuffer = AsRemoveData (SubString, SubBuffer);
    532             }
    533             else
    534             {
    535                 /* Skip the entire definition */
    536 
    537                 SubString = strchr (SubString, ';') + 1;
    538                 SubBuffer = SubString;
    539             }
    540         }
    541     }
    542 }
    543 
    544 
    545 /******************************************************************************
    546  *
    547  * FUNCTION:    AsRemoveEmptyBlocks
    548  *
    549  * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This
    550  *              can happen as a result of removing lines such as DEBUG_PRINT.
    551  *
    552  ******************************************************************************/
    553 
    554 void
    555 AsRemoveEmptyBlocks (
    556     char                    *Buffer,
    557     char                    *Filename)
    558 {
    559     char                    *SubBuffer;
    560     char                    *BlockStart;
    561     BOOLEAN                 EmptyBlock = TRUE;
    562     BOOLEAN                 AnotherPassRequired = TRUE;
    563     UINT32                  BlockCount = 0;
    564 
    565 
    566     while (AnotherPassRequired)
    567     {
    568         SubBuffer = Buffer;
    569         AnotherPassRequired = FALSE;
    570 
    571         while (*SubBuffer)
    572         {
    573             if (*SubBuffer == '{')
    574             {
    575                 BlockStart = SubBuffer;
    576                 EmptyBlock = TRUE;
    577 
    578                 SubBuffer++;
    579                 while (*SubBuffer != '}')
    580                 {
    581                     if ((*SubBuffer != ' ') &&
    582                         (*SubBuffer != '\n'))
    583                     {
    584                         EmptyBlock = FALSE;
    585                         break;
    586                     }
    587 
    588                     SubBuffer++;
    589                 }
    590 
    591                 if (EmptyBlock)
    592                 {
    593                     /* Find start of the first line of the block */
    594 
    595                     while (*BlockStart != '\n')
    596                     {
    597                         BlockStart--;
    598                     }
    599 
    600                     /* Find end of the last line of the block */
    601 
    602                     SubBuffer = AsSkipUntilChar (SubBuffer, '\n');
    603                     if (!SubBuffer)
    604                     {
    605                         break;
    606                     }
    607 
    608                     /* Remove the block */
    609 
    610                     SubBuffer = AsRemoveData (BlockStart, SubBuffer);
    611                     BlockCount++;
    612                     AnotherPassRequired = TRUE;
    613                     continue;
    614                 }
    615             }
    616 
    617             SubBuffer++;
    618         }
    619     }
    620 
    621     if (BlockCount)
    622     {
    623         Gbl_MadeChanges = TRUE;
    624         AsPrint ("Code blocks deleted", BlockCount, Filename);
    625     }
    626 }
    627 
    628 
    629 /******************************************************************************
    630  *
    631  * FUNCTION:    AsRemoveDebugMacros
    632  *
    633  * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output.
    634  *
    635  ******************************************************************************/
    636 
    637 void
    638 AsRemoveDebugMacros (
    639     char                    *Buffer)
    640 {
    641     AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT");
    642 
    643     AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT",      REPLACE_WHOLE_WORD);
    644     AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW",  REPLACE_WHOLE_WORD);
    645     AsRemoveStatement (Buffer, "DEBUG_EXEC",            REPLACE_WHOLE_WORD);
    646     AsRemoveStatement (Buffer, "FUNCTION_ENTRY",        REPLACE_WHOLE_WORD);
    647     AsRemoveStatement (Buffer, "PROC_NAME",             REPLACE_WHOLE_WORD);
    648     AsRemoveStatement (Buffer, "FUNCTION_TRACE",        REPLACE_SUBSTRINGS);
    649     AsRemoveStatement (Buffer, "DUMP_",                 REPLACE_SUBSTRINGS);
    650 
    651     AsReplaceString ("return_VOID",         "return", REPLACE_WHOLE_WORD, Buffer);
    652     AsReplaceString ("return_PTR",          "return", REPLACE_WHOLE_WORD, Buffer);
    653     AsReplaceString ("return_STR",          "return", REPLACE_WHOLE_WORD, Buffer);
    654     AsReplaceString ("return_ACPI_STATUS",  "return", REPLACE_WHOLE_WORD, Buffer);
    655     AsReplaceString ("return_acpi_status",  "return", REPLACE_WHOLE_WORD, Buffer);
    656     AsReplaceString ("return_VALUE",        "return", REPLACE_WHOLE_WORD, Buffer);
    657 }
    658 
    659 
    660 /******************************************************************************
    661  *
    662  * FUNCTION:    AsCleanupSpecialMacro
    663  *
    664  * DESCRIPTION: For special macro invocations (invoked without ";" at the end
    665  *              of the lines), do the following:
    666  *              1. Remove spaces appended by indent at the beginning of lines.
    667  *              2. Add an empty line between two special macro invocations.
    668  *
    669  ******************************************************************************/
    670 
    671 void
    672 AsCleanupSpecialMacro (
    673     char                    *Buffer,
    674     char                    *Keyword)
    675 {
    676     char                    *SubString;
    677     char                    *SubBuffer;
    678     char                    *CommentEnd;
    679     int                     NewLine;
    680     int                     NestLevel;
    681 
    682 
    683     SubBuffer = Buffer;
    684     SubString = Buffer;
    685 
    686     while (SubString)
    687     {
    688         SubString = strstr (SubBuffer, Keyword);
    689 
    690         if (SubString)
    691         {
    692             /* Find start of the macro parameters */
    693 
    694             while (*SubString != '(')
    695             {
    696                 SubString++;
    697             }
    698 
    699             SubString++;
    700 
    701             NestLevel = 1;
    702             while (*SubString)
    703             {
    704                 if (*SubString == '(')
    705                 {
    706                     NestLevel++;
    707                 }
    708                 else if (*SubString == ')')
    709                 {
    710                     NestLevel--;
    711                 }
    712 
    713                 SubString++;
    714 
    715                 if (NestLevel == 0)
    716                 {
    717                     break;
    718                 }
    719             }
    720 
    721 SkipLine:
    722 
    723             /* Find end of the line */
    724 
    725             NewLine = FALSE;
    726             while (!NewLine && *SubString)
    727             {
    728                 if (*SubString == '\n' && *(SubString - 1) != '\\')
    729                 {
    730                     NewLine = TRUE;
    731                 }
    732 
    733                 SubString++;
    734             }
    735 
    736             /* Find end of the line */
    737 
    738             if (*SubString == '#' || *SubString == '\n')
    739             {
    740                 goto SkipLine;
    741             }
    742 
    743             SubBuffer = SubString;
    744 
    745             /* Find start of the non-space */
    746 
    747             while (*SubString == ' ')
    748             {
    749                 SubString++;
    750             }
    751 
    752             /* Find end of the line */
    753 
    754             if (*SubString == '#' || *SubString == '\n')
    755             {
    756                 goto SkipLine;
    757             }
    758 
    759             /* Find end of the line */
    760 
    761             if (*SubString == '/' || *SubString == '*')
    762             {
    763                 CommentEnd = strstr (SubString, "*/");
    764                 if (CommentEnd)
    765                 {
    766                     SubString = CommentEnd + 2;
    767                     goto SkipLine;
    768                 }
    769             }
    770 
    771             SubString = AsRemoveData (SubBuffer, SubString);
    772         }
    773     }
    774 }
    775